This package should be up-to-date with GTK version 3.21.4. Tested with GTK 3.18.9 on Linux Mint 18 Cinnamon 64-bit and Gtk 3.10.8 on Mint 17.2 Rafaela 64-bit, as these are the most-popular distros with the latest stable GTK 3 versions included. Also, tested on Windows 7 64-bit with Gtk 3.20.2.
The Good News:
GTK3 is better both in ease of use and in
the ability to produce attractive, modern program interfaces than any other GUI libraries
I've tried. GTK3, unlike most of the other GUI libraries, has functions
to handle touch screens.
Linux distros such as Ubuntu, Mint, Ultimate, Parsix, etc. come with GTK3 libraries already installed. If necessary, you can install GTK3 alongside GTK2 without problems. Apt-get will do it for you. Or, in your package manager, look for libgtk-3-0. If you can't get libgtk-3, then it may be time to think about updating your ancient Linux installation.
In addition, EuGTK 4.9.0 and up works with OS X™. It also works on Windows™, but I cannot recommend this. Windows has become entirely too awkward to use and maintain.
(Once upon a time I succeeded in nailing some jelly to a tree. That doesn't mean I'd consider jelly-nailing to be a good career choice.)
The same EuGTK engine and sourcecode can be used on any of the three platforms without change, except for possibly missing icons on different platforms. You can supply your own icons if appearance is important.
More Good News:
Compared to other programming language/GUI combinations,
EuGTK is very simple to set up and to use.
There is only one 'include' you must add to your programs, which is 'include GtkEngine.e'.
There are only a few files that need to be available when you write, test,
run or perhaps compile your program - GtkEngine.e and GtkEnums.e. Adding, when required,
GtkPrinter.e, etc...
No additional files are produced or needed other than the code you write and the standard
Euphoria library files. This makes project management simpler, and
if you want to ship EuGTK with your program, the required files only add about 350k to
the total package (74k if compressed!).
Also, EuGTK is easier to use because EuGTK adds some 'intelligence' that is missing from other languages, (like C or Python), such as the ability to create images from a variety of sources without the programmer having to call a different function for each source type. See variants.
In addition, EuGTK is easy to keep up-to date with the latest versions of GTK because all of EuGTK is written in Euphoria, so it can easily be edited by anyone, with no re-compiling or other tricky steps involved.
You'll need the latest Euphoria 4 interpreter from OpenEuphoria.org. I use Euphoria 4.1.0 beta. Plus, you'll really need the latest GTK docs! Get 'em from gtk.org.
Just open the gzipped package (I guess you've already done that) and drag the 'demos' folder into your home folder. All files are in the demos folder (and subfolders thereof). Try them so you'll know what you can do with GTK!
Installation
Later, you can put these files - GtkEngine.e, GtkEnums.e, GtkPrinter.e, etc. -
into the folder with your other Euphoria includes, or just add a one-line
eu.cfg file to any directory you wish to work in, pointing to the location
of these files. My Euphoria/include folder is /usr/local/share/euphoria/include.
Moving all the Gtk***.e files from the demos folder into there works.
Be sure to add this eu.cfg to your home directory as well, otherwise, eu programs will not be able to find the necessary GtkEngine.e when you start a program from your file manager (such as caja).
My eu.cfg reads:
~/demos
First, open an x-term, cd to the demos directory, and run a program: $> eui test0
Running from an x-term is mandatory while you are writing your Euphoria/GTK programs, so that you can see error messages and crash reports, but not necessary once you have your program working and debugged.
************************************ Fatal Error: no libgtk-3.so.0 found! ************************************
If you get the above error message, either you do not have libgtk-3 installed (try apt-get or your package manager), or it has been installed in an unexpected location. Check lines 66 thru 88 at the top of GtkEngine.e and make changes as necessary.
Now try as many of the test programs as you can, they will help you find incompatibilities (if any) with the version of the GTK library you are using.
Running these test programs is also the best way to see what GTK offers for use in your own programs.
Now, get busy!
If you haven't read How it Works yet, please do so now!
You can use any plain text editor to create your EuGTK programs. I use either Pete Eberlein's great WEE editor (written in Euphoria), sometimes Pluma or Geany, or the GtkSourceView widget, which also works well, and could easily be expanded into a full-featured programmer's editor.See Programmer's Resources for an overview.
The WEE editor (recommended!) automatically colorizes Euphoria source code, and moves the cursor to the file/line where a syntax error occurs.
For WEE:
Pop-up help for both Euphoria and GTK keywords is available by pressing the [F1] key. See
instructions here.
In the ~/demos/resources/geany_syntax folder you will find files to add Euphoria syntax highlighting to Geany, as well as an add-on program by Kenneth Rhodes which moves the Geany edit cursor to the error line in your Eu program.
In the ~/demos/resources/gedit_syntax folder you will find files to add Euphoria syntax highlighting to Pluma, GEdit, GtkSourceView, the BEAR, etc.
It is also possible to use Glade to design your program layout. You will need the latest version of Glade (3.16 or up). See the following programs for demos: calendar.ex and calendar.glade. and clock.ex and clock.glade. Also, please read XML/GtkBuilder.
Before you start coding, please read HowItWorks to get an overview, then open guide_a.html in your browser for links to demos showing how the various controls (a.k.a. widgets) are used.
You'll also need the latest GTK 3.0 docs (from gtk.org), since there are perhaps 4x more methods available than I have used in the demos. Some of these methods can be ignored, since there are easier-to-use equivalents in Euphoria itself.
There are three possible sources of error messages: Euphoria, GTK, and EuGTK.
Euphoria gives you the line number and description of the error, but these will only appear
in a console - there will not be a pop-up error dialog - since these come directly from the Euphoria
interpreter, before GTK is running! Spelling errors, undeclared variables, and such will appear here:
<0074>:: Errors resolving the following references: 'GtkBufton' (text16.ex:39) has not been declared. constant okbtn = create(GtkBufton,"gtk-ok","Foo") ^
GTK errors, which also only appear when running from a console, will sometimes display an enigmatic message that will take some effort to understand. Best way to debug these errors is to comment out blocks of code, and then uncomment one line of code at a time, and see which line triggers the error message. Then consult the GTK docs to see what GTK is expecting vs. what you've written:
(test174.ex:3126): Gtk-WARNING **: Can't set a parent on a toplevel widget ** Gtk:ERROR: /build/buildd/gtk+3.0-3.4.2/./gtk/gtkcontainer.c:3292: gtk_container_propogate_draw: assertion failed: (gtk_widget_get_parent(child) == GTK_WIDGET (container)) Aborted
Error: function Foo is not in scope ****** (make it global or link via call_back(routine_id())
CAUTION! |
---|
If you plan to compile your EuGTK program, please read HowItWorks to see the correct way to link controls to your Euphoria functions! |
Another possible error occurs when you create a GTK widget with a version of libgtk-3 which does not implement that widget. You have 3 choices in this event: use something else, create your own custom object to simulate the new widget, or update your version of libgtk-3. The last is often not possible, usually you will find it easier to update to a newer Linux distro which includes the latest libgtk-3 instead.
Fatal Error: GtkMenuButton ************ not implemented in this GTK library version
When you use a recently-implemented GTK widget in a program you plan to distribute, it is a good idea to check the libgtk version and if necessary present an error message. Use the requires() function for this. See test193.
There are several other flags you can set to display debugging info. See Debugging section of HowItWorks.html
Starting with GTK version 3.10, the old GTK stock items are deprecated, and new programs should not use them. Instead, use named icons. This is good, because the set of stock buttons was limited, and some were missing altogether. There's a far wider variety of named icons to choose from - except on Windows™, where there are very few. This is a problem which can be avoided by packaging your own custom icons with your program.
You can most easily see all the available icons by running examples/icons.ex. It now has a handy search feature, which is a great help when choosing the buttons and menus for your nifty new programs!
However, using named icons means more work for the programmer, usually involving several lines of
code just to create each button. To solve this problem and make the transition to named icons easier,
this version of EuGTK adds a new, more flexible way to create GtkButtons.
Old Style:
constant btn1 = create(GtkButton,"gtk-edit",...)
-- button caption and icon are pre-set, not easily changed,
-- but nice-looking and easy to use. This is the leftmost button above.
New Style:
constant btn1 = create(GtkButton,"text-editor#_Edit",...)
-- this uses a named icon and your own label.
-- Run examples/icons.ex to search for a suitable icon.
-- These themed icons should change appearance to match the
-- current theme the user selects.
Please note the new hashtag# syntax:
constant btn1 = create(GtkButton,{"gtk-edit#_Edit",...}
-- changing the caption and hot-key as desired
-- icon name is first, caption second, separated by #.
-- Optional underscore prepends the hot-key in caption
-- this button is shown above, center
constant btn1 = create(GtkButton,"~/demos/thumbnails/4_rhombuses.gif#_Colors",...)
-- You can set the button image from a file (even animated!),
-- so you can customize your program's appearance.
-- You can even have "check images" that change depending
-- upon their state! (see test15)
Someone now [only temporarily, I hope] in charge of GTK decided that having images on buttons and menu items was a bad idea. They cite some academic study which 'proved' that people are quicker at choosing the correct button out of an array of buttons if the buttons contain nothing but boring text captions.
Did this same 'academic study' prove that traffic signs didn't need to be different colors and shapes? If not, why not?
So they're gone as of GTK3.14. I guess they don't want people with dyslexia to use their computers.
If you don't like images, you don't have to use 'em, but if you do like them, don't worry too much, I can outsmart them and put those images back. See, for example, test25.
Interactive Debugger
This change is actually a good idea. You can, starting with GTK3.14, enable a pop-up GTK+ Inspector by adding one line of code just before the call to main():
show_all(win)
set(win,"interactive debugging",TRUE)
main()
This interactive debugger allows you to view the widget hierarchy and experiment with various settings while your program is running! It also lists the applicable properties and signals for each selected widget.
New Types
Gtk widget types have been added to EuGTK. You can now declare Euphoria objects as GTK types,
as follows:
As you can see, you just use the Gtk widget name, sans the 'Gtk' part.
It's generally not necessary nor even a good idea to use these.
They are provided mainly for use in the rare occasion where it is necessary to
register and "type cast" a Euphoria function parameter. Most objects passed as
function params already 'know' their type, as do all that are created as Eu
constants, objects, or atoms, so this is seldom necessary.
function Foo(Window w, Button b)
Settings
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 specified properties of any GtkWidget, such as the preferred background color,
font, position and size of windows, etc., from run to run. You can do this without having to write lines of code to save, parse, and restore each setting. Just supply the name
of an .ini file and a list of control handles you wish to save/restore to the save_settings() or load_settings() functions.
Refer to test153.ex, test153.ini, test173.ex, test173.ini, test201.ex, and test201.ini for some examples. Below is a sample file, which can have any name and extension. (.ini works fine, and is familiar) Note that the file is plain text, so it's easily edited, and comments are preserved when it is updated.
---------------------------------------------------------------------------- -- Following items are 'persistent', only changed by editing this file: ---------------------------------------------------------------------------- --!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 ------------------------------------------------------------ -- Items beginning with + are added via the settings:Add() -- function called in your program code, as they are not a -- default property as defined in GtkSettings.e -- They can also be added by manually editing the ini file. -- Items without the leading + sign are saved automatically, -- by passing a list of names or handles of controls to -- the settings:Save() function. -- You may also save and restore widgets named data spaces -- by settings:Add(ini,ctl,"data.name","value") -- see MainWindow.data lines in blue below. ------------------------------------------------------------ +MainWindow.data.Foobar=Baz! +MainWindow.data.Message=Thanks a lot! +MainWindow.background=#FCE94F +MyCalendar.font=TakaoPGothic Bold Italic 12 ColorChooserButton.rgba=#FCE94F Font Button.font name=TakaoPGothic Bold Italic 12 MyCalendar.date={2016,6,8}
In order to make programming even easier, I've added a new way to set properties at the time a widget is created. This doesn't replace the previous set(... functions, just allows you to use a shorter method if you wish. It may be faster than the old method, since it can avoid multiple lookups.
constant win = create(GtkWindow,{
{"title","Simple Text Viewer"},
{"default size",600,500},
{"position",GTK_WIN_POS_CENTER},
{"icon","~/demos/thumbnails/mongoose.png"},
{"connect","destroy","Quit"}})
In simple cases, an even easier-to-use syntax is possible using key/value pairs. See screenshot at top of page.
constant win = create(GtkWindow,
"title=Hello world!,size=300x100,background=green,border=10")
You can freely mix these styles in your program, using whichever notation is the cleanest and clearest. Because this last version uses Eu 4.0 key/value pairs, not all settings can be made this way. You can't, for example, pass Eu variables or Gtk constants as part of the settings string, except for the constants TRUE, FALSE, HORIZONTAL, and VERTICAL, which are specifically allowed.
EuGTK 4.11.0 has a Custom dialog which allows adding almost any widget(s) to an easy-to-use pop-up dialog, with basically one line of code. See dialogs.html and test87.ex for details.
A plug and socket demo (plug.ex, sock.ex) has been added, to allow embedding widgets from one process into another process. I haven't been able to dream up a real need to do this so far.
To Do: find a useful program that needs this!
EuGTK 4.8.9 has a new 'plug-in' feature, added in order to implement the GtkSourceView and WebKit widgets.
The SourceView widget offers automatic language recognition and syntax highlighting for a huge number of programming languages (about 110, I think).
I've put the SourceView functions into a plugin. This loads the additional required shared library and the links to the functions contained in that library. You only need to include the GtkSourceView.plugin when you want to use this editor widget.
A set of syntax files for Euphoria 4.0 by Mario Steele can be found in /demos/resources/gedit-syntax. Just copy them as instructed in the README.
One reason for making this a plugin is that some installations don't automatically include the GtkSourceView library. Making the sourceview code an integral part of GtkEngine.e would cause problems if the sourceview library could not be found. A second reason; having it separate makes it easier for me to continue adding sourceview functions. Currently only a few are implemented, but it is useful nevertheless. I use it to edit these web pages and my demo programs. See test201).
To Do: implement code completion and search functions
EuGTK also includes a WebKit plugin, which allows you to incorporate a web browser widget into your program. You are free to implement - in Euphoria! - features that may not even be available on Firefox™ or Chrome™!
The WebKit plugin includes a pop-up Web Inspector, similar to that in Firefox™ and Chrome™.
Like the SourceView, this plugin is still under development, but is quite usable already. See examples/webkit.ex
To Do: implement security and script-running features
With the latest versions of GTK, you can specify the Broadway server (broadwayd) to run your EuGTK programs, and view them on any connected device which has an up-to-date HTML5 web browser such as Firefox™. Neither Euphoria nor EuGTK are required on the client!
The Broadway server that comes with Mint 18 works GREAT!. Over 95% of the 200+ demos work with Firefox 47.0, and most of those that fail could probably could be modified to work.
I have had as many as 50 EuGTK programs running simultaneously in a single Firefox browser window, while only using about 50% CPU.
That's an acronym for a small program, a little over 800 lines of code, which took a couple of days to write and test.
Since it's written in Euphoria, the single source code file is only 21.5k in length,
The BEAR has already been used extensively to edit these doc pages. If you look at the raw html, you'll see how much cleaner it is now than before :)
Encorporating a full-fledged web browser widget similar to Firefox™, and a source-code editor which can recognize and colorize over 100 programming languages, this allows me to browse and edit html pages, and if those pages contain links to source code, display and edit the source. If the source is Euphoria, you can also test run the program! (Other languages could easily be added.)
The web browser panel has buttons to zoom in / out, and the editor panel has selectable fonts, optional line numbers and the ability to make visible "white space" characters, such as spaces and tabs.
When html pages are edited, the Web view is refreshed whenever the editor Save button is clicked, so that changes are instantly visible.
Modified source code is saved to temp files for the test run. Your BEAR preferences are stored in a hidden file: .bear.ini located in your $HOME directory.
The BEAR requires the latest versions of both libgtksourceview-3 and libwebkit2gtk-3.
Below is a simple "Hello World!" program written in C, taken from the GTK docs (with comments removed). Following that is the same program written in EuGTK.
C Code |
---|
|
Euphoria |
----------------------------------------------------------------- -- Purpose: -- Show a window with a button; when the button is clicked, -- print "Hello World" on the terminal, then exit. --------------------------------------------------------------------- include GtkEngine.e constant window = create(GtkWindow, {"title","Hello"}, {"border width",10}, {"connect","destroy","Quit"}, {"connect","delete-event","on_delete_event"}}) constant button = create(GtkButton, {"label","Hello World"}, {"connect","clicked","print_hello"}, {"connect","clicked",destroy,window}}) add(window,button) show_all(window) main() global function print_hello() puts(1,"Hello World\n") return FALSE end function global function on_delete_event() puts(1,"delete event occurred\n") return FALSE end function |
Now you know why C programmers grow bald at an earlier age than others.
Even with this simple program, you can see the difference. As C programs grow larger, they become increasingly littered with type-casts, pointer references, etc., while the Euphoria code remains shorter and much more readable.
For example, compare the following two equivalent lines of code:
Or to put it another way, the C code is full of distracting 'noise', while Euphoria is cleaner and quieter. Other than that, the program structure is in other respects pretty similar, so that you can port a C or Python program to Eu in many cases without much difficulty. I've done just that for many of the test programs in this package.
4.11.5: To make space for new openGL graphics, the seldom-used Pango text and Cairo drawing functions have been moved to their own include: GtkCairo.e. If your program uses Cairo graphics or PangoFont calls, the only change needed in your source code is to include GtkCairo.e following GtkEngine.e. See test60 for example.
To add [F1] pop-up html help for Gtk widgets, as well as Euphoria keywords, make the change shown below to wee.exw:
global procedure context_help()
sequence text, decls, word, name_space, path
integer pos, junk
object help
text = get_edit_text()
pos = get_pos()
word = word_pos(text, pos)
if length(word) < 2 then
name_space = ""
word = ""
else
name_space = word[2]
word = word[1]
end if
-- add the following 4 lines to add pop-up GTK help:
if match("Gtk",word) = 1 then
ui_show_uri("FILE://" & canonical_path(sprintf("~/gtk3/%s.html",{word})))
return
end if
-- my GTK docs are in a gtk3 folder in my home directory
-- adjust as necessary for your setup.
Tested with | ||||
---|---|---|---|---|
Euphoria | GTK | Distro | Arch | Platform |
4.0.4 | 3.0.8 | Ultimated Edition 3.0 | 32-bit | AMD Athlon II X2 220 processor, 2800mhz, 4gig |
4.0.5 | 3.0.8 | Ultimated Edition 3.0 | 32-bit | AMD Athlon 64x2 processor, 1000mhz, 873meg |
4.0.5 | 3.2.0 | Mint 12 * | 32-bit | Pentium M processor, 1500 mhz. 487 megs |
4.1.0 | 3.0.8 | Mint 11 | 32-bit | Pentium M processor 1.5ghz, 512meg |
4.1.0 | 3.4.1 | Luninux (Ubuntu 12.04) | 64-bit | AMD Athlon II X2 220 processor, 2800mhz, 4gig |
4.1.0 | 3.4.2 | Mint 13 * | 64-bit | |
4.1.0 | 3.6.0 | Mint 14 * | 64-bit | |
4.1.0 | 3.6.2 | Manjaro xfce 0.8.3-x86-64 * | 64-bit | |
4.1.0 | 3.6.4 | Mint 15 Mate * | 64-bit | |
4.1.0 | 3.8.4, | Mint 16 Cinnamon * | 64-bit | |
Above, 14-year-old laptops | ||||
4.1.0 rev. 4467, | 3.10.6 | Parsix 4.0 (Gloria) * | 64-bit | Intel Core 2 Quad CPU 2.33 ghz 8 gig |
4.1.0 rev. 5783 | 3.8.4 | Mint 16 * | 64-bit | |
4.1.0 | 3.10.2 | SalentOS (Ubuntu 14.04) * | 64-bit | |
4.1.0 rev. 6238 | 3.10.8 | Mint 17 Cinnamon * | 64-bit | |
4.1.0 | 3.10.8 | Mint 17 Mate * | 64-bit | |
4.1.0 | 3.14.7 | Ubuntu Vivid 3.18.0-9-generic * | 64-bit | |
4.1.0 | 3.6.4 | Windows 7 | 64-bit | |
4.1.0 b2 | 3.10.8 | Mint 17 * | 64-bit | |
4.1.0 b2 | 3.14 | Ubuntu Vivid | 64-bit | |
4.1.0 development | 3.16.6 | Ubuntu MATE 15.10 * | 64-bit | |
4.1.0 rev. 6318 | 3.16.6 | Mint 17 * works fine! | 64-bit | |
4.1.0 rev. 6318 | 3.18.9 | Ubuntu 16 * has a few bugs | 64-bit | |
4.1.0 rev. 6318 | 3.18.9 | Mint 18 * | 64-bit | |
4.1.0 rev. 6318 | 3.20.2 | Windows™ 7 | 64-bit | |
* Best results |