GTK4 and Gemini experiment
- Posted by irv 1 week ago
- 227 views
---------------------------------------------------- -- # About Dialog Demo (Euphoria / GTK 4) ---------------------------------------------------- include euphoria/info.e -- High-level GTK 4 wrapper module imports include gtk4.e include application.e include application_window.e include css_provider.e include box.e include label.e include action_bar.e include button.e include g_file.e include about_dialog.e -- Application ID following reverse-DNS naming convention constant app_id = "org.gtk.app200" ---------------------------------------------------- -- Setup Callback: Constructs the main UI window ---------------------------------------------------- function setup(atom app) -- 1. Load custom CSS styles from disk object css = CssProvider:new("css/gtk4.css") -- 2. Construct top-level Application Window object win = ApplicationWindow:new(app) __("add css class", "decor1") -- Apply custom CSS class __("size", 100, 150) -- Set default dimensions __("resizable", FALSE) -- Lock window dimensions __("present") -- Realize and show window -- 3. Main container: Vertical box with 5px spacing between elements object panel = Box:new(1, 5) __("margins", 10, 10, 5, 10) -- Start, end, top, bottom margins add(win, panel) -- 4. Header Label using inline Pango Markup object lbl = Label:new("<b>About Dialog</b>") __("vexpand", TRUE) -- Allow label space to expand vertically add(panel, lbl) -- 5. Exit Button: Binds 'clicked' event directly to destroying the main window object btn1 = Button:new("E_xit", "destroy", win) __("tip", "Click to Exit") -- 6. Construct persistent About Dialog instance object about = build_about_dialog() -- 7. About Button: Shows the pre-built About Dialog instance object btn2 = Button:new("_About", "show", about) __("name", "btn2") __("name", "About") __("tip", "Click to show About Dialog") -- 8. Bottom Action Bar: Houses control buttons object btnbar = ActionBar:new() __("pack start", btn1) -- Align Exit button to the left __("pack end", btn2) -- Align About button to the right add(panel, btnbar) return win end function -- Create C-compatible callback pointer for the GApplication "activate" signal constant setup_cb = call_back(routine_id("setup")) -- Initialize and run the GtkApplication lifecycle object app = Application:new(app_id) Application:activate(app, setup_cb) Application:run(app) ---------------------------------------------------- -- Helper: Dynamically builds system information text ---------------------------------------------------- function generate_sysinfo() -- Query Euphoria system library for copyright data object cr = info:all_copyrights() -- Format and word-wrap copyright string segments to fit dialog bounds object cr1 = cr[1][2] cr1 = text:wrap(cr1, 40, "\r", ".") object cr2 = cr[2][1] & "\r" & text:wrap(cr[2][2], 40, "\r", " ") -- Combine into formatted system info string return sprintf("🖥️ Eu version: %s\r%s\r\r%s", {info:version_string_short(), cr1, cr2}) end function ---------------------------------------------------- -- Dialog Builder: Instantiates & configures GtkAboutDialog ---------------------------------------------------- function build_about_dialog() -- Load image file and convert to GdkTexture pointer expected by GTK 4 atom eu_logo = GFile:texture(canonical_path( "~/gtk4/images/EuGTK.png")) -- Instantiate new GtkAboutDialog widget atom dlg = AboutDialog:new() -- CRITICAL GTK4 LIFE-CYCLE PATTERN: -- Intercept 'close-request' and call 'hide' instead of destroying the dialog window. -- This keeps the GtkAboutDialog alive in memory so it can be re-presented. connect(dlg, "close-request", "hide", dlg) -- Apply metadata & styling properties __("add css class", "decor3") __("program name", program_name) __("version", "Version 1.0") __("copyright", "Copyright 2026") __("license type", GPL_3_0) __("comments", "GTK version: " & gtk_version_str) __("website", "https://openeuphoria.org") __("website label", "OpenEuphoria") __("logo", eu_logo) -- Pass Euphoria string sequences across FFI boundary as C NULL-terminated string arrays __("authors", {"✍ Irv Mullins", "Based on an idea💡 by Dave Cuny"}) __("system information", generate_sysinfo()) __("artists", {"🖍️ Picasso", "🎨 Da Vinci", "🖌️ van Gogh"}) __("wrap license", TRUE) return dlg end function
/*
**Key Takeaways & Learning Points from Your Architecture**
This is an elegant implementation. It demonstrates a clean
object-oriented Euphoria wrapper around GTK 4, featuring a
clever `__` procedure shorthand for property setting and signal binding.
**The `__()` Property DSL:**
Using a helper function `__("property", value)`to operate
on the active or previously instantiated GTK widget
keeps UI layout code clean, declarative, and readable
without repeating object handles.
**Persistent Window Lifecycle:**
Connecting `"close-request"` directly to `"hide"`
(`connect(dlg, "close-request", "hide", dlg)`)
solves GTK 4's default window-destruction behavior.
It keeps the GtkAboutDialog allocated in memory
so `gtk_window_present` can re-display it instantaneously
without re-allocating textures or string arrays.
**Clean FFI Array Marshalling:**
Passing high-level Euphoria sequences e.g.
`{"🖍️ Picasso", "🎨 Da Vinci"}`) to `__("artists",...)`
shows that your wrapper cleanly handles converting
Euphoria strings into `const char* const*`
C NULL-terminated pointer arrays under the hood.
*/
Link to image: https://drive.google.com/file/d/1zcH-BvtEPvgxHDyfvX_2JoDm9BxxT8bM/view?usp=sharing

