1196 lines
53 KiB
HTML
1196 lines
53 KiB
HTML
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<title>How EuGTK Works</title>
|
|
<link rel="stylesheet" href="style.css" type="text/css">
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<heading>
|
|
<img src="../thumbnails/mongoose.png" alt="mongoose" />
|
|
<img src="../thumbnails/gtk-logo-rgb.gif" alt="gtk logo align="left" height="100px" />
|
|
<img src="../thumbnails/gnome-run.png"alt="gnome-run" align="right" />
|
|
|
|
<h2> <hr />How EuGTK Works<hr /> </h2>
|
|
</heading>
|
|
|
|
<nav>
|
|
<div class="hdr">Quick Links:</div>
|
|
<a href="#create"><button>Create</button></a>
|
|
<a href="#keywords"><button>Key Words</button></a>
|
|
<a href="#properties"><button>Properties</button></a>
|
|
<a href="#set"><button>Set</button></a>
|
|
<a href="#get"><button>Get</button></a>
|
|
<a href="#connecting"><button>Linking to Eu Funcs</button></a>
|
|
<a href="#datapassing"><button>Passing Data</button></a>
|
|
<a href="#calendar"><button>Calendars</button></a>
|
|
<a href="#colors"><button>Colors</button></a>
|
|
<a href="#settings"><button>Settings</button></a>
|
|
<a href="#debugging"><button>Debugging</button></a>
|
|
<a href="#memory"><button>Memory Usage</button></a>
|
|
<br />
|
|
|
|
<div class="hdr">Other Files:</div>
|
|
<a href="README.html"><button>README</button></a>
|
|
<a href="guide_a.html"><button>Alphabetical Guide</button></a>
|
|
<a href="dialogs.html"><button>Built-in EuGTK Dialogs</button></a>
|
|
<a href="treeviews.html"><button>ListView/TreeView widgets</button></a>
|
|
<a href="pango_markup.html"><button>Markup</button></a>
|
|
<a href="printing.html"><button>Printing</button></a>
|
|
<a href="ServerHelp.html"><button>Web Server</button></a>
|
|
<a href="functions.html"><button>Quick Function List</button></a>
|
|
<a href="Glade.html"><button>Glade GUI Builder</button></a>
|
|
<a href="platforms.html"><button>Platforms</button></a>
|
|
|
|
<br />
|
|
</nav>
|
|
|
|
<h3><hr />Overview:<hr /></h3>
|
|
<div class="quote">
|
|
|
|
<blockquote cite="http://gtk.org">
|
|
|
|
From the GTK docs:
|
|
|
|
<p class="small">
|
|
"A GTK+ user interface is constructed by nesting widgets inside widgets.
|
|
Container widgets are the inner nodes in the resulting tree of widgets:
|
|
they contain other widgets. So, for example, you might have a GtkWindow
|
|
containing a GtkFrame containing a GtkLabel. If you wanted an image instead
|
|
of a textual label inside the frame, you might replace the GtkLabel widget
|
|
with a GtkImage widget.
|
|
</p>
|
|
|
|
<p class="small">
|
|
There are two major kinds of container widgets in GTK+. Both are subclasses of
|
|
the abstract GtkContainer base class.
|
|
The first type of container widget has a single child widget and derives from
|
|
GtkBin. These containers are decorators, which add some kind of functionality
|
|
to the child. For example, a GtkButton makes its child into a clickable button;
|
|
a GtkFrame draws a frame around its child and a GtkWindow places its child
|
|
widget inside a top-level window.
|
|
</p>
|
|
|
|
<p class="small">
|
|
The second type of container can have more than one child; its purpose is to
|
|
manage layout. This means that these containers assign sizes and positions to
|
|
their children. For example, a GtkBox arranges its children in a horizontal
|
|
[or vertical] row, and a GtkGrid arranges the widgets it contains in a
|
|
two-dimensional grid."
|
|
</p>
|
|
|
|
</div>
|
|
</blockquote>
|
|
|
|
<p>
|
|
To reiterate the last point: GTK does <i><b>not</b></i> expect the programmer to specify
|
|
position and size of each widget as is required when programming for Windows™.
|
|
GTK handles these things automatically, adjusting things 'on-the-fly', as the user resizes
|
|
windows, changes fonts, etc... which makes your programs more user-friendly.
|
|
</p>
|
|
|
|
<div class="quote">
|
|
<blockquote cite="gtk.org">
|
|
|
|
Quote:
|
|
|
|
<p class="small">
|
|
"Note the inherent danger of setting any fixed size - themes, translations into other languages,
|
|
different fonts, and user action can all change the appropriate size for a given widget.
|
|
So, <u>it's basically impossible to hardcode a size that will always be correct.</u>
|
|
"
|
|
</p>
|
|
|
|
</blockquote>
|
|
</div>
|
|
|
|
<p>
|
|
If you are accustomed to writing programs for Windows™, you'll wonder why there's not
|
|
a complex IDE to help lay out your GTK program interface. The answer is: because it's not necessary!
|
|
You don't need to specify sizes and positions for GTK controls, GTK takes care of that task for you.
|
|
Your main job will be writing Euphoria functions, for which a plain old text editor works
|
|
just fine! You do have the option to use Glade to design your program interface if you wish.
|
|
See <a href="Glade.html">Glade.html</a>.
|
|
</p>
|
|
|
|
<a name="keywords"></a>
|
|
<h3><hr />Keywords<hr /></h3>
|
|
<p>EuGTK allows you to program in an object-oriented style.</p>
|
|
<p>
|
|
There are only a handful of new keywords to know. You can create nice-looking, functional
|
|
programs with only the six shown here:
|
|
<ul>
|
|
<li><a href="#create">create</a>
|
|
<dd>declare a new instance of a given GTK object</dd>
|
|
</li>
|
|
|
|
<li><a href="#set">set</a>
|
|
<dd>modify a property of an object</dd>
|
|
</li>
|
|
|
|
<li><a href="#get">get</a>
|
|
<dd>retrieve a property of an object</dd>
|
|
</li>
|
|
|
|
<li><a href="#connecting">connect</a>
|
|
<dd>instructs an instance to respond to an event (a.k.a. signal)</dd>
|
|
</li>
|
|
|
|
<li><a href="functions.html#functions">show_all</a>
|
|
<dd>make a container and all objects contained therein visible</dd>
|
|
</li>
|
|
|
|
<li><a href="functions.html#functions">main</a>
|
|
<dd>start the GTK main event loop, waiting for user input</dd>
|
|
</li>
|
|
</ul>
|
|
</p>
|
|
|
|
<p>
|
|
You'll find a more complete list of keywords in <a href="functions.html">functions.html</a>
|
|
</p>
|
|
|
|
<a name="create"></a>
|
|
<h3><hr />Create<hr /></h3>
|
|
|
|
<p>
|
|
New instances of EuGTK containers and controls (collectively called <i>'widgets'</i> in GTK)
|
|
are created by calling the <i>create()</i> function with a class name.
|
|
These class names are enumerated in GtkEnums.e,
|
|
and they are the same as those used by the GTK
|
|
docs. These class names are the <i>ONLY</i> ones you can send to
|
|
the <i>create()</i> function. Never try numbers or strings. No quotes. Spelling counts!
|
|
</p>
|
|
|
|
<p>
|
|
The <i>create()</i> function returns a <i>'handle'</i> (a.k.a. pointer) to the newly created
|
|
instance.
|
|
That handle can (and usually should) be saved in a Euphoria constant for later access:
|
|
<pre>
|
|
<em class="kw">constant</em> win = <em class="gtk">create</em>(GtkWindow) <em>-- generally, a constant is best, because you won't be changing these;</em>
|
|
</pre>
|
|
Parameters, if any, which follow the class name vary, and are often optional.
|
|
Refer to the demo programs and the GTK docs for details. Also, explore the new, more compact <a href="README.html#syntax">syntax options</a> for the create() function <a href="README.html#syntax">here</a>, as well as <a href="#variants"> variants</a>, below.
|
|
</p>
|
|
|
|
<p>
|
|
GtkEngine.e maintains a list of currently created GTK containers and controls, and directs calls from your Euphoria program to the appropriate
|
|
'method' based on the type of widget and whether the call is to <a href="#set">
|
|
set</a> or to <a href="#get">get</a> one of that widget's <a href="#properties">properties</a>.
|
|
</p>
|
|
|
|
<a name="properties"></a>
|
|
<h3><hr />Properties<hr /></h3>
|
|
|
|
<p>
|
|
Every GTK widget has a list of <i>properties</i> which can be written to
|
|
or read from. For example, a window has a <i>title</i>, a <i>border width</i>,
|
|
a <i>default size</i>, etc.
|
|
</p>
|
|
|
|
<p>
|
|
Widgets which display information or accept input from users have properties such as
|
|
<i>text</i> for labels and text entries, <i>value</i> for numeric widgets, and <i>active</i>
|
|
for widgets such as checkboxes.
|
|
</p>
|
|
|
|
<p>
|
|
To find out what properties exist for a given widget, refer
|
|
to the GTK docs. Remember that widgets inherit properties from ancestor widgets, so if
|
|
you don't find a property for a given widget, follow the Object Hierarchy links in the GTK docs.
|
|
As an example, you can select the <i>font</i>, <i>background</i> or text <i>color</i> for a window,
|
|
but these properties are actually implemented by GtkWindow's ancestor the GtkWidget,
|
|
whereas <i>border width</i> is actually implemented by the GtkWindow's ancestor GtkContainer.
|
|
But you don't need to be concerned about this, all you need do is tell the window what to do, and it - or its parents or grandparents - will see that it gets done.</p>
|
|
</p>
|
|
|
|
<p>
|
|
EuGTK takes care of finding these ancestor properties for you, but if you don't
|
|
read the GTK docs, you won't be aware that these properties are available!
|
|
In many cases you can just use common sense: for example, if it seems reasonable that a window
|
|
should be able to have a blue background, just try it: <code>set(win,"background","blue")</code>.
|
|
If you try something that isn't possible, such as setting a window's <i>text</i>, for example,
|
|
you will get an error message on your terminal such as:
|
|
<br />
|
|
<div class="scrn"><tt>
|
|
object class 'GtkWindow' has no property named 'text'
|
|
</tt></div>
|
|
</p>
|
|
|
|
<div class="hint">
|
|
<img class="hint" src="../thumbnails/hint.png" alt="hint" width="100px" align="left" float="right" />
|
|
<p>Remember, when writing your EuGTK programs, you <i><u>must</u></i> run them from a terminal,
|
|
in order to see warnings such as the one above!</p>
|
|
</div>
|
|
|
|
<a name="set"></a>
|
|
<h3><hr />Set<hr /></h3>
|
|
<p>
|
|
The set() function takes a 'handle' to a control, plus a 'property' to
|
|
be set. Handle is <i>almost</i> always an atom (as assigned by the create() function),
|
|
except when you are using Glade to design your interfaces, when you often use the name of the control in string form, e.g. "button1"
|
|
or "help:window".
|
|
</p>
|
|
|
|
<p>
|
|
'property' is always a string! Following those are one or more parameters. The type and number of
|
|
parameters requred must be determined by looking at the GTK documentation
|
|
and the sample programs included here.
|
|
|
|
Some examples:
|
|
<pre>
|
|
<em class="gtk">set</em>(win,<em class="str">"title","My Program"</em>)
|
|
<em class="gtk">set</em>(win,<em class="str">"border_width"</em>,<em class="orange">10</em>)
|
|
<em class="gtk">set</em>(win,<em class="str">"default_size"</em>,<em class="orange">300,200</em>)
|
|
<em class="gtk">set</em>(<em class="str"><b>"help:window"</b>,"Title","Using EuGTK"</em>) <em>-- using widget name</em>
|
|
<em> -- the window directly above is created in an include file
|
|
-- which has the namespace "help"</em>
|
|
</pre>
|
|
</p>
|
|
|
|
<div class="hint">
|
|
<img class="hint" src="../thumbnails/hint.png" alt="hint" width="100px" align="left" float="right" />
|
|
<p>
|
|
Note that you can use <i>widget names</i> to refer to controls, rather than handles,
|
|
<i>if</i> you give the control its own individual name.
|
|
<br />(When using Glade, a name will be assigned automatically.)
|
|
</p>
|
|
</div>
|
|
|
|
<p>
|
|
For example: <code>win = <em class="gtk">create</em>(GtkWindow,<em class="str">"<b>name=Main Window</b>,size=400x300"</em>)</code>
|
|
<br /><br />In the above line, you have named this window, and so can refer to it as
|
|
"Main Window" in future set() or get() calls. Sometimes this can come in handy,
|
|
resulting in more-readable code.
|
|
</p>
|
|
|
|
<p>
|
|
If you supply too many parameters, like:
|
|
<pre>
|
|
<em class="gtk">set</em>(win,<em class="str">"title","My Program", "well isn't that swell?"</em>,<em class="orange">1,2,3</em>)
|
|
</pre>
|
|
That won't usually cause any problem; the excess parameters are just discarded.
|
|
You'll get an error message if you get carried away and try to send more than 10.
|
|
</p>
|
|
|
|
<p>
|
|
Too few parameters will usually cause problems, if not crashes, because unfilled values
|
|
default to zero:
|
|
<pre>
|
|
<em class="gtk">set</em>(win,<em class="str">"default_size"</em>)
|
|
</pre>
|
|
This will set the window size to 0x0 pixels, i.e: nothing, which will make it
|
|
kinda hard to see! No error message can help in this case, since such a
|
|
setting <i>could</i> - for some strange reason - be intentional.
|
|
</p>
|
|
|
|
<p>
|
|
Mismatched parameter types - sending a string where an atom or integer is expected, or vice-versa -
|
|
will usually give an error message, but
|
|
sometimes a crash (segfault) is unavoidable. Again, read the GTK docs!
|
|
</p>
|
|
|
|
<a name="get"></a>
|
|
<h3><hr />Get<hr /></h3>
|
|
<p>
|
|
The get() function takes a 'handle' to the control, plus a 'property' to
|
|
be looked up. Handle is always an atom, except when using Glade to design your
|
|
interface, in which case it is sometimes a string. And 'property' is always a string!
|
|
Some examples:
|
|
<pre>
|
|
<em class="gtk">get</em>(win,<em class="str">"title"</em>) <em>-- returns a string if a title was set, 0 otherwise</em>
|
|
<em class="gtk">get</em>(win,<em class="str">"border_width"</em>) <em>-- returns an integer (pixels), 0 if unset</em>
|
|
<em class="gtk">get</em>(win,<em class="str">"default_size"</em>) <em>-- returns a sequence {x,y} e.g: {300,200} or {-1,-1} if unset</em>
|
|
<em class="gtk">get</em>(<em class="str"><b>"prefs:spinbutton1"</b>,"value"</em>) <em> -- returns an atom or integer</em>
|
|
</pre>
|
|
Sending the wrong number of parameters to the get() function will
|
|
very likely cause problems! Sometimes a machine-level exception (signal 11).
|
|
Fortunately, this is easy to avoid, as there normally AREN'T ANY
|
|
parameters to 'get', other than the handle and the property name.
|
|
</p>
|
|
|
|
<a name="conveniences"></a>
|
|
<h3><hr />Conveniences<hr /></h3>
|
|
<p>
|
|
A few very frequently-used functions have simpler 'shorthand' ways to call them:
|
|
<table border="1">
|
|
<tr>
|
|
<th>Function</th><th>Parameters</th><th>Shorthand</th><th>Parameters</th>
|
|
</tr>
|
|
<tr>
|
|
<td> set(x,"add",z) </td>
|
|
<td rowspan="7">
|
|
<i>For functions on the left,<br /><hr /><b> x</b></i></i> and <i><b>z</b></i> must be atoms<br />
|
|
(widget handles) <br />
|
|
or widget names as strings</td>
|
|
<td> add(x,z)<em>*</em> </td>
|
|
<td rowspan="5"><i>For shorthand notation,<br /><hr />
|
|
<b> x</b></i> must be an atom <br /> (a widget handle)<br />or a widget name as a string<br />
|
|
<br /> <em><big>*</big></em> <i><b>z</b></i> can be a handle<br /> or a {list} of handles</td>
|
|
</tr>
|
|
<tr>
|
|
<td> set(x,"show")</td><td> show(z)<em>*</em> </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="emphasis"> set(x,"show_all")</td><td class="emphasis"> show_all(z) </td>
|
|
</tr>
|
|
<tr>
|
|
<td> set(x,"hide")</td><td> hide(z)<em>*</em></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="emphasis"> set(x,"hide all")</td><td class="emphasis"> hide_all(z)</td></tr>
|
|
</table>
|
|
</p>
|
|
|
|
<p>
|
|
These shortcut methods not only save a bit of typing, but more importantly, allow you to send <i>{lists}</i> of items, rather
|
|
than calling the routine over and over, once for each item. <i>{lists}</i> are simply sequences of one or more
|
|
handles to widgets. For example:
|
|
<pre>
|
|
<em class="gtk">add</em>(panel,{img1,btn1,btn2,btn3})
|
|
<em>-- or</em>
|
|
<em class="gtk">add</em>(panel,x) <em> -- where x can be a {list} of handles to any number of objects, of mixed types (don't all have to be buttons!)')</em>
|
|
<em>-- or</em>
|
|
<em class="gtk">add</em>(panel,x[1..5]) <em>-- you can send slices as well</em>
|
|
</pre>
|
|
</p>
|
|
|
|
<p>
|
|
GTK provides two 'pack' methods: pack_start and pack_end, which are identical except for direction.
|
|
The original calls are still there, but for added convenience, I've also provided <i>pack</i>, which uses the - (neg.) sign to indicate <i>pack at end</i>. This may be helpful when packing several items in one call.
|
|
<pre>
|
|
<em class="gtk">pack</em>(panel,btn1) <em>-- pack_start (top to bottom for vert. containers, left to right for horiz.)</em>
|
|
<em>-- or</em>
|
|
<em class="gtk">pack</em>(panel,-btn1) <em>-- pack_end (this item will go at the bottom / far right of the container)</em>
|
|
</pre>
|
|
</p>
|
|
|
|
<a name="variants"></a>
|
|
<h3><hr />Variants<hr /></h3>
|
|
<p>
|
|
There are some GTK widgets which have multiple ways to create
|
|
them. An image, for example, might be created from:
|
|
<ul>
|
|
<li>a file ~ *.jpg, .png, .gif, etc...</li>
|
|
<li>a stock item ~ "gtk-ok", "gtk-cancel", etc...</li>
|
|
<li>a pixbuf previously created or loaded from a file.</li>
|
|
<li>a themed icon ~ from one of the hundreds supplied: "face-cool", for example.</li>
|
|
<li>something else ~ a GIcon, perhaps.</li>
|
|
<li>or nothing at all</li>
|
|
</ul>
|
|
</p>
|
|
|
|
<p>
|
|
EuGTK tries to figure out which you want by examining the params (if any) you send
|
|
to the create() function:
|
|
<pre>
|
|
<em class="kw">constant</em> img = <em class="gtk">create</em>(GtkImage)
|
|
<em>--it seems you want an empty container which can hold an image to be set at a later time.</em>
|
|
|
|
<em class="kw">constant</em> img = <em class="gtk">create</em>(GtkImage,<em class="str">"~/demos/thumbnails/BabyTux.jpg"</em>)
|
|
<em>-- looks like you want to create this from the file named, if such file exists.
|
|
-- Note: cannonical_path() is automatically called to convert the filename/path to a usable form.</em>
|
|
|
|
<em class="kw">constant</em> img = <em class="gtk">create</em>(GtkImage,<em class="str">"gtk-ok"</em>,GTK_ICON_SIZE_DIALOG)
|
|
<em>-- looks like you want a stock image, in the size given.
|
|
-- Note: any name beginning with "gtk-" is considered to be a stock item</em>
|
|
|
|
<em class="kw">constant</em> img = <em class="gtk">create</em>(GtkImage,<em class="str">"face-smile"</em>,GTK_ICON_SIZE_DIALOG)
|
|
<em>-- you want an icon, as named, from the current icon theme, in the size specified.
|
|
-- size can be either one of the GTK_ICON_SIZE_ enums, or can be a pixel value,
|
|
-- usually between 16 and 256.</em>
|
|
|
|
<em class="kw">constant</em> pix = <em class="gtk">create</em>(GdkPixbuf,<em class="str">"~/demos/thumbnails/mongoose.png"</em>,<em class="orange">80,80</em>,TRUE)
|
|
<em class="kw">constant</em> img = <em class="gtk">create</em>(GtkImage,pix)
|
|
<em>-- by creating a pixbuf from the file, you can specify a size for the image,
|
|
-- plus, you have a static pixbuf object which can be re-used.
|
|
-- If you create an image directly from a file, you can't resize or re-use that image </em>
|
|
|
|
</pre>
|
|
</p>
|
|
|
|
<a name="connecting"></a>
|
|
<h3><hr />Connecting controls to functions<hr /></h3>
|
|
<p>
|
|
It should be obvious, but just to be clear, GTK programs, like Windows™ programs,
|
|
Apple™ programs, and almost every other computer program written in the last few decades,
|
|
are <i>event driven</i>. If you aren't sure what that means, find out before you begin designing your
|
|
nifty new program.
|
|
</p>
|
|
|
|
<p>
|
|
Your program will need to respond to user actions (events). The various
|
|
events emit signals, for example, a button click emits a "clicked" signal.
|
|
Your job is to connect a widget's signal to the appropriate function to handle the
|
|
event.
|
|
<pre>
|
|
<em class="gtk">connect</em>(win,<em class="str">"destroy","Quit"</em>) -- <em><u>Always</u> do this for the main window!</em>
|
|
</pre>
|
|
Where <i>win</i> is the handle, <i>"destroy"</i> [always a string] is a signal,
|
|
a.k.a. the name of an event. <i>"Quit"</i> is what to do in that event. The example above will
|
|
call the function Quit() when the program's main window is destroyed.
|
|
Quit() - a function exported by GtkEngine.e - then shuts down the GTK engine and frees memory it has allocated.
|
|
</p>
|
|
|
|
<p>
|
|
Quit() is one of very few <i>built-in</i> EuGTK functions you will need to connect to.
|
|
Most other connections will be made to Euphoria functions YOU write.
|
|
Any Euphoria function used for this purpose must be:
|
|
<ol>
|
|
<li>A function, not a procedure</li>
|
|
<li>Visible to the code doing the calling</li>
|
|
</ol>
|
|
</p>
|
|
|
|
<p>
|
|
You usually do not have to write a separate line of code to connect a widget to a function. The most commonly-used widgets have a convenient way to make that connection
|
|
at the time the widget is created, which leads to cleaner and easier to maintain code:
|
|
|
|
<pre>
|
|
<em>(A)</em> <em class="kw">constant</em> btn1 = <em class="gtk">create</em>(GtkButton,<em class="str">"gtk-ok","Foo"</em>,<i>42</i>)
|
|
|
|
<em>(B)</em> <em class="kw">constant</em> btn1 = <em class="gtk">create</em>(GtkButton,<em class="str">"gtk-ok","Foo","Hello World!"</em>)
|
|
|
|
<em>(C)</em> <em class="kw">constant</em> <b>foo</b> = call_back(routine_id(<em class="str">"Foo"</em>))
|
|
<em class="kw">constant</em> btn1 = <em class="gtk">create</em>(GtkButton,<em class="str">"gtk-ok"</em>,<b>foo</b>,<em class="str">"Hello World!"</em>)
|
|
</pre>
|
|
|
|
<div class="hint" style="width:100%">
|
|
<em>(D)</em> <b>New in 4.11.4!</b><pre>
|
|
<em class="kw">constant</em> btn1 = <em class="gtk">create</em>(GtkButton,"gtk-ok",<b><em>_("Foo")</em></b>,[...])
|
|
|
|
<em class="blue">The <b><em>_()</em></b> function allows linking to <i>local</i> functions, instead of global.
|
|
It works better than call_back(routine_id()), since it can
|
|
'look forward' to find functions which are defined
|
|
further down in your code, allowing cleaner program structure.
|
|
|
|
Thanks to Greg Haberek for this function.
|
|
</em></pre>
|
|
</div>
|
|
</p>
|
|
|
|
<p>
|
|
In any of the calls above, you are making a new button with the stock OK image, connecting its default signal (which is <i>'clicked'</i>, in the case of a button) to
|
|
call your Euphoria function Foo(), and optionally sending some object
|
|
as the data parameter to that function.
|
|
The data item is always optional, and can contain almost anything you
|
|
want.
|
|
</p>
|
|
|
|
<p>
|
|
See <a href='#datapassing'>Data passing</a> below for examples of how to pass
|
|
various data types to your Euphoria functions.
|
|
</p>
|
|
|
|
<p>
|
|
If you use method <em>(A)</em> or <em>(B)</em> then your Euphoria function declaration could look like this:
|
|
<pre>
|
|
<em>--------------------------------------------------------------</em>
|
|
<em class="kw"><b>global</b> function</em> Foo(<em class="kw">atom</em> <i>ctl</i>, <em class="kw">object</em> <i>data</i>) <em>-- must be global!</em>
|
|
<em>--------------------------------------------------------------</em>
|
|
</pre>
|
|
If you use method <em>(C)</em> or <em>(D)</em> then you can declare your Euphoria functions as local functions, not global:
|
|
<pre>
|
|
<em>-----------------------------------------------------------</em>
|
|
<em class="kw">function</em> Foo(<em class="kw">atom</em> <i>ctl</i>, <em class="kw">object</em> <i>data</i>)
|
|
<em>-----------------------------------------------------------</em>
|
|
</pre>
|
|
</p>
|
|
|
|
<p>
|
|
The parameter <i>ctl</i> will be filled in with the handle of the control which
|
|
dispatched the call, and <i>data</i> will be the data attached to that control,
|
|
or null if no data value was provided.
|
|
</p>
|
|
|
|
<p>
|
|
If you compile a program which uses method <em>(A)</em> or <em>(B)</em> to link to functions, it may compile
|
|
without error, but you will get a run-time error on the terminal like the following:
|
|
<br clear="all" />
|
|
<div class="scrn" width="80%"><pre>Error: function Foo is not in scope
|
|
****** (make it global or link via routine_id)</pre>
|
|
</p>
|
|
</div>
|
|
|
|
<br clear="all" />
|
|
<p>
|
|
Use the COMPILE flag for a way to quickly detect these errors in advance, before you go to the trouble of compiling.
|
|
|
|
<div class="scrn">
|
|
$ eui -d COMPILE myprogram.ex
|
|
</div>
|
|
</p>
|
|
|
|
<h4>Connections, alternate methods</h4>
|
|
<p>
|
|
You can also connect signals to controls by typing a separate line:
|
|
<pre>
|
|
<em>(1)</em><em class="gtk"> connect</em>(btn1,<em class="str">"clicked","Foo"</em>,[...]) <em>-- global function</em>
|
|
|
|
<em>(2)</em><em class="gtk"> connect</em>(btn1,<em class="str">"clicked"</em>,call_back(routine_id(<em class="str">"Foo"</em>)),[...])
|
|
|
|
<em>(3)</em><em class="gtk"> connect</em>(btn1,<em class="str">"clicked"</em>,_(<em class="str">"Foo"</em>),[...]) <em>-- local function</em>
|
|
|
|
<em>(4)</em> <em class="kw">constant</em> foo = <em class="kw">call_back(routine_id</em>(<em class="str">"Foo"</em>))
|
|
<em class="gtk">connect</em>(btn1,<em class="str">"clicked"</em>,foo,[...])
|
|
|
|
</pre>
|
|
|
|
You might use this method instead of the previous one
|
|
if you want to connect a signal other than the default, or if there is no default signal provided for
|
|
that control. See GTK docs for appropriate signal names, and GtkEngine.e for the implemented defaults
|
|
(around line 348 in the create() function). Again, if you plan to compile, use call_back(routine_id()) as shown in <em>(2)</em>, <em>(3)</em> or <em>(4)</em>.
|
|
</p>
|
|
<a name="caution"></a>
|
|
|
|
<p><h4>Function Parameters</h4>
|
|
<p>Different controls can pass different types and number of parameters to your Euphoria "handler" functions when activated, so be sure to check the GTK docs for the particular widget/signal you are using. The GTK docs usually show a prototype of an appropriate signal handler.</p>
|
|
|
|
Often, your Euphoria functions can ignore the parameters that GTK passes to them.
|
|
If you do not need to access these parameters, just don't bother to declare them!
|
|
</p>
|
|
|
|
<div class="hint">
|
|
<img class="hint" src="../thumbnails/hint.png" alt="hint" width="100px" align="left" float="right" />
|
|
<p>Note that you can connect <i>more than one signal</i> and/or <i>more than one function</i> to a control.
|
|
The calls will be executed in order.
|
|
|
|
To do this, use the alternate 'connect' syntax as shown in <em>(1,2,3)</em> above,
|
|
repeating the connect line for each different function or signal to be called.
|
|
</p>
|
|
|
|
<hr />
|
|
|
|
<p>
|
|
A practical application of this might be to trap your main window's "delete-event" signal first,
|
|
perhaps calling a routine that saves your work if necessary, then allowing (or not) the "destroy" event to call the "Quit" function to end the program.
|
|
</p>
|
|
|
|
<div class="quote">
|
|
<p>
|
|
<pre><code><em class="kw">constant</em> win = <em class="gtk">create</em>(GtkWindow)
|
|
<em class="gtk">connect</em>(win,<em class="str">"delete-event"</em>,_(<em class="str">"AreYouSure"</em>)) <em>--[1]</em>
|
|
<em class="gtk">connect</em>(win,<em class="str">"destroy","Quit"</em>) <em>--[2]</em>
|
|
<em>-- note 1: this will be called first</em>
|
|
<em>-- note 2: this may be called next, depending upon the</em>
|
|
<em>-- value returned by #1</em>
|
|
|
|
<em>-------------------------------------------------</em>
|
|
<em class="kw">function</em> AreYouSure()
|
|
<em>-------------------------------------------------</em>
|
|
<em class="kw">if</em> dirty <em class="kw">then</em>
|
|
<em>-- *save it* code goes here</em>
|
|
<em class="kw">end if</em>
|
|
<em class="kw">return</em><em class="gtk"> Question</em>(win,,<em class="str">"OK to Quit?"</em>) != MB_YES
|
|
<em class="kw">end function</em>
|
|
</code></pre>
|
|
</p>
|
|
</div>
|
|
|
|
<p>
|
|
The value returned by the first function will determine whether the succeeding function(s) will be called or skipped. Note that we use the syntax <i>not equal MB_YES</i>. This is so closing the popup Question dialog window without actually answering YES or NO will not kill the program.
|
|
</p>
|
|
|
|
<p>
|
|
If a 1 is returned from the first called function, then succeeding functions will <i>NOT</i> be called, and
|
|
a 0 will allow the succeeding function(s) to be called. One way to look at this so it makes sense is to think
|
|
of the return value as a report: A 1 or TRUE means "I've handled this myself, don't bother any further", while
|
|
a zero or FALSE means "I've done what I can, it's your turn now!".
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<p>
|
|
If you find that you need to be able to <i>disconnect</i> a signal,
|
|
use this alternate method, and save the signal_id:
|
|
<pre><em class="kw"> integer</em> sigid = <em class="gtk">connect</em>(btn1,<em class="str">"clicked"</em>,....)
|
|
</pre>
|
|
so that later, you can disconnect that signal by calling:
|
|
<pre> <em class="gtk">disconnect</em>(btn1,sigid)
|
|
</pre>
|
|
Do not use this to disable a control, because it does not change the appearance
|
|
to indicate that the control is disabled. Instead, use
|
|
<pre> <em class="gtk">set</em>(btn1,<em class="str">"sensitive"</em>,<em class="kw">FALSE</em>)
|
|
</pre>
|
|
</p>
|
|
|
|
<h3><hr />How to figure out which control was activated<hr /></h3>
|
|
<p>
|
|
Since you can connect several controls to a single Eu function, your function may need to determine which
|
|
control is doing the calling.<br /><br />
|
|
As a rule, the first parameter passed to a called Eu function will be the
|
|
handle of the control that was activated.
|
|
The second parameter is usually the data attached
|
|
when the connection was made.<br /><br />
|
|
These 'rules' vary on occasion. See the GTK docs for a prototype of the respective callback routine.<br />
|
|
<br />Here are two ways to determine which control was activated:
|
|
<pre><code><em>--------------------------------------------</em>
|
|
<em class="kw">function</em> Foo(atom ctl, atom data)
|
|
<em>--------------------------------------------</em>
|
|
<em>-- within this function, you might choose to:</em>
|
|
</code></pre>
|
|
<ol>
|
|
<li>Match the ctl parameter to known control handles</li>
|
|
<small>
|
|
<ul><li><em class="kw">switch </em>ctl <em class="kw">do</em><br />
|
|
<em class="kw">case</em> btn1 <em class="kw">then</em> ...<br />
|
|
<em class="kw">case</em> btn2 <em class="kw">then</em> ...</li></ul><br />
|
|
</small>
|
|
<li>Use the data parameter to pass a unique identifier</li>
|
|
<small>
|
|
<ul><li><em class="kw">if</em> data = 42 <em class="kw">then</em> ...</li></ul>
|
|
</small></ul></small>
|
|
</ol>
|
|
|
|
<b>Note:</b> <br />
|
|
For control groups (such as RadioButtons), which send a 'toggled' signal,
|
|
there will be <b><i>two</i></b> controls responding to events,
|
|
and thus two calls to your Eu function!
|
|
<ul>
|
|
<li>One call being from the previously-selected button
|
|
as it is toggled to the de-activated state.</li>
|
|
<li>The other being
|
|
from the newly-selected button as it is toggled to the activated state.
|
|
</ul>
|
|
|
|
You must check the 'active' property
|
|
to see which of the two you should respond to. In some cases, you may want to respond to
|
|
<i>both </i>, deactivating or closing one thing, and activating or showing another, for example.
|
|
|
|
<ul><li><em class="kw">if</em> <em class="gtk">get</em>(ctl,<em class="str">"active"</em>) <em class="kw">then ...</em> <em>-- this is the one just clicked</em></li></ul>
|
|
</p>
|
|
|
|
<a name='datapassing'>
|
|
<h3><hr />Data passing<hr /></h3>
|
|
</a>
|
|
<p>
|
|
Frequently, it is convenient to be able to attach data items to an individual control,
|
|
which that control will pass to functions it calls when activated. One advantage of doing things this way
|
|
is that it allows you to write a single Eu function which can handle events from multiple controls.
|
|
Another advantage is that it makes your code easier to read and maintain.<br /><br />
|
|
Depending upon the method chosen, the data can be almost anything, from a simple integer to
|
|
a complex Euphoria sequence containing strings, pointers, routine_id's, and perhaps even images
|
|
or other GTK 'widgets'.
|
|
</p>
|
|
|
|
<h4>Method 1</h4>
|
|
<p>
|
|
Often it is enough to simply attach the data to a control's data space, as in the examples
|
|
below. This is also the cleanest and most readable method.
|
|
</p>
|
|
|
|
<p>
|
|
<pre>
|
|
<b class="x">(1) -- passing an integer</b>
|
|
<em class="kw">constant</em>
|
|
btn1 = <em class="gtk">create</em>(GtkButton,<em class="str">"Justin"</em>,_(<em class="str">"DisplayAge"</em>),<em class="brown">17</em>),
|
|
btn2 = <em class="gtk">create</em>(GtkButton,<em class="str">"Jamie"</em>,_(<em class="str">"DisplayAge"</em>),<em class="brown">15</em>)
|
|
|
|
<em>---------------------------------------------------------------</em>
|
|
<em class="kw">function</em> DisplayAge(<em class="kw">atom</em> ctl, <em class="kw">integer</em> age)
|
|
<em>---------------------------------------------------------------</em>
|
|
<em class="kw"> printf</em>(1,<em class="str">"Age = %d\n"</em>,age)
|
|
|
|
Integers are passed and used directly, with no conversion needed.
|
|
All other data types are passed as pointers,
|
|
and must be 'decoded' by using the unpack() function.
|
|
|
|
<b class="x">(2) -- passing a float</b>
|
|
|
|
<em class="kw">constant</em> btn1 = <em class="gtk">create</em>(GtkButton,<em class="str">"gtk-ok"</em>,_(<em class="str">"Foo"</em>),<em class="brown">123.456</em>)
|
|
|
|
<em>---------------------------------------------------------------</em>
|
|
<em class="kw">function</em> Foo(<em class="kw">atom</em> ctl, <em class="kw">object</em> data)
|
|
<em>---------------------------------------------------------------</em>
|
|
<em class="kw">atom</em> num = <em class="gtk">unpack</em>(data)
|
|
|
|
The unpack() function will return an atom
|
|
|
|
<b class="x">(3) -- passing a string</b>
|
|
|
|
<em class="kw">constant</em> btn1 = <em class="gtk">create</em>(GtkButton,<em class="str">"gtk-ok"</em>,_(<em class="str">"Foo"</em>),<em class="str">"James Brown"</em>)
|
|
|
|
<em>---------------------------------------------------------------</em>
|
|
<em class="kw">function</em> Foo(<em class="kw">atom</em> ctl, <em class="kw"><b>object</b></em> data) <em>-- must be object</em>
|
|
<em>---------------------------------------------------------------</em>
|
|
data = <em class="gtk">unpack</em>(data)
|
|
|
|
The unpack() function will return a string
|
|
|
|
<b class="x">(4) -- passing a Euphoria sequence {} containing almost any mix of data </b>
|
|
|
|
<em class="kw">constant</em>
|
|
btn1 = <em class="gtk">create</em>(GtkButton,<em class="str">"_Pie"</em>,_(<em class="str">"Foo"</em>),<b>{</b><em class="str">"Apple Pie"</em>,<em class="brown">1.95</em><b>}</b>),
|
|
btn2 = <em class="gtk">create</em>(GtkButton,<em class="str">"_Cake"</em>,_(<em class="str">"Foo"</em>),<b>{</b><em class="str">"Carrot Cake"</em>,<em class="brown">2.10</em><b>}</b>)
|
|
|
|
<em>---------------------------------------------------------------</em>
|
|
<em class="kw">function</em> Foo(<em class="kw">atom</em> ctl, <em class="kw">object</em> data) <em>-- must be object</em>
|
|
<em>---------------------------------------------------------------</em>
|
|
data = <em class="gtk">unpack</em>(data)
|
|
<em class="gtk">Info</em>(win,<em class="str">"Flo's Bakery"</em>,
|
|
<em class="kw">format</em>(<em class="str">"Two orders of [1]"</em>,data),
|
|
<em class="kw">format</em>(<em class="str">"$[2.2]"</em>,data*2))
|
|
|
|
The unpack() function will return a sequence
|
|
</pre>
|
|
</p>
|
|
</p>
|
|
|
|
<h4>Method 2</h4>
|
|
<p>
|
|
Sometimes, the best way to pass multiple data values of varying types might be with Euphoria's map functions.
|
|
One advantage of this method is that it allows you to access the values by
|
|
name, rather than by position, as shown in the method above. The disadvantage - verbosity.</p>
|
|
<img src="../screenshots/test84.jpg" alt="test84" align="right" />
|
|
<pre>
|
|
<em class="kw">object</em> jerry = <em class="kw">map:new()</em>
|
|
<em class="kw">map:put</em>(jerry,<em class="str">"Name","Jerry"</em>)
|
|
<em class="kw">map:put</em>(jerry,<em class="str">"School","Central High"</em>)
|
|
<em class="kw">map:put</em>(jerry,<em class="str">"Age"</em>,17)
|
|
<em class="kw">map:put</em>(jerry,<em class="str">"Pix"</em>,<em class="gtk">create</em>(GdkPixbuf,<em class="str">"~/demos/thumbnails/Jerry.jpg"</em>))
|
|
<em>-- above, we store a 'handle' to a picture of
|
|
-- Jerry in the map structure</em>
|
|
|
|
<em class="kw">constant </em>btn1 = <em class="gtk">create</em>(GtkButton,<em class="str">"Student 1"</em>,_(<em class="str">"ShowDetails"</em>),jerry)
|
|
|
|
<em>----------------------------------------------------------------</em>
|
|
<em class="kw">function</em> ShowDetails(<em class="str">atom</em> ctl, <em class="str">atom</em> data)
|
|
<em>----------------------------------------------------------------</em>
|
|
<em class="gtk">Info</em>(win,<em class="str">"Student"</em>,<em class="kw">map:get</em>(data,<em class="str">"Name"</em>),
|
|
<em class="kw">sprintf</em>(<em class="str">"<small><i>School:</i></small>\n %s\n<small><i>Age:</i></small>\n %d"</em>,
|
|
{<em class="kw">map:get</em>(data,<em class="str">"School"</em>),
|
|
<em class="kw">map:get</em>(data,<em class="str">"Age"</em>)}),,<em class="kw">map:get</em>(data,<em class="str">"Pix"</em>))
|
|
<em>-- above, we use the passed 'handle' to
|
|
-- display Jerry's photo in the Info pop-up</em>
|
|
</pre>
|
|
</p>
|
|
|
|
<br clear="all" />
|
|
|
|
<h4>Method 3</h4>
|
|
<p>
|
|
Another way is to use each control's "data" space to pass
|
|
<i>name/value</i> pairs. It is possible to combine this method with one of the
|
|
others listed above to pass even more data.
|
|
</p>
|
|
<p>
|
|
A drawback to this method is that you can only pass strings,
|
|
not numbers. You can either pass the numbers as strings, e.g. "$1.95",
|
|
or use one of the above methods
|
|
instead.
|
|
</p>
|
|
|
|
<img src="../screenshots/flo.jpg" alt="flo.jpg" width="300px" align="right" />
|
|
|
|
<pre>
|
|
<em class="kw">constant</em> pie = <em class="str">"~/demos/thumbnails/pie.png"</em>
|
|
<em class="kw">constant</em> cake = <em class="str">"~/demos/thumbnails/cake.png"</em>
|
|
|
|
<em class="kw">constant</em>
|
|
btn1 = <em class="gtk">create</em>(GtkButton,<em class="str">"gtk-quit","Quit"</em>),
|
|
btn2 = <em class="gtk">create</em>(GtkButton,pie & <em class="str">"#_Pie"</em>),
|
|
btn3 = <em class="gtk">create</em>(GtkButton,cake & <em class="str">"#_Cake"</em>)
|
|
<em class="gtk">connect</em>({btn2,btn3},<em class="str">"clicked"</em>,_(<em class="str">"Foo"</em>))
|
|
<em class="gtk">add</em>(box,{btn1,btn2,btn3})
|
|
|
|
<em class="gtk">set</em>(btn2,<em class="str">"data","dessert","Pumpkin Pie"</em>)
|
|
<em class="gtk">set</em>(btn2,<em class="str">"data","price","$1.95"</em>)
|
|
<em class="gtk">set</em>(btn2,<em class="str">"data","pix"</em>,pie)
|
|
|
|
<em class="gtk">set</em>(btn3,<em class="str">"data","dessert","Birthday Cake"</em>)
|
|
<em class="gtk">set</em>(btn3,<em class="str">"data","price","$2.10"</em>)
|
|
<em class="gtk">set</em>(btn3,<em class="str">"data","pix"</em>,cake)
|
|
|
|
<em class="gtk">show_all</em>(win)
|
|
<em class="gtk">main()</em>
|
|
|
|
<em>--------------------------------</em>
|
|
<em class="kw">function</em> Foo(<em class="kw">atom</em> ctl)
|
|
<em>--------------------------------</em>
|
|
<em class="gtk">Info</em>(win,<em class="str">"Flo's Bakery"</em>,
|
|
<em class="gtk">get</em>(ctl,<em class="str">"data","dessert"</em>),
|
|
<em class="gtk">get</em>(ctl,<em class="str">"data","price"</em>),,,
|
|
<em class="gtk">get</em>(ctl,<em class="str">"data","pix"</em>))
|
|
<em class="kw">return</em> 1
|
|
<em class="kw">end function</em>
|
|
|
|
</pre>
|
|
</p>
|
|
|
|
<h4>But Wait, There's More!</h4>
|
|
<p>
|
|
You can pass almost any type of Euphoria variable as data attached to
|
|
a control, which means that you can also pass Euphoria routine_id's -
|
|
so your connected function can execute whatever Eu function is attached as
|
|
its data item.<br />
|
|
If you combine this with the ability to store and pass other information in
|
|
name/value pairs as shown in Method 3 above, you can have a single
|
|
Eu function that provides a number of different 'services' with very little code.
|
|
</p>
|
|
|
|
<a name="calendar"></a>
|
|
<h3><hr />Calendars<img src="../thumbnails/cal.png" alt="calendar" height="30px" align="left" /></h3><hr />
|
|
<p>The GtkCalendar widget has a variety of ways to set and get the calendar date:</p>
|
|
<img src="../screenshots/test31.jpg" alt="calendar" width="300px" align="right" />
|
|
|
|
<pre>
|
|
<em class="gtk">get</em>(cal,<em class="str">"day"</em>) => 26 <em>-- as integers</em>
|
|
<em class="gtk">get</em>(cal,<em class="str">"month"</em>) => 4
|
|
<em class="gtk">get</em>(cal,<em class="str">"year"</em>) => 2015
|
|
|
|
<em class="gtk">set</em>(cal,<em class="str">"day"</em>,<em class="orange">23</em>) <em>-- changes day only</em>
|
|
<em class="gtk">set</em>(cal,<em class="str">"month"</em>,<em class="orange">3</em>) <em>-- changes month only</em>
|
|
<em class="gtk">set</em>(cal,<em class="str">"year"</em>,<em class="orange">1946</em>) <em>-- changes year only</em>
|
|
|
|
<em class="gtk">get</em>(cal,<em class="str">"eu_date"</em>) => {115,4,26} <em>-- Y in Eu format</em>
|
|
<em class="gtk">set</em>(cal,<em class="str">"eu_date"</em>,{<em class="orange">115,1,4</em>}) => Jan 4, 2015
|
|
<em class="gtk">set</em>(cal,<em class="str">"eu_date"</em>,date()) => current computer date
|
|
|
|
<em class="gtk">set</em>(cal,<em class="str">"date"</em>,{<em class="orange">1960,11,2</em>}) => Nov 2, 1960
|
|
<em class="gtk">set</em>(cal,<em class="str">"date"</em>,{<em class="orange">44,11,15</em>}) => Nov 15, 1944
|
|
|
|
<em class="gtk">set</em>(cal,<em class="str">"date","11/25/1940"</em>) => Nov 25, 1940
|
|
<em class="gtk">set</em>cal,<em class="str">"date","1924/4/25"</em>) => Apr 25, 1924
|
|
</pre>
|
|
<br clear="right">
|
|
<pre>
|
|
<em class="gtk">get</em>(cal,<em class="str">"datetime"</em>) => returns calendar date and current clock time in datetime format.
|
|
<em class="gtk">get</em>(cal,<em class="str">"datetime"</em>,0) => returns calendar date in datetime format with h,m,s = 0.
|
|
|
|
<em class="gtk">get</em>(cal,<em class="str">"date"</em>) => Tuesday, May 26, 2015 <em>-- if no format provided,returns a string in default format shown</em>
|
|
<em class="gtk">get</em>(cal,<em class="str">"date","%a on %A!"</em>) => "Sun on Sunday!" <em>-- this will be right as often as the weather bureau!</em>
|
|
|
|
Format string can include the following specifiers, along with other characters of your choice:
|
|
%% -- a literal %
|
|
%a -- locale's abbreviated weekday name (e.g., Sun)
|
|
%A -- locale's full weekday name (e.g., Sunday)
|
|
%b -- locale's abbreviated month name (e.g., Jan)
|
|
%B -- locale's full month name (e.g., January)
|
|
%C -- century; like %Y, except omit last two digits (e.g., 21)
|
|
%d -- day of month (e.g, 01)
|
|
%j -- day of year (001..366)
|
|
%m -- month (01..12)
|
|
%u -- day of week (1..7); 1 is Monday
|
|
%w -- day of week (0..6); 0 is Sunday
|
|
%y -- last two digits of year (00..99)
|
|
%Y -- year
|
|
|
|
For example, <em class="gtk">get</em>(cal,<em class="str">"date","Today is %A, day #%j of the year %Y"</em>)
|
|
|
|
<i><u>Results</u></i><br />
|
|
Today is Monday, day #126 of the year 2013
|
|
|
|
The calendar will normally open with the current computer date, if you don't tell it otherwise.
|
|
|
|
You may also use a datetime function, such as:
|
|
|
|
today = <em class="kw">datetime:now</em>()
|
|
<em class="gtk">gtk:set</em>(cal,<em class="str">"date"</em>,today)
|
|
or
|
|
<em class="gtk">gtk:set</em>(cal,<em class="str">"date"</em>,datetime:add(today,30,DAYS)) <em>-- shows date 30 days from now</em>
|
|
|
|
</pre>
|
|
</p>
|
|
|
|
<a name="colors"></a>
|
|
<h3><hr />RGBA Colors
|
|
<img src="../thumbnails/applications-graphics.png" alt="colors" height="30px" align="left" /></h3><hr />
|
|
<p>
|
|
GTK 3 uses a 32-bit RGBA color structure which can be a bit tricky to use, so EuGTK
|
|
implements some functions to make the process simpler. With EuGTK, you can specify colors by:
|
|
<ul>
|
|
<li>name: "red" <em><small>--this is the preferred way, using the xcolor names</small></em>
|
|
<small> Refer to <a href="../resources/xcolors.txt">xcolors.txt</a> for a list of names</small></li>
|
|
<li>hex value: #FF0000 <em><small>-- #RRGGBB </small></em></li>
|
|
<li>hex string: "#FF0000" <em><small>-- as above</small></em></li>
|
|
<li>decimal value: 16711680 <small><em>-- seldom useful, who can remember what color this is?</em></small>
|
|
<li>rgb string: "rgb(255,0,0)" <em><small>-- r,g, and b colors are 0 => 255</small></em></li>
|
|
<li>rgba string: "rgba(255,0,0,0.5)" <em><small>-- as above, plus alpha in the range from 0 => 1</small></em></li>
|
|
</ul>
|
|
</p>
|
|
<p>
|
|
To retrieve colors from, for example, the GtkColorChooserDialog, use:
|
|
<pre><code> <em class="kw">object</em> color = <em class="gtk">get</em>(ccd,<em class="str">"rgba"</em>) <em>-- returns rgb or rgba string</em></code></pre>
|
|
To make manipulating colors easier, there are several format options available for the above call:
|
|
|
|
<pre><code> <em class="kw">object</em> color = <em class="gtk">get</em>(ccd,<em class="str">"rgba"</em>,N) <em>-- see table below for N values</em></code></pre>
|
|
<ul>
|
|
<li>0 = Euphoria sequence: {"rgb",255,0,0} or {"rgba",255,0,0,0.51}</li>
|
|
<li>1 = hex string: "#FF0000" <dfn> -- this is a string, not a hex number</dfn></li>
|
|
<li>2 = decimal number: 16711680 <dfn> -- this is a number, not a string</dfn></li>
|
|
<li>3 = 3-element Eu sequence: {255,0,0} <dfn>-- {R,G,B}, colors are 0=>255<dfn></li>
|
|
<li>4 = 4-element Eu sequence: {255,0,0,0.51} <dfn>-- {R,G,B,A} where alpha is 0=>1</dfn></li>
|
|
<li>5 = 4-element Eu sequence: {255,0,0,130.5} <dfn>-- {R,G,B,A} where alpha is 0=>255</dfn></li>
|
|
<li>6 = rgb or rgba string: "rgb(255,0,0)" or "rgba(255,0,0,.51)" <dfn>-- rgba returned if alpha != 1, otherwise rgb returned</dfn></li>
|
|
</ul>
|
|
Note: there is no mapping back to a xcolor name from any of the above
|
|
color formats.
|
|
</p>
|
|
|
|
<a name="memory"></a>
|
|
<h3><hr />Memory Usage<img src="../thumbnails/mongoose.png" alt="goose" height="30px" align="left" /></h3><hr />
|
|
|
|
<p>
|
|
<em><b><u>eui</u></b></em><br />
|
|
A modest sized EuGTK program, when run in interpreted mode, may use a relatively large
|
|
amount of memory, (a minimum of 25 to 50 megs on my computer). This is because almost
|
|
<i>all</i> of the Euphoria std libraries are loaded by EuGTK.<br />The source code will,
|
|
however, run on both 32-bit and 64-bit machines, if they have Euphoria installed.
|
|
WEE editor, for example, uses 107 megs. when interpreted.
|
|
</p>
|
|
|
|
<p>
|
|
<em><b><u>eubind</u></b></em><br />
|
|
The same program, when bound, may only require 10 or 20 megs, and the bound source will
|
|
take up perhaps 4 or 5 megs of disk space, since the binder removes the unused routines.
|
|
Bound programs run almost instantly, compared with interpreted programs.<br />
|
|
In addition, binding takes only a moment - often less than a second. Remember that bound
|
|
programs must be distributed in two forms - 32-bit and 64-bit versions. WEE uses 35.6 megs.
|
|
</p>
|
|
|
|
<p>
|
|
<em><b><u>eushroud</u></b></em><br />
|
|
This also works nicely, producing an obfuscated .il file which loads and runs <i>very</i>
|
|
quickly. In addition, the .il file will be much smaller than a bound file - perhaps 1/2
|
|
to 1/5 the size. Like bound programs, there must be both a 32-bit version and a 64-bit
|
|
version. WEE uses 22.7 megs.
|
|
</p>
|
|
|
|
<p>
|
|
<em><b><u>euc</u></b></em><br />
|
|
When compiled, the program will use only 3 or 4 megs of memory, and the runtime will be
|
|
small, perhaps 1 or 2 megs, and will start even faster, but it takes quite a while to
|
|
compile. I only compile a program when I'm certain that all the bugs have been worked out.
|
|
You may prefer to distribute your program in compiled form. Just remember, you will need
|
|
to provide separate 32-bit and 64-bit versions. WEE uses only 8.3 megs!
|
|
</p>
|
|
|
|
<p>
|
|
<em><b><u>Conserving Memory</u></b></em><br />
|
|
In general, each widget you create will require some amount of memory, so you should
|
|
avoid creating (or re-creating) them in loops that might run for many iterations.
|
|
Instead, create them outside the loop, and simply
|
|
hide() and show() them as required. If widgets <i>must</i> be created within function
|
|
calls, try to <i>destroy()</i> them before
|
|
returning from the call to keep from wasting memory.
|
|
</p>
|
|
|
|
<a name="debugging"></a>
|
|
<h3><hr />Debugging<img src="../thumbnails/bug-buddy.png" alt="bug" height="30px" align="left" /></h3><hr />
|
|
<p>
|
|
In the table below are some command-line switches you may use to get into the inner
|
|
workings of EuGTK.
|
|
All but the first are generally only needed when maintaining EuGTK itself, but there
|
|
may be times when you can use them to help you find a programming error.
|
|
Of course, you must run your program from an x-terminal in order to see the output!
|
|
</p>
|
|
|
|
<table class="testing" border="1">
|
|
<th width="20%">Switch</th><th>Output</th><th>Comment</th>
|
|
|
|
<tr>
|
|
<td><b>-d COMPILE</b></td>
|
|
<td><code><pre><b>Caution: function Foo will not link when compiled!
|
|
********</b></pre></code>
|
|
</b></td>
|
|
<td><b>Use before compiling so you can fix links</b></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-d CREATE</td>
|
|
<td><code><pre>Create
|
|
Call: GtkWindow->new
|
|
Params: Int
|
|
Return type: Ptr
|
|
Vector: 101
|
|
Args: {0}
|
|
GtkWindow=>37278096</pre></code>
|
|
</td>
|
|
<td>Vector is the routine_id assigned to the function "gtk_window_new"
|
|
by EuGTK's "init" procedure.<br /><br />The number following the =>
|
|
is the 'handle' to the newly-created window.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-d SET</td>
|
|
<td><code><pre>Set
|
|
Call: GtkWindow->set_default_size
|
|
Params: Ptr Int Int
|
|
Return type: None
|
|
Vector: 107
|
|
Args: {37278096,300,80}</pre></code>
|
|
</td>
|
|
<td>Args are: 'handle' to the widget being 'set', and following that are
|
|
the parameters being passed, in this case, two integers, width and height.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>-d GET</td>
|
|
<td><code><pre>Get
|
|
Call: GtkComboBoxEntry->get_active_text
|
|
Params: Ptr
|
|
Return type: Str
|
|
Vector: 277
|
|
Args: {30175312}
|
|
Result: Banana</pre></code>
|
|
</td>
|
|
<td>Vectors > 0 are direct calls to GTK routines generated via define_c_func or define_c_proc.Vectors less than -1 mean that the call is to a function written in Euphoria, in which case the vector is the negated RID. </td>
|
|
</tr>
|
|
<tr>
|
|
<td>-d INIT</td>
|
|
<td><code><pre>Init class:GtkButton...
|
|
set_image_position 510
|
|
get_image_position 511
|
|
set_always_show_image -1
|
|
get_always_show_image -1</pre></code>
|
|
</td>
|
|
<td>The numbers represent the routine_id that Euphoria has assigned to the GTK calls.
|
|
<br />Use -d INITX for detailed listing.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-d INIT_ERR</td>
|
|
<td><code><pre>ERR:GtkWindow set_titlebar -1
|
|
ERR:GtkWindow close -1
|
|
ERR:GtkBox set_baseline_position -1
|
|
ERR:GtkBox get_baseline_position -1
|
|
ERR:GtkButton set_always_show_image -1
|
|
ERR:GtkButton get_always_show_image -1
|
|
ERR:GtkWidget get_frame_clock -1</pre></code></td>
|
|
<td>When the number is -1, that means the call is invalid, usually because the version
|
|
of GTK you are using does not implement that call.<br /><br />
|
|
'always_show_image' is only available in GTK 3.6+, for example.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-d INI</td><td>
|
|
<pre>-- Ini file for test173.ex
|
|
My Calendar={"date",{2015,4,5}}
|
|
ColorButton={"rgba","rgb(255,255,255)"}
|
|
MyCheckButton1={"active",1}
|
|
FontButton={"font name","Sans"}
|
|
</pre></td><td>Used to display data written to settings (ini) file on x-term</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-d FUNC</td><td><pre>FUNC g_slist_nth_data 162
|
|
PARAMS {50331649,16777220}
|
|
Values {24122256,103}</pre></td>
|
|
<td>Debug calls to gtk_func() and gtk_str_func()</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-d PROC</td>
|
|
<td><pre>PROC g_set_prgname 37
|
|
PARAMS {117440516}
|
|
Values widgets.ex</pre>
|
|
</td><td>Debug calls to gtk_proc</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-d PIXBUF</td><td><pre>Pixbuf from file /home/irv/Pictures/IMG_0020.JPG
|
|
Scaled 300x300 1</pre>
|
|
</td><td>For debugging pixbuf creation</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>-d PIXBUF_ERR</td><td><pre>CAUTION: cannot create pixbuf from /home/irv/Pictures/map.pdf</pre>
|
|
</td><td>For debugging pixbuf errors</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td><b>-d BUILDER</b></td>
|
|
<td><a href="../screenshots/hello.png">Screenshot</a></td>
|
|
<td>Used to display namespaced objects loaded from Glade</td>
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
</p>
|
|
|
|
<a name="settings" />
|
|
<h3><hr />Settings<img src="../thumbnails/gnome-run.png" alt="gears" height="30px" align="left" /></h3><hr />
|
|
|
|
<p><u><em class="blue">Updated for EuGTK 4.11.10</em></u></p>
|
|
<p>
|
|
The ability to very easily save selected settings from one run to the next has been added in EuGTK 4.10.0.
|
|
This includes saving the 'state' of active controls, such as spin buttons, check buttons, color buttons,
|
|
font buttons, etc. as well as saving <i>selected</i> properties of any GtkWidget, such as the preferred background color,
|
|
font, position or size of windows, etc., from run to run.
|
|
</p>
|
|
|
|
<p>
|
|
IOW, your arrangement of things at the time the program was closed will be restored next time the program is run.
|
|
Refer to <a href="../test153.ex">test153.ex</a> and <a href="../resources/test153.ini">test153.ini</a> for some examples. Below is a sample
|
|
file, which can have any name and extension. <i>.ini</i> works fine, and is familiar. Note that it is plain text,
|
|
so it's easily edited, and comments are preserved when it's updated. It uses simple <i>name</i> <small>(dot)</small> <i>property</i> notation.
|
|
</p>
|
|
|
|
<p>
|
|
For commonly-used controls, there is a default property defined in GtkSettings.e,
|
|
which can be saved/loaded simply by adding the control's handle or name to a list of
|
|
controls to pass to settings:Save(). Note that controls to be saved MUST have a name!
|
|
These default states are restored when the ini file is loaded.
|
|
</p>
|
|
|
|
<p>
|
|
For saving other (non-default) properties, you must add one line of code to save
|
|
that property. No additional effort is required when loading the settings,
|
|
the property will be reset automatically to the saved value when the ini is loaded.
|
|
</p>
|
|
|
|
<p>
|
|
For saving bits of data which are NOT properties of a given widget, you can use the
|
|
widget's named <i>data</i> spaces (a.k.a. key/value pairs) to store almost
|
|
anything you want. For these, your program code must specifically read the
|
|
data item when it needs to use it:
|
|
<br /><code><em class="gtk">get</em>(<em class="str">"MainWindow","data","Foobar"</em>) => "Baz!"</code>
|
|
</p>
|
|
|
|
<p><pre><em>
|
|
----------------------------------------------------------------------------
|
|
-- Following items are 'persistent', only changed by editing this file:
|
|
----------------------------------------------------------------------------</em>
|
|
--!MainWindow.icon=face-smile
|
|
--!MainWindow.border width=20
|
|
|
|
--!Label1.text=Move, resize, change color, etc...
|
|
--!ColorChooserButton.tooltip text=Pick a color for the Main Window background
|
|
--!Font Button.tooltip text=Select font for calendar
|
|
<em>
|
|
------------------------------------------------------------
|
|
-- Following items are added by the settings:Save() command
|
|
-- using the default properties for the controls on the list
|
|
-- your program provides, or by the settings:Add() command,
|
|
-- using properties you specify.
|
|
------------------------------------------------------------
|
|
</em>
|
|
<em class="brown">MainWindow.data.Foobar</em>=Baz!
|
|
<em class="brown">MainWindow.data.Message</em>=Thanks a lot!
|
|
<em class="brown">MainWindow.background</em>=<em class="orange">#729FCF</em>
|
|
<em class="brown">MyCalendar.font</em>=Serif Bold Italic 12
|
|
<em class="brown">ColorChooserButton.rgba</em>=<em class="orange">#729FCF</em>
|
|
<em class="brown">FontButton.font</em> name=Serif Bold Italic 12
|
|
<em class="brown">MyCalendar.date</em>={<em class="gtk">2016,4,10</em>}
|
|
</pre>
|
|
</p>
|
|
|
|
<footer>
|
|
<div class="hint">
|
|
<img class="hint" src="../thumbnails/mongoose.png" alt="hint" align="left" float="right" />
|
|
<p>
|
|
This page edited by The <a href="README.html#bear">Bear</a>,
|
|
a web-page and programming editor
|
|
written in <a href="OpenEuphoria.org">Euphoria</a>.
|
|
</p>
|
|
<p>Updated for EuGTK version 4.12.0, Sept 15, 2016
|
|
<br />All code © 2016 by Irv Mullins
|
|
</p>
|
|
</div>
|
|
</footer>
|
|
|
|
</body>
|
|
</html>
|