forum-msg-id-139376-edit
Original date:2026-08-11 16:06:42 Edited by: irv Subject: GTK4 and Gemini experiment
---------------------------------------------------- -- # 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
|
Not Categorized, Please Help
|

