MODULE headerbar ; (* m2-GTK4 example - a header bar with window controls. A GtkApplicationWindow whose titlebar is a GtkHeaderBar: title widget - a label packed start - a "New" button (connected with GtkClosures.Connect2) packed end - a GtkMenuButton with an application menu (Bold toggle, Quit) plus the Ctrl+N / Ctrl+B / Ctrl+Q accelerators. Build: make examples Run: ./build/examples/headerbar *) FROM Gio IMPORT g_application_run, g_application_quit; FROM GtkApplication IMPORT gtk_application_new; FROM GtkApplicationWindow IMPORT gtk_application_window_new; FROM GtkWindow IMPORT gtk_window_set_title, gtk_window_set_default_size, gtk_window_set_titlebar, gtk_window_set_child, gtk_window_present; FROM GtkHeaderBar IMPORT gtk_header_bar_new, gtk_header_bar_set_title_widget, gtk_header_bar_pack_start, gtk_header_bar_pack_end; FROM GtkMenuButton IMPORT gtk_menu_button_new, gtk_menu_button_set_menu_model, gtk_menu_button_set_icon_name; FROM GtkLabel IMPORT gtk_label_new, gtk_label_set_text; FROM GtkButton IMPORT gtk_button_new_with_label; FROM GSimpleAction IMPORT g_simple_action_new, g_simple_action_new_stateful; FROM GActionMap IMPORT g_action_map_add_action; FROM GMenu IMPORT g_menu_new, g_menu_append; FROM GVariant IMPORT g_variant_new_boolean, g_variant_get_boolean; FROM GtkUtils IMPORT Connect, SetAccel; FROM GtkClosures IMPORT Connect2; FROM SYSTEM IMPORT ADDRESS, ADR; FROM libc IMPORT printf; CONST AppId = "org.example.m2gtk4.HeaderBar"; VAR app, status: ADDRESS; PROCEDURE OnQuit (action: ADDRESS; param: ADDRESS; data: ADDRESS); BEGIN g_application_quit(app) END OnQuit; (* GtkClosures.Handler2: void handler(instance, user_data) *) PROCEDURE OnNew (instance: ADDRESS; user: ADDRESS); BEGIN gtk_label_set_text(status, "New selected") END OnNew; PROCEDURE OnBold (action: ADDRESS; param: ADDRESS; data: ADDRESS); BEGIN IF g_variant_get_boolean(param) # 0 THEN gtk_label_set_text(status, "Bold on") ELSE gtk_label_set_text(status, "Bold off") END END OnBold; PROCEDURE OnActivate (application: ADDRESS; data: ADDRESS); VAR window, header, newButton, menuButton, menu, action, title: ADDRESS; BEGIN (* app-scoped action: quit *) action := g_simple_action_new("quit", NIL); Connect(action, "activate", ADR(OnQuit), NIL); g_action_map_add_action(application, action); window := gtk_application_window_new(application); (* window-scoped stateful action: bold *) action := g_simple_action_new_stateful("bold", NIL, g_variant_new_boolean(0)); Connect(action, "change-state", ADR(OnBold), NIL); g_action_map_add_action(window, action); (* header bar: title, start button, end-packed menu button *) title := gtk_label_new("m2-GTK4 Header Bar"); header := gtk_header_bar_new(); gtk_header_bar_set_title_widget(header, title); newButton := gtk_button_new_with_label("New"); Connect2(newButton, "clicked", OnNew, NIL); gtk_header_bar_pack_start(header, newButton); menu := g_menu_new(); g_menu_append(menu, "Bold", "win.bold"); g_menu_append(menu, "Quit", "app.quit"); menuButton := gtk_menu_button_new(); gtk_menu_button_set_icon_name(menuButton, "open-menu-symbolic"); gtk_menu_button_set_menu_model(menuButton, menu); gtk_header_bar_pack_end(header, menuButton); status := gtk_label_new("Ready"); SetAccel(application, "app.quit", "q"); SetAccel(application, "win.bold", "b"); gtk_window_set_title(window, "m2-GTK4 Header Bar"); gtk_window_set_default_size(window, 420, 220); gtk_window_set_titlebar(window, header); gtk_window_set_child(window, status); gtk_window_present(window) END OnActivate; VAR rc: INTEGER; BEGIN app := gtk_application_new(AppId, 0); IF app = NIL THEN printf("gtk_application_new failed\n"); HALT(1) END; Connect(app, "activate", ADR(OnActivate), NIL); rc := g_application_run(app, 0, NIL) END headerbar.