GTK4 and Gemini experiment

new topic     » topic index » view thread      » older message » newer message
 
---------------------------------------------------- 
-- # 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

new topic     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu