diff --git a/.vscode/settings.json b/.vscode/settings.json index b943dbc..cbac569 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "deno.enable": true -} \ No newline at end of file + "deno.enable": true +} diff --git a/README.md b/README.md index cfbcc8b..ecb71f2 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,20 @@ -> **Note** -> This library provides [Deno](https://deno.com/) bindings to [libadwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/) and [GTK4](https://www.gtk.org/docs/) using Deno's [Foreign Function Interface (FFI)](https://docs.deno.com/runtime/fundamentals/ffi/). It enables building native GNOME-style UIs in TypeScript. +> **Note** This library provides [Deno](https://deno.com/) bindings to +> [libadwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/) and +> [GTK4](https://www.gtk.org/docs/) using Deno's +> [Foreign Function Interface (FFI)](https://docs.deno.com/runtime/fundamentals/ffi/). +> It enables building native GNOME-style UIs in TypeScript. ## About -- Uses FFI to call native libraries from TypeScript, allowing most UI work to be handled by libadwaita/GTK4. -- Business logic and application code remain in TypeScript, while rendering and system integration are managed natively. -- Suitable for developers who want to create desktop applications with a GNOME look and feel, without writing C or Rust. +- Uses FFI to call native libraries from TypeScript, allowing most UI work to be + handled by libadwaita/GTK4. +- Business logic and application code remain in TypeScript, while rendering and + system integration are managed natively. +- Suitable for developers who want to create desktop applications with a GNOME + look and feel, without writing C or Rust. ### References diff --git a/adw.ts b/adw.ts index e596ab2..ee709be 100644 --- a/adw.ts +++ b/adw.ts @@ -1,1063 +1,1271 @@ import { AnyGValue, DefaultHandler, GCallback } from "./gobj.ts"; -import { gtk4, GtkAdjustment, GtkApplication, GtkApplicationWindow, GtkLayoutManager, GtkPaintable, GtkWidget } from "./gtk4.ts"; +import { + gtk4, + GtkAdjustment, + GtkApplication, + GtkApplicationWindow, + GtkLayoutManager, + GtkPaintable, + GtkWidget, +} from "./gtk4.ts"; import { gio } from "./libs.ts"; -import { cString } from "./utils.ts"; - -export const adwaita = Deno.dlopen("/opt/homebrew/lib/libadwaita-1.dylib", { +import { cString, os } from "./utils.ts"; + +export const adwaita = Deno.dlopen( + { + darwin: "libadwaita-1.dylib", + linux: "libadwaita-1.so", + }[os], + { adw_init: { - parameters: [], - result: "void" // no return value + parameters: [], + result: "void", // no return value }, adw_get_major_version: { - parameters: [], - result: "u32" // returns the major version of Adwaita + parameters: [], + result: "u32", // returns the major version of Adwaita }, adw_get_minor_version: { - parameters: [], - result: "u32" // returns the minor version of Adwaita + parameters: [], + result: "u32", // returns the minor version of Adwaita }, adw_get_micro_version: { - parameters: [], - result: "u32" // returns the micro version of Adwaita + parameters: [], + result: "u32", // returns the micro version of Adwaita }, adw_application_new: { - parameters: [ - "buffer", - "u32" - ], - result: "pointer" // instance of AdwApplication + parameters: ["buffer", "u32"], + result: "pointer", // instance of AdwApplication }, adw_application_window_new: { - parameters: [ - "pointer" // instance pointer of GtkApplication - ], - result: "pointer" // returns a pointer to a new AdwApplicationWindow + parameters: [ + "pointer", // instance pointer of GtkApplication + ], + result: "pointer", // returns a pointer to a new AdwApplicationWindow }, adw_application_window_set_content: { - parameters: [ - "pointer", // instance pointer of AdwApplicationWindow - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer of AdwApplicationWindow + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_preferences_page_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwPreferencesPage + parameters: [], + result: "pointer", // returns a pointer to a new AdwPreferencesPage }, adw_preferences_page_add: { - parameters: [ - "pointer", // instance pointer of AdwPreferencesPage - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer of AdwPreferencesPage + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_preferences_page_remove: { - parameters: [ - "pointer", // instance pointer of AdwPreferencesPage - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer of AdwPreferencesPage + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_preferences_page_scroll_to_top: { - parameters: [ - "pointer" // instance pointer of AdwPreferencesPage - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer of AdwPreferencesPage + ], + result: "void", // no return value }, adw_preferences_page_set_banner: { - parameters: [ - "pointer", // instance pointer of AdwPreferencesPage - "pointer" // banner widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer of AdwPreferencesPage + "pointer", // banner widget pointer + ], + result: "void", // no return value }, adw_preferences_group_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwPreferencesGroup + parameters: [], + result: "pointer", // returns a pointer to a new AdwPreferencesGroup }, adw_preferences_group_add: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_preferences_group_remove: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_preferences_group_set_header_suffix: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_preferences_row_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwPreferencesRow + parameters: [], + result: "pointer", // returns a pointer to a new AdwPreferencesRow }, adw_action_row_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwActionRow + parameters: [], + result: "pointer", // returns a pointer to a new AdwActionRow }, adw_action_row_add_prefix: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_action_row_add_suffix: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_action_row_remove: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_button_row_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwButtonRow + parameters: [], + result: "pointer", // returns a pointer to a new AdwButtonRow }, adw_clamp_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwClamp + parameters: [], + result: "pointer", // returns a pointer to a new AdwClamp }, adw_clamp_set_child: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_switch_row_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwSwitchRow + parameters: [], + result: "pointer", // returns a pointer to a new AdwSwitchRow }, adw_switch_row_set_active: { - parameters: [ - "pointer", // instance pointer - "bool" // active state - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "bool", // active state + ], + result: "void", // no return value }, adw_switch_row_get_active: { - parameters: [ - "pointer" // instance pointer - ], - result: "bool" // returns the active state + parameters: [ + "pointer", // instance pointer + ], + result: "bool", // returns the active state }, adw_expander_row_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwExpanderRow + parameters: [], + result: "pointer", // returns a pointer to a new AdwExpanderRow }, adw_expander_row_add_suffix: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_expander_row_add_prefix: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_expander_row_remove: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_expander_row_add_row: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_toolbar_view_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwToolbarView + parameters: [], + result: "pointer", // returns a pointer to a new AdwToolbarView }, adw_toolbar_view_add_top_bar: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_toolbar_view_add_bottom_bar: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_toolbar_view_set_content: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_header_bar_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwHeaderBar + parameters: [], + result: "pointer", // returns a pointer to a new AdwHeaderBar }, adw_combo_row_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwComboRow + parameters: [], + result: "pointer", // returns a pointer to a new AdwComboRow }, adw_combo_row_get_selected: { - parameters: [ - "pointer" // instance pointer - ], - result: "u32" // returns the selected index + parameters: [ + "pointer", // instance pointer + ], + result: "u32", // returns the selected index }, adw_combo_row_set_selected: { - parameters: [ - "pointer", // instance pointer - "u32" // selected index - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "u32", // selected index + ], + result: "void", // no return value }, adw_entry_row_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwEntryRow + parameters: [], + result: "pointer", // returns a pointer to a new AdwEntryRow }, adw_password_entry_row_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwPasswordEntryRow + parameters: [], + result: "pointer", // returns a pointer to a new AdwPasswordEntryRow }, adw_spin_row_new: { - parameters: [ - "pointer", // gtk adjustment pointer - "f64", - "i32", // minimum value - ], - result: "pointer" // returns a pointer to a new AdwSpinRow + parameters: [ + "pointer", // gtk adjustment pointer + "f64", + "i32", // minimum value + ], + result: "pointer", // returns a pointer to a new AdwSpinRow }, adw_spin_row_new_with_range: { - parameters: [ - "f64", // minimum value - "f64", // maximum value - "f64", // step increment - ], - result: "pointer" // returns a pointer to a new AdwSpinRow + parameters: [ + "f64", // minimum value + "f64", // maximum value + "f64", // step increment + ], + result: "pointer", // returns a pointer to a new AdwSpinRow }, adw_spin_row_get_value: { - parameters: [ - "pointer" // instance pointer - ], - result: "f64" // returns the current value of the spin row + parameters: [ + "pointer", // instance pointer + ], + result: "f64", // returns the current value of the spin row }, adw_dialog_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwDialog + parameters: [], + result: "pointer", // returns a pointer to a new AdwDialog }, adw_dialog_close: { - parameters: [ - "pointer" // instance pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + ], + result: "void", // no return value }, adw_dialog_set_child: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_dialog_present: { - parameters: [ - "pointer", // instance pointer - "pointer" // parent window pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // parent window pointer + ], + result: "void", // no return value }, adw_preferences_dialog_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwPreferencesDialog + parameters: [], + result: "pointer", // returns a pointer to a new AdwPreferencesDialog }, adw_preferences_dialog_add: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_preferences_dialog_remove: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_preferences_dialog_push_subpage: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_preferences_dialog_pop_subpage: { - parameters: [ - "pointer" // instance pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + ], + result: "void", // no return value }, adw_toggle_group_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwToggleGroup + parameters: [], + result: "pointer", // returns a pointer to a new AdwToggleGroup }, adw_toggle_group_add: { - parameters: [ - "pointer", // instance pointer - "pointer" // toggle pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // toggle pointer + ], + result: "void", // no return value }, adw_toggle_group_remove: { - parameters: [ - "pointer", // instance pointer - "pointer" // toggle pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // toggle pointer + ], + result: "void", // no return value }, adw_toggle_group_remove_all: { - parameters: [ - "pointer" // instance pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + ], + result: "void", // no return value }, adw_toggle_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwToggle + parameters: [], + result: "pointer", // returns a pointer to a new AdwToggle }, adw_status_page_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwStatusPage + parameters: [], + result: "pointer", // returns a pointer to a new AdwStatusPage }, adw_banner_new: { - parameters: [ - "buffer" // title - ], - result: "pointer" // returns a pointer to a new AdwBanner + parameters: [ + "buffer", // title + ], + result: "pointer", // returns a pointer to a new AdwBanner }, adw_spinner_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwSpinner + parameters: [], + result: "pointer", // returns a pointer to a new AdwSpinner }, adw_avatar_new: { - parameters: [ - // int size - "i32", // size of the avatar - "buffer", // text - "bool" // show initials - ], - result: "pointer" // returns a pointer to a new AdwAvatar + parameters: [ + // int size + "i32", // size of the avatar + "buffer", // text + "bool", // show initials + ], + result: "pointer", // returns a pointer to a new AdwAvatar }, adw_avatar_set_custom_image: { - parameters: [ - "pointer", // instance pointer - "pointer" // GdkPaintable pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // GdkPaintable pointer + ], + result: "void", // no return value }, adw_alert_dialog_new: { - parameters: [ - "buffer", // title - "buffer" // body text - ], - result: "pointer" // returns a pointer to a new AdwAlertDialog + parameters: [ + "buffer", // title + "buffer", // body text + ], + result: "pointer", // returns a pointer to a new AdwAlertDialog }, adw_alert_dialog_add_response: { - parameters: [ - "pointer", // instance pointer - "buffer", // response label - "buffer" // response id - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // response label + "buffer", // response id + ], + result: "void", // no return value }, adw_alert_dialog_set_response_appearance: { - parameters: [ - "pointer", // instance pointer - "buffer", // response id - "i32" // appearance type - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // response id + "i32", // appearance type + ], + result: "void", // no return value }, adw_alert_dialog_set_default_response: { - parameters: [ - "pointer", // instance pointer - "buffer" // response id - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // response id + ], + result: "void", // no return value }, adw_alert_dialog_set_close_response: { - parameters: [ - "pointer", // instance pointer - "buffer" // response id - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // response id + ], + result: "void", // no return value }, adw_wrap_box_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwWrapBox + parameters: [], + result: "pointer", // returns a pointer to a new AdwWrapBox }, adw_wrap_box_append: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_wrap_layout_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwWrapLayout + parameters: [], + result: "pointer", // returns a pointer to a new AdwWrapLayout }, adw_bin_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwBin + parameters: [], + result: "pointer", // returns a pointer to a new AdwBin }, adw_bin_set_child: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_breakpoint_bin_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwBreakpointBin + parameters: [], + result: "pointer", // returns a pointer to a new AdwBreakpointBin }, adw_breakpoint_bin_set_child: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, adw_breakpoint_bin_add_breakpoint: { - parameters: [ - "pointer", // instance pointer - "i32" // breakpoint value - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "i32", // breakpoint value + ], + result: "void", // no return value }, adw_navigation_view_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwNavigationView + parameters: [], + result: "pointer", // returns a pointer to a new AdwNavigationView }, adw_navigation_view_add: { - parameters: [ - "pointer", // instance pointer - "pointer" // page pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // page pointer + ], + result: "void", // no return value }, adw_navigation_view_push: { - parameters: [ - "pointer", // instance pointer - "pointer" // page pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // page pointer + ], + result: "void", // no return value }, adw_navigation_view_pop: { - parameters: [ - "pointer" // instance pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + ], + result: "void", // no return value }, adw_navigation_view_remove: { - parameters: [ - "pointer", // instance pointer - "pointer" // page pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // page pointer + ], + result: "void", // no return value }, adw_navigation_view_push_by_tag: { - parameters: [ - "pointer", // instance pointer - "buffer" // tag - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // tag + ], + result: "void", // no return value }, adw_navigation_page_new: { - parameters: [ - "pointer", // child - "buffer" // title - ], - result: "pointer" // returns a pointer to a new AdwNavigationPage + parameters: [ + "pointer", // child + "buffer", // title + ], + result: "pointer", // returns a pointer to a new AdwNavigationPage }, adw_navigation_page_new_with_tag: { - parameters: [ - "pointer", // child - "buffer", // title - "buffer" // tag - ], - result: "pointer" // returns a pointer to a new AdwNavigationPage with a tag + parameters: [ + "pointer", // child + "buffer", // title + "buffer", // tag + ], + result: "pointer", // returns a pointer to a new AdwNavigationPage with a tag }, adw_navigation_split_view_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwNavigationSplitView + parameters: [], + result: "pointer", // returns a pointer to a new AdwNavigationSplitView }, adw_navigation_split_view_set_content: { - parameters: [ - "pointer", // instance pointer - "pointer" // content widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // content widget pointer + ], + result: "void", // no return value }, adw_navigation_split_view_set_sidebar: { - parameters: [ - "pointer", // instance pointer - "pointer" // sidebar widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // sidebar widget pointer + ], + result: "void", // no return value }, adw_overlay_split_view_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwOverlaySplitView + parameters: [], + result: "pointer", // returns a pointer to a new AdwOverlaySplitView }, adw_overlay_split_view_set_sidebar: { - parameters: [ - "pointer", // instance pointer - "pointer" // sidebar widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // sidebar widget pointer + ], + result: "void", // no return value }, adw_overlay_split_view_set_content: { - parameters: [ - "pointer", // instance pointer - "pointer" // content widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // content widget pointer + ], + result: "void", // no return value }, adw_view_switcher_new: { - parameters: [], - result: "pointer" // returns a pointer to a new AdwViewSwitcher - } -}); + parameters: [], + result: "pointer", // returns a pointer to a new AdwViewSwitcher + }, + }, +); -console.log("Adwaita version:", `${adwaita.symbols.adw_get_major_version()}.` + adwaita.symbols.adw_get_minor_version() + "." + adwaita.symbols.adw_get_micro_version()); +console.log( + "Adwaita version:", + `${adwaita.symbols.adw_get_major_version()}.` + + adwaita.symbols.adw_get_minor_version() + + "." + + adwaita.symbols.adw_get_micro_version(), +); const GApplicationFlags = { - FLAGS_NONE: 0 + FLAGS_NONE: 0, }; export class Application extends GtkApplication { - #activePromise = Promise.withResolvers(); - constructor(applicationId: string, flags: number = GApplicationFlags.FLAGS_NONE) { - super(adwaita.symbols.adw_application_new(cString(applicationId), flags)); - } - - get activated(): Promise { - return this.#activePromise.promise; - } - - signalActivate(callback: (self: this) => void) { - this.connect("activate", new DefaultHandler(() => { - try { - callback(this); - } catch (error) { - console.error("Error during activation:", error); - Deno.exit(1); - } - })); - return this; - } - - run() { - gio.symbols.g_application_run(this.internalPointer, 0, null); - } + #activePromise = Promise.withResolvers(); + constructor( + applicationId: string, + flags: number = GApplicationFlags.FLAGS_NONE, + ) { + super(adwaita.symbols.adw_application_new(cString(applicationId), flags)); + } + + get activated(): Promise { + return this.#activePromise.promise; + } + + signalActivate(callback: (self: this) => void) { + this.connect( + "activate", + new DefaultHandler(() => { + try { + callback(this); + } catch (error) { + console.error("Error during activation:", error); + Deno.exit(1); + } + }), + ); + return this; + } + + run() { + gio.symbols.g_application_run(this.internalPointer, 0, null); + } } export class ApplicationWindow extends GtkApplicationWindow { - protected constructor(internalPointer: Deno.PointerValue) { - super(internalPointer); - } - - static override create(application: GtkApplication) { - return new ApplicationWindow(adwaita.symbols.adw_application_window_new(application.internalPointer)); - } - - override setChild(child: GtkWidget) { - adwaita.symbols.adw_application_window_set_content(this.internalPointer, child.internalPointer); - return this; - } + protected constructor(internalPointer: Deno.PointerValue) { + super(internalPointer); + } + + static override create(application: GtkApplication) { + return new ApplicationWindow( + adwaita.symbols.adw_application_window_new(application.internalPointer), + ); + } + + override setChild(child: GtkWidget) { + adwaita.symbols.adw_application_window_set_content( + this.internalPointer, + child.internalPointer, + ); + return this; + } } export class ToolbarView extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_toolbar_view_new()) { - super(internalPointer); - } - - addTopBar(child: HeaderBar): this; - addTopBar(child: GtkWidget) { - adwaita.symbols.adw_toolbar_view_add_top_bar(this.internalPointer, child.internalPointer); - return this; - } - - addBottomBar(child: GtkWidget) { - adwaita.symbols.adw_toolbar_view_add_bottom_bar(this.internalPointer, child.internalPointer); - return this; - } - - setContent(child: GtkWidget) { - adwaita.symbols.adw_toolbar_view_set_content(this.internalPointer, child.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_toolbar_view_new(), + ) { + super(internalPointer); + } + + addTopBar(child: HeaderBar): this; + addTopBar(child: GtkWidget) { + adwaita.symbols.adw_toolbar_view_add_top_bar( + this.internalPointer, + child.internalPointer, + ); + return this; + } + + addBottomBar(child: GtkWidget) { + adwaita.symbols.adw_toolbar_view_add_bottom_bar( + this.internalPointer, + child.internalPointer, + ); + return this; + } + + setContent(child: GtkWidget) { + adwaita.symbols.adw_toolbar_view_set_content( + this.internalPointer, + child.internalPointer, + ); + return this; + } } export class HeaderBar extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_header_bar_new()) { - super(internalPointer); - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_header_bar_new(), + ) { + super(internalPointer); + } } export class Clamp extends GtkWidget { - constructor() { - super(adwaita.symbols.adw_clamp_new()); - } - - setChild(child: GtkWidget) { - adwaita.symbols.adw_clamp_set_child(this.internalPointer, child.internalPointer); - return this; - } + constructor() { + super(adwaita.symbols.adw_clamp_new()); + } + + setChild(child: GtkWidget) { + adwaita.symbols.adw_clamp_set_child( + this.internalPointer, + child.internalPointer, + ); + return this; + } } export class PreferencesPage extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_preferences_page_new()) { - super(internalPointer); - } - - add(child: PreferencesGroup) { - adwaita.symbols.adw_preferences_page_add(this.internalPointer, child.internalPointer); - return this; - } - - remove(child: PreferencesGroup) { - adwaita.symbols.adw_preferences_page_remove(this.internalPointer, child.internalPointer); - return this; - } - - scrollToTop() { - adwaita.symbols.adw_preferences_page_scroll_to_top(this.internalPointer); - return this; - } - - setBanner(banner: Banner) { - adwaita.symbols.adw_preferences_page_set_banner(this.internalPointer, banner.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols + .adw_preferences_page_new(), + ) { + super(internalPointer); + } + + add(child: PreferencesGroup) { + adwaita.symbols.adw_preferences_page_add( + this.internalPointer, + child.internalPointer, + ); + return this; + } + + remove(child: PreferencesGroup) { + adwaita.symbols.adw_preferences_page_remove( + this.internalPointer, + child.internalPointer, + ); + return this; + } + + scrollToTop() { + adwaita.symbols.adw_preferences_page_scroll_to_top(this.internalPointer); + return this; + } + + setBanner(banner: Banner) { + adwaita.symbols.adw_preferences_page_set_banner( + this.internalPointer, + banner.internalPointer, + ); + return this; + } } export class PreferencesGroup extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_preferences_group_new()) { - super(internalPointer); - } - - add(child: GtkWidget) { - adwaita.symbols.adw_preferences_group_add(this.internalPointer, child.internalPointer); - return this; - } - - remove(child: GtkWidget) { - adwaita.symbols.adw_preferences_group_remove(this.internalPointer, child.internalPointer); - return this; - } - - setHeaderSuffix(child: GtkWidget) { - adwaita.symbols.adw_preferences_group_set_header_suffix(this.internalPointer, child.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols + .adw_preferences_group_new(), + ) { + super(internalPointer); + } + + add(child: GtkWidget) { + adwaita.symbols.adw_preferences_group_add( + this.internalPointer, + child.internalPointer, + ); + return this; + } + + remove(child: GtkWidget) { + adwaita.symbols.adw_preferences_group_remove( + this.internalPointer, + child.internalPointer, + ); + return this; + } + + setHeaderSuffix(child: GtkWidget) { + adwaita.symbols.adw_preferences_group_set_header_suffix( + this.internalPointer, + child.internalPointer, + ); + return this; + } } export class PreferencesRow extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_preferences_row_new()) { - super(internalPointer); - } - - override setProperty(propertyName: string, value: AnyGValue): this { - super.setProperty(propertyName, value); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols + .adw_preferences_row_new(), + ) { + super(internalPointer); + } + + override setProperty(propertyName: string, value: AnyGValue): this { + super.setProperty(propertyName, value); + return this; + } } export class ActionRow extends PreferencesRow { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_action_row_new()) { - super(internalPointer); - } - - signalActivate(callback: (self: this) => void) { - this.connect("activate", new DefaultHandler(() => callback(this))); - return this; - } - - addSuffix(child: GtkWidget) { - adwaita.symbols.adw_action_row_add_suffix(this.internalPointer, child.internalPointer); - return this; - } - - addPrefix(child: GtkWidget) { - adwaita.symbols.adw_action_row_add_prefix(this.internalPointer, child.internalPointer); - return this; - } - - remove(child: GtkWidget) { - adwaita.symbols.adw_action_row_remove(this.internalPointer, child.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_action_row_new(), + ) { + super(internalPointer); + } + + signalActivate(callback: (self: this) => void) { + this.connect("activate", new DefaultHandler(() => callback(this))); + return this; + } + + addSuffix(child: GtkWidget) { + adwaita.symbols.adw_action_row_add_suffix( + this.internalPointer, + child.internalPointer, + ); + return this; + } + + addPrefix(child: GtkWidget) { + adwaita.symbols.adw_action_row_add_prefix( + this.internalPointer, + child.internalPointer, + ); + return this; + } + + remove(child: GtkWidget) { + adwaita.symbols.adw_action_row_remove( + this.internalPointer, + child.internalPointer, + ); + return this; + } } export class ButtonRow extends PreferencesRow { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_button_row_new()) { - super(internalPointer); - } - - signalActivated(callback: (self: this) => void) { - this.connect("activated", new DefaultHandler(() => callback(this))); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_button_row_new(), + ) { + super(internalPointer); + } + + signalActivated(callback: (self: this) => void) { + this.connect("activated", new DefaultHandler(() => callback(this))); + return this; + } } export class SwitchRow extends ActionRow { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_switch_row_new()) { - super(internalPointer); - } - - set active(active: boolean) { - adwaita.symbols.adw_switch_row_set_active(this.internalPointer, active); - } - - get active(): boolean { - return adwaita.symbols.adw_switch_row_get_active(this.internalPointer); - } - - onActive(callback: (self: this) => void) { - this.connect("notify::active", new DefaultHandler(() => callback(this))); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_switch_row_new(), + ) { + super(internalPointer); + } + + set active(active: boolean) { + adwaita.symbols.adw_switch_row_set_active(this.internalPointer, active); + } + + get active(): boolean { + return adwaita.symbols.adw_switch_row_get_active(this.internalPointer); + } + + onActive(callback: (self: this) => void) { + this.connect("notify::active", new DefaultHandler(() => callback(this))); + return this; + } } export class ComboRow extends ActionRow { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_combo_row_new()) { - super(internalPointer); - } - - get selected(): number { - return adwaita.symbols.adw_combo_row_get_selected(this.internalPointer); - } - - set selected(index: number) { - adwaita.symbols.adw_combo_row_set_selected(this.internalPointer, index); - } - - onSelected(callback: (self: this) => void) { - this.connect("notify::selected", new DefaultHandler(() => callback(this))); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_combo_row_new(), + ) { + super(internalPointer); + } + + get selected(): number { + return adwaita.symbols.adw_combo_row_get_selected(this.internalPointer); + } + + set selected(index: number) { + adwaita.symbols.adw_combo_row_set_selected(this.internalPointer, index); + } + + onSelected(callback: (self: this) => void) { + this.connect("notify::selected", new DefaultHandler(() => callback(this))); + return this; + } } export class ExpanderRow extends PreferencesRow { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_expander_row_new()) { - super(internalPointer); - } - - addSuffix(child: GtkWidget) { - adwaita.symbols.adw_expander_row_add_suffix(this.internalPointer, child.internalPointer); - return this; - } - addPrefix(child: GtkWidget) { - adwaita.symbols.adw_expander_row_add_prefix(this.internalPointer, child.internalPointer); - return this; - } - remove(child: GtkWidget) { - adwaita.symbols.adw_expander_row_remove(this.internalPointer, child.internalPointer); - return this; - } - addRow(child: GtkWidget) { - adwaita.symbols.adw_expander_row_add_row(this.internalPointer, child.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_expander_row_new(), + ) { + super(internalPointer); + } + + addSuffix(child: GtkWidget) { + adwaita.symbols.adw_expander_row_add_suffix( + this.internalPointer, + child.internalPointer, + ); + return this; + } + addPrefix(child: GtkWidget) { + adwaita.symbols.adw_expander_row_add_prefix( + this.internalPointer, + child.internalPointer, + ); + return this; + } + remove(child: GtkWidget) { + adwaita.symbols.adw_expander_row_remove( + this.internalPointer, + child.internalPointer, + ); + return this; + } + addRow(child: GtkWidget) { + adwaita.symbols.adw_expander_row_add_row( + this.internalPointer, + child.internalPointer, + ); + return this; + } } export class EntryRow extends PreferencesRow { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_entry_row_new()) { - super(internalPointer); - } - - signalActivated(callback: (self: this) => void) { - this.connect("activated", new DefaultHandler(() => callback(this))); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_entry_row_new(), + ) { + super(internalPointer); + } + + signalActivated(callback: (self: this) => void) { + this.connect("activated", new DefaultHandler(() => callback(this))); + return this; + } } export class PasswordEntryRow extends EntryRow { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_password_entry_row_new()) { - super(internalPointer); - gtk4.symbols.gtk_widget_init_template(this.internalPointer); - - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols + .adw_password_entry_row_new(), + ) { + super(internalPointer); + gtk4.symbols.gtk_widget_init_template(this.internalPointer); + } } export class SpinRow extends ActionRow { - constructor(options: { adjustment: GtkAdjustment, climbRate: number, digits: number; } | { min: number, max: number, step: number; }) { - super( - 'adjustment' in options - ? adwaita.symbols.adw_spin_row_new(options.adjustment.internalPointer, options.climbRate, options.digits) - : adwaita.symbols.adw_spin_row_new_with_range(options.min, options.max, options.step) - ); - } - - set value(value: number) { - this.setProperty("value", value); - } - - get value(): number { - return adwaita.symbols.adw_spin_row_get_value(this.internalPointer); - } - - onValue(callback: (self: this) => void) { - this.connect("notify::value", new DefaultHandler(() => callback(this))); - return this; - } + constructor( + options: + | { adjustment: GtkAdjustment; climbRate: number; digits: number } + | { min: number; max: number; step: number }, + ) { + super( + "adjustment" in options + ? adwaita.symbols.adw_spin_row_new( + options.adjustment.internalPointer, + options.climbRate, + options.digits, + ) + : adwaita.symbols.adw_spin_row_new_with_range( + options.min, + options.max, + options.step, + ), + ); + } + + set value(value: number) { + this.setProperty("value", value); + } + + get value(): number { + return adwaita.symbols.adw_spin_row_get_value(this.internalPointer); + } + + onValue(callback: (self: this) => void) { + this.connect("notify::value", new DefaultHandler(() => callback(this))); + return this; + } } export class Dialog extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_dialog_new()) { - super(internalPointer); - } - - close() { - adwaita.symbols.adw_dialog_close(this.internalPointer); - return this; - } - - setChild(child: GtkWidget) { - adwaita.symbols.adw_dialog_set_child(this.internalPointer, child.internalPointer); - return this; - } - - present(parent?: GtkWidget) { - adwaita.symbols.adw_dialog_present(this.internalPointer, parent ? parent.internalPointer : null); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_dialog_new(), + ) { + super(internalPointer); + } + + close() { + adwaita.symbols.adw_dialog_close(this.internalPointer); + return this; + } + + setChild(child: GtkWidget) { + adwaita.symbols.adw_dialog_set_child( + this.internalPointer, + child.internalPointer, + ); + return this; + } + + present(parent?: GtkWidget) { + adwaita.symbols.adw_dialog_present( + this.internalPointer, + parent ? parent.internalPointer : null, + ); + return this; + } } export class PreferencesDialog extends Dialog { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_preferences_dialog_new()) { - super(internalPointer); - } - - add(page: PreferencesPage) { - adwaita.symbols.adw_preferences_dialog_add(this.internalPointer, page.internalPointer); - return this; - } - - remove(page: PreferencesPage) { - adwaita.symbols.adw_preferences_dialog_remove(this.internalPointer, page.internalPointer); - return this; - } - - pushSubpage(page: PreferencesPage) { - adwaita.symbols.adw_preferences_dialog_push_subpage(this.internalPointer, page.internalPointer); - return this; - } - - popSubpage() { - adwaita.symbols.adw_preferences_dialog_pop_subpage(this.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols + .adw_preferences_dialog_new(), + ) { + super(internalPointer); + } + + add(page: PreferencesPage) { + adwaita.symbols.adw_preferences_dialog_add( + this.internalPointer, + page.internalPointer, + ); + return this; + } + + remove(page: PreferencesPage) { + adwaita.symbols.adw_preferences_dialog_remove( + this.internalPointer, + page.internalPointer, + ); + return this; + } + + pushSubpage(page: PreferencesPage) { + adwaita.symbols.adw_preferences_dialog_push_subpage( + this.internalPointer, + page.internalPointer, + ); + return this; + } + + popSubpage() { + adwaita.symbols.adw_preferences_dialog_pop_subpage(this.internalPointer); + return this; + } } export class Toggle extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_toggle_new()) { - super(internalPointer); - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_toggle_new(), + ) { + super(internalPointer); + } } export class ToggleGroup extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_toggle_group_new()) { - super(internalPointer); - } - - add(toggle: Toggle) { - adwaita.symbols.adw_toggle_group_add(this.internalPointer, toggle.internalPointer); - return this; - } - - remove(toggle: Toggle) { - adwaita.symbols.adw_toggle_group_remove(this.internalPointer, toggle.internalPointer); - return this; - } - - removeAll() { - adwaita.symbols.adw_toggle_group_remove_all(this.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_toggle_group_new(), + ) { + super(internalPointer); + } + + add(toggle: Toggle) { + adwaita.symbols.adw_toggle_group_add( + this.internalPointer, + toggle.internalPointer, + ); + return this; + } + + remove(toggle: Toggle) { + adwaita.symbols.adw_toggle_group_remove( + this.internalPointer, + toggle.internalPointer, + ); + return this; + } + + removeAll() { + adwaita.symbols.adw_toggle_group_remove_all(this.internalPointer); + return this; + } } export class StatusPage extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_status_page_new()) { - super(internalPointer); - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_status_page_new(), + ) { + super(internalPointer); + } } export class Banner extends GtkWidget { - constructor(title: string, internalPointer: Deno.PointerValue = adwaita.symbols.adw_banner_new(cString(title))) { - super(internalPointer); - } - - onButtonClicked(callback: (self: this) => void) { - this.connect("button-clicked", new DefaultHandler(() => callback(this))); - return this; - } + constructor( + title: string, + internalPointer: Deno.PointerValue = adwaita.symbols.adw_banner_new( + cString(title), + ), + ) { + super(internalPointer); + } + + onButtonClicked(callback: (self: this) => void) { + this.connect("button-clicked", new DefaultHandler(() => callback(this))); + return this; + } } export class Spinner extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_spinner_new()) { - super(internalPointer); - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_spinner_new(), + ) { + super(internalPointer); + } } export class Avatar extends GtkWidget { - constructor(size: number, text: string, showInitials: boolean = true, internalPointer: Deno.PointerValue = adwaita.symbols.adw_avatar_new(size, cString(text), showInitials)) { - super(internalPointer); - } - - setCustomImage(paintable: GtkPaintable) { - adwaita.symbols.adw_avatar_set_custom_image(this.internalPointer, paintable.internalPointer); - return this; - } -}; + constructor( + size: number, + text: string, + showInitials: boolean = true, + internalPointer: Deno.PointerValue = adwaita.symbols.adw_avatar_new( + size, + cString(text), + showInitials, + ), + ) { + super(internalPointer); + } + + setCustomImage(paintable: GtkPaintable) { + adwaita.symbols.adw_avatar_set_custom_image( + this.internalPointer, + paintable.internalPointer, + ); + return this; + } +} export enum ResponseAppearance { - DEFAULT = 0, - SUGGESTED = 1, - DESTRUCTIVE = 2, + DEFAULT = 0, + SUGGESTED = 1, + DESTRUCTIVE = 2, } export interface Response { - id: string; - label: string; - appearance?: ResponseAppearance; - isCloseAction?: boolean; - isDefaultAction?: boolean; + id: string; + label: string; + appearance?: ResponseAppearance; + isCloseAction?: boolean; + isDefaultAction?: boolean; } export class AlertDialog extends Dialog { - #responses = new Map(); - constructor(title?: string, bodyText?: string, internalPointer: Deno.PointerValue = adwaita.symbols.adw_alert_dialog_new(title ? cString(title) : null, bodyText ? cString(bodyText) : null)) { - super(internalPointer); - } - - addResponse(response: Response) { - if (this.#responses.has(response.id)) { - throw new Error(`Response with id "${response.id}" already exists.`); - } - this.#responses.set(response.id, response); - adwaita.symbols.adw_alert_dialog_add_response(this.internalPointer, cString(response.id), cString(response.label)); - if (response.appearance !== undefined) { - adwaita.symbols.adw_alert_dialog_set_response_appearance(this.internalPointer, cString(response.id), response.appearance); - } - if (response.isDefaultAction) { - adwaita.symbols.adw_alert_dialog_set_default_response(this.internalPointer, cString(response.id)); - } - if (response.isCloseAction) { - adwaita.symbols.adw_alert_dialog_set_close_response(this.internalPointer, cString(response.id)); - } - return this; - } - - onResponse(callback: (responseId: string) => void) { - this.connect("response", new GCallback({ - parameters: [ - "pointer", // instance pointer - "buffer", // response id - "pointer" // user data (not used here) - ], - result: "void", // no return value - }, (_, responseId) => { - if (responseId === null) return; - callback(new Deno.UnsafePointerView(responseId).getCString()); - })); - return this; - } + #responses = new Map(); + constructor( + title?: string, + bodyText?: string, + internalPointer: Deno.PointerValue = adwaita.symbols.adw_alert_dialog_new( + title ? cString(title) : null, + bodyText ? cString(bodyText) : null, + ), + ) { + super(internalPointer); + } + + addResponse(response: Response) { + if (this.#responses.has(response.id)) { + throw new Error(`Response with id "${response.id}" already exists.`); + } + this.#responses.set(response.id, response); + adwaita.symbols.adw_alert_dialog_add_response( + this.internalPointer, + cString(response.id), + cString(response.label), + ); + if (response.appearance !== undefined) { + adwaita.symbols.adw_alert_dialog_set_response_appearance( + this.internalPointer, + cString(response.id), + response.appearance, + ); + } + if (response.isDefaultAction) { + adwaita.symbols.adw_alert_dialog_set_default_response( + this.internalPointer, + cString(response.id), + ); + } + if (response.isCloseAction) { + adwaita.symbols.adw_alert_dialog_set_close_response( + this.internalPointer, + cString(response.id), + ); + } + return this; + } + + onResponse(callback: (responseId: string) => void) { + this.connect( + "response", + new GCallback( + { + parameters: [ + "pointer", // instance pointer + "buffer", // response id + "pointer", // user data (not used here) + ], + result: "void", // no return value + }, + (_, responseId) => { + if (responseId === null) return; + callback(new Deno.UnsafePointerView(responseId).getCString()); + }, + ), + ); + return this; + } } export class WrapLayout extends GtkLayoutManager { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_wrap_layout_new()) { - super(internalPointer); - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_wrap_layout_new(), + ) { + super(internalPointer); + } } export class WrapBox extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_wrap_box_new()) { - super(internalPointer); - } - - append(child: GtkWidget) { - adwaita.symbols.adw_wrap_box_append(this.internalPointer, child.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_wrap_box_new(), + ) { + super(internalPointer); + } + + append(child: GtkWidget) { + adwaita.symbols.adw_wrap_box_append( + this.internalPointer, + child.internalPointer, + ); + return this; + } } export class Bin extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_bin_new()) { - super(internalPointer); - } - - setChild(child: GtkWidget) { - adwaita.symbols.adw_bin_set_child(this.internalPointer, child.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols.adw_bin_new(), + ) { + super(internalPointer); + } + + setChild(child: GtkWidget) { + adwaita.symbols.adw_bin_set_child( + this.internalPointer, + child.internalPointer, + ); + return this; + } } // export class Breakpoint extends GObject // { @@ -1080,76 +1288,126 @@ export class Bin extends GtkWidget { // } export class NavigationView extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_navigation_view_new()) { - super(internalPointer); - } - - add(page: NavigationPage) { - adwaita.symbols.adw_navigation_view_add(this.internalPointer, page.internalPointer); - return this; - } - - push(page: NavigationPage) { - adwaita.symbols.adw_navigation_view_push(this.internalPointer, page.internalPointer); - return this; - } - - pop() { - adwaita.symbols.adw_navigation_view_pop(this.internalPointer); - return this; - } - - remove(page: NavigationPage) { - adwaita.symbols.adw_navigation_view_remove(this.internalPointer, page.internalPointer); - return this; - } - - pushByTag(tag: string) { - adwaita.symbols.adw_navigation_view_push_by_tag(this.internalPointer, cString(tag)); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols + .adw_navigation_view_new(), + ) { + super(internalPointer); + } + + add(page: NavigationPage) { + adwaita.symbols.adw_navigation_view_add( + this.internalPointer, + page.internalPointer, + ); + return this; + } + + push(page: NavigationPage) { + adwaita.symbols.adw_navigation_view_push( + this.internalPointer, + page.internalPointer, + ); + return this; + } + + pop() { + adwaita.symbols.adw_navigation_view_pop(this.internalPointer); + return this; + } + + remove(page: NavigationPage) { + adwaita.symbols.adw_navigation_view_remove( + this.internalPointer, + page.internalPointer, + ); + return this; + } + + pushByTag(tag: string) { + adwaita.symbols.adw_navigation_view_push_by_tag( + this.internalPointer, + cString(tag), + ); + return this; + } } export class NavigationPage extends GtkWidget { - constructor(child: GtkWidget, title: string, tag?: string, internalPointer: Deno.PointerValue = tag ? adwaita.symbols.adw_navigation_page_new_with_tag(child.internalPointer, cString(title), cString(tag)) : adwaita.symbols.adw_navigation_page_new(child.internalPointer, cString(title))) { - super(internalPointer); - } + constructor( + child: GtkWidget, + title: string, + tag?: string, + internalPointer: Deno.PointerValue = tag + ? adwaita.symbols.adw_navigation_page_new_with_tag( + child.internalPointer, + cString(title), + cString(tag), + ) + : adwaita.symbols.adw_navigation_page_new( + child.internalPointer, + cString(title), + ), + ) { + super(internalPointer); + } } export class NavigationSplitView extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_navigation_split_view_new()) { - super(internalPointer); - } - - setContent(content: NavigationPage) { - adwaita.symbols.adw_navigation_split_view_set_content(this.internalPointer, content.internalPointer); - return this; - } - - setSidebar(sidebar: NavigationPage) { - adwaita.symbols.adw_navigation_split_view_set_sidebar(this.internalPointer, sidebar.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols + .adw_navigation_split_view_new(), + ) { + super(internalPointer); + } + + setContent(content: NavigationPage) { + adwaita.symbols.adw_navigation_split_view_set_content( + this.internalPointer, + content.internalPointer, + ); + return this; + } + + setSidebar(sidebar: NavigationPage) { + adwaita.symbols.adw_navigation_split_view_set_sidebar( + this.internalPointer, + sidebar.internalPointer, + ); + return this; + } } export class OverlaySplitView extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_overlay_split_view_new()) { - super(internalPointer); - } - - setSidebar(sidebar: NavigationPage) { - adwaita.symbols.adw_overlay_split_view_set_sidebar(this.internalPointer, sidebar.internalPointer); - return this; - } - - setContent(content: NavigationPage) { - adwaita.symbols.adw_overlay_split_view_set_content(this.internalPointer, content.internalPointer); - return this; - } + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols + .adw_overlay_split_view_new(), + ) { + super(internalPointer); + } + + setSidebar(sidebar: NavigationPage) { + adwaita.symbols.adw_overlay_split_view_set_sidebar( + this.internalPointer, + sidebar.internalPointer, + ); + return this; + } + + setContent(content: NavigationPage) { + adwaita.symbols.adw_overlay_split_view_set_content( + this.internalPointer, + content.internalPointer, + ); + return this; + } } export class ViewSwitcher extends GtkWidget { - constructor(internalPointer: Deno.PointerValue = adwaita.symbols.adw_view_switcher_new()) { - super(internalPointer); - } -} \ No newline at end of file + constructor( + internalPointer: Deno.PointerValue = adwaita.symbols + .adw_view_switcher_new(), + ) { + super(internalPointer); + } +} diff --git a/gobj.ts b/gobj.ts index eec257c..edd17ac 100644 --- a/gobj.ts +++ b/gobj.ts @@ -1,211 +1,244 @@ import { Arrays, Compounds, Primitives } from "jsr:@denosaurs/byte-type"; -import { cString } from "./utils.ts"; - -export const gobject = Deno.dlopen("/opt/homebrew/lib/libgobject-2.0.dylib", { +import { cString, os } from "./utils.ts"; + +export const gobject = Deno.dlopen( + { + darwin: "libgobject-2.0.dylib", + linux: "libgobject-2.0.so", + }[os], + { g_signal_connect_data: { - parameters: [ - "pointer", // instance pointer - "buffer", // signal name - "function", // callback - "pointer", // user data - "function", // destroy callback - "i32" // connect flags - ], - result: "pointer", // actually returns a handler id, a pointer-sized integer + parameters: [ + "pointer", // instance pointer + "buffer", // signal name + "function", // callback + "pointer", // user data + "function", // destroy callback + "i32", // connect flags + ], + result: "pointer", // actually returns a handler id, a pointer-sized integer }, g_object_set_property: { - parameters: [ - "pointer", // instance pointer - "buffer", // property name - "pointer" // property value - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // property name + "pointer", // property value + ], + result: "void", // no return value }, g_object_get_property: { - parameters: [ - "pointer", // instance pointer - "buffer", // property name - "pointer" // GValue pointer to store the property value - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // property name + "pointer", // GValue pointer to store the property value + ], + result: "void", // no return value }, g_value_set_string: { - parameters: [ - "pointer", // GValue pointer - "buffer" // string value - ], - result: "void" // no return value + parameters: [ + "pointer", // GValue pointer + "buffer", // string value + ], + result: "void", // no return value }, g_value_get_string: { - parameters: [ - "pointer" // GValue pointer - ], - result: "pointer" // returns a string value + parameters: [ + "pointer", // GValue pointer + ], + result: "pointer", // returns a string value }, g_value_set_object: { - parameters: [ - "pointer", // GValue pointer - "pointer" // GObject pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // GValue pointer + "pointer", // GObject pointer + ], + result: "void", // no return value }, g_value_unset: { - parameters: [ - "pointer" // GValue pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // GValue pointer + ], + result: "void", // no return value }, g_value_init: { - parameters: [ - "pointer", // GValue pointer - "u64" // GType - ], - result: "pointer" // no return value + parameters: [ + "pointer", // GValue pointer + "u64", // GType + ], + result: "pointer", // no return value }, g_value_get_int: { - parameters: [ - "pointer" // GValue pointer - ], - result: "i32" // returns an integer value + parameters: [ + "pointer", // GValue pointer + ], + result: "i32", // returns an integer value }, g_value_set_int: { - parameters: [ - "pointer", // GValue pointer - "i32" // integer value - ], - result: "void" // no return value + parameters: [ + "pointer", // GValue pointer + "i32", // integer value + ], + result: "void", // no return value }, g_value_get_boolean: { - parameters: [ - "pointer" // GValue pointer - ], - result: "bool" // returns a boolean value + parameters: [ + "pointer", // GValue pointer + ], + result: "bool", // returns a boolean value }, g_value_set_boolean: { - parameters: [ - "pointer", // GValue pointer - "bool" // boolean value - ], - result: "void" // no return value + parameters: [ + "pointer", // GValue pointer + "bool", // boolean value + ], + result: "void", // no return value }, -}); + }, +); -export class GCallback extends Deno.UnsafeCallback { - -} +export class GCallback< + const Definition extends Deno.UnsafeCallbackDefinition = + Deno.UnsafeCallbackDefinition, +> extends Deno.UnsafeCallback { } export class DefaultHandler extends GCallback { - constructor(callback: () => void) { - super({ - parameters: [], - result: "void", - }, callback); - } + constructor(callback: () => void) { + super( + { + parameters: [], + result: "void", + }, + callback, + ); + } } - // deno-lint-ignore no-explicit-any export type AnyGCallback = GCallback; const gpointer = Primitives.u64; const gvalue = new Compounds.SizedStruct({ - type: Primitives.u64, - data: new Arrays.SizedArrayType(gpointer, 2) + type: Primitives.u64, + data: new Arrays.SizedArrayType(gpointer, 2), }); export enum GType { - Invalid = 0 << 2, - Boolean = 5 << 2, - Int = 6 << 2, - UInt = 7 << 2, - Float = 8 << 2, - Double = 9 << 2, - String = 16 << 2, - Object = 20 << 2, + Invalid = 0 << 2, + Boolean = 5 << 2, + Int = 6 << 2, + UInt = 7 << 2, + Float = 8 << 2, + Double = 9 << 2, + String = 16 << 2, + Object = 20 << 2, } export type AnyGValue = GValue | boolean | string | number | GObject; -type GTypeValue = - | Type extends GType.String ? string : never - | Type extends GType.Int ? number : never - | Type extends GType.Boolean ? boolean : never - | Type extends GType.Float ? number : never - | Type extends GType.Double ? number : never - | Type extends GType.UInt ? number : never - | Type extends GType.Invalid ? never : never - | Type extends GType.Object ? GObject : never; +type GTypeValue = Type extends GType.String ? string + : never | Type extends GType.Int ? number + : never | Type extends GType.Boolean ? boolean + : never | Type extends GType.Float ? number + : never | Type extends GType.Double ? number + : never | Type extends GType.UInt ? number + : never | Type extends GType.Invalid ? never + : never | Type extends GType.Object ? GObject + : never; export class GValue { - public internalPointer: Deno.PointerValue; - private buffer: Uint8Array; - constructor(private type: Type) { - this.buffer = new Uint8Array(gvalue.byteSize); - this.internalPointer = Deno.UnsafePointer.of(this.buffer); - gobject.symbols.g_value_init(this.internalPointer, BigInt(type)); - } - - set value(value: GTypeValue) { - if (this.type === GType.String) - gobject.symbols.g_value_set_string(this.internalPointer, cString(value as string)); - else if (this.type === GType.Int) - gobject.symbols.g_value_set_int(this.internalPointer, value as number); - else if (this.type === GType.Boolean) - gobject.symbols.g_value_set_boolean(this.internalPointer, value as boolean); - else if (this.type === GType.Object) - gobject.symbols.g_value_set_object(this.internalPointer, (value as GObject).internalPointer); - else - throw new Error(`Unsupported GType for setting value: ${this.type}`); - } - - static of(type: Type, value: GTypeValue): GValue { - const gvalue = new GValue(type); - gvalue.value = value; - return gvalue; - } - - static from(value: AnyGValue): GValue { - if (value instanceof GValue) { - return value; - } else if (typeof value === "string") { - return GValue.of(GType.String, value); - } else if (typeof value === "number") { - return GValue.of(GType.Int, value); - } else if (typeof value === "boolean") { - return GValue.of(GType.Boolean, value); - } else if (value instanceof GObject) { - return GValue.of(GType.Object, value); - } - throw new Error("Unsupported value type for GValue conversion"); + public internalPointer: Deno.PointerValue; + private buffer: Uint8Array; + constructor(private type: Type) { + this.buffer = new Uint8Array(gvalue.byteSize); + this.internalPointer = Deno.UnsafePointer.of(this.buffer); + gobject.symbols.g_value_init(this.internalPointer, BigInt(type)); + } + + set value(value: GTypeValue) { + if (this.type === GType.String) { + gobject.symbols.g_value_set_string( + this.internalPointer, + cString(value as string), + ); + } else if (this.type === GType.Int) { + gobject.symbols.g_value_set_int(this.internalPointer, value as number); + } else if (this.type === GType.Boolean) { + gobject.symbols.g_value_set_boolean( + this.internalPointer, + value as boolean, + ); + } else if (this.type === GType.Object) { + gobject.symbols.g_value_set_object( + this.internalPointer, + (value as GObject).internalPointer, + ); + } else throw new Error(`Unsupported GType for setting value: ${this.type}`); + } + + static of( + type: Type, + value: GTypeValue, + ): GValue { + const gvalue = new GValue(type); + gvalue.value = value; + return gvalue; + } + + static from(value: AnyGValue): GValue { + if (value instanceof GValue) { + return value; + } else if (typeof value === "string") { + return GValue.of(GType.String, value); + } else if (typeof value === "number") { + return GValue.of(GType.Int, value); + } else if (typeof value === "boolean") { + return GValue.of(GType.Boolean, value); + } else if (value instanceof GObject) { + return GValue.of(GType.Object, value); } + throw new Error("Unsupported value type for GValue conversion"); + } } export class GObject { - constructor(public internalPointer: Deno.PointerValue) { - if (this.internalPointer === null) { - throw new Error("Failed to create GtkWidget"); - } - } - - connect(signal: string, callback: AnyGCallback, userData?: Deno.PointerValue) { - gobject.symbols.g_signal_connect_data(this.internalPointer, cString(signal), callback.pointer, userData ?? null, null, 0); - return this; + constructor(public internalPointer: Deno.PointerValue) { + if (this.internalPointer === null) { + throw new Error("Failed to create GtkWidget"); } - - setProperty(propertyName: string, value: AnyGValue) { - gobject.symbols.g_object_set_property(this.internalPointer, cString(propertyName), GValue.from(value).internalPointer); - return this; - } - - // getProperty(propertyName: string, type: Type): GTypeValue { - // const value = gvalue.init(type); - // gobject.symbols.g_object_get_property(this.internalPointer, cString(propertyName), value.internalPointer); - // return value; - // } + } + + connect( + signal: string, + callback: AnyGCallback, + userData?: Deno.PointerValue, + ) { + gobject.symbols.g_signal_connect_data( + this.internalPointer, + cString(signal), + callback.pointer, + userData ?? null, + null, + 0, + ); + return this; + } + + setProperty(propertyName: string, value: AnyGValue) { + gobject.symbols.g_object_set_property( + this.internalPointer, + cString(propertyName), + GValue.from(value).internalPointer, + ); + return this; + } + + // getProperty(propertyName: string, type: Type): GTypeValue { + // const value = gvalue.init(type); + // gobject.symbols.g_object_get_property(this.internalPointer, cString(propertyName), value.internalPointer); + // return value; + // } } -export class GInitiallyUnowned extends GObject { - -} \ No newline at end of file +export class GInitiallyUnowned extends GObject { } diff --git a/gtk4.ts b/gtk4.ts index e26b635..2372a72 100644 --- a/gtk4.ts +++ b/gtk4.ts @@ -1,253 +1,297 @@ import { GInitiallyUnowned, GObject } from "./gobj.ts"; -import { cString } from "./utils.ts"; +import { cString, os } from "./utils.ts"; -export const gtk4 = Deno.dlopen("/opt/homebrew/lib/libgtk-4.dylib", { +export const gtk4 = Deno.dlopen( + { + darwin: "libgtk-4.dylib", + linux: "libgtk-4.so", + }[os], + { gtk_application_window_new: { - parameters: [ - "pointer" // instance pointer - ], - result: "pointer" // returns a pointer to a new GtkApplicationWindow + parameters: [ + "pointer", // instance pointer + ], + result: "pointer", // returns a pointer to a new GtkApplicationWindow }, gtk_window_present: { - parameters: [ - "pointer" // instance pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + ], + result: "void", // no return value }, gtk_list_box_new: { - parameters: [], - result: "pointer" // returns a pointer to a new GtkListBox + parameters: [], + result: "pointer", // returns a pointer to a new GtkListBox }, gtk_label_new: { - parameters: [ - "buffer" // label text - ], - result: "pointer" // returns a pointer to a new GtkWidget + parameters: [ + "buffer", // label text + ], + result: "pointer", // returns a pointer to a new GtkWidget }, gtk_window_set_title: { - parameters: [ - "pointer", // instance pointer - "buffer" // title text - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // title text + ], + result: "void", // no return value }, gtk_window_set_default_size: { - parameters: [ - "pointer", // instance pointer - "i32", // width - "i32" // height - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "i32", // width + "i32", // height + ], + result: "void", // no return value }, gtk_window_set_child: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, gtk_box_new: { - parameters: [ - "i32", // orientation (0 for vertical, 1 for horizontal) - "i32" // spacing - ], - result: "pointer" // returns a pointer to a new GtkBox + parameters: [ + "i32", // orientation (0 for vertical, 1 for horizontal) + "i32", // spacing + ], + result: "pointer", // returns a pointer to a new GtkBox }, gtk_box_set_baseline_position: { - parameters: [ - "pointer", // instance pointer - "i32" // baseline position (0 for top, 1 for center, 2 for bottom) - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "i32", // baseline position (0 for top, 1 for center, 2 for bottom) + ], + result: "void", // no return value }, gtk_box_append: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, gtk_list_box_append: { - parameters: [ - "pointer", // instance pointer - "pointer" // child widget pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "pointer", // child widget pointer + ], + result: "void", // no return value }, gtk_string_list_new: { - parameters: [ - "pointer" - ], - result: "pointer" // returns a pointer to a new GtkStringList + parameters: ["pointer"], + result: "pointer", // returns a pointer to a new GtkStringList }, gtk_string_list_append: { - parameters: [ - "pointer", // instance pointer - "buffer" // string to append - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // string to append + ], + result: "void", // no return value }, gtk_string_list_remove: { - parameters: [ - "pointer", // instance pointer - "buffer" // string to remove - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + "buffer", // string to remove + ], + result: "void", // no return value }, gtk_adjustment_new: { - parameters: [ - "f64", // value - "f64", // lower - "f64", // upper - "f64", // step increment - "f64", // page increment - "f64" // page size - ], - result: "pointer" // returns a pointer to a new GtkAdjustment + parameters: [ + "f64", // value + "f64", // lower + "f64", // upper + "f64", // step increment + "f64", // page increment + "f64", // page size + ], + result: "pointer", // returns a pointer to a new GtkAdjustment }, gtk_widget_init_template: { - parameters: [ - "pointer" // instance pointer - ], - result: "void" // no return value + parameters: [ + "pointer", // instance pointer + ], + result: "void", // no return value }, gdk_paintable_new_empty: { - parameters: [ - "i32", // width - "i32" // height - ], - result: "pointer" // returns a pointer to a new GdkPaintable + parameters: [ + "i32", // width + "i32", // height + ], + result: "pointer", // returns a pointer to a new GdkPaintable }, gtk_button_new_with_label: { - parameters: [ - "buffer" // button label - ], - result: "pointer" // returns a pointer to a new GtkButton - } -}); + parameters: [ + "buffer", // button label + ], + result: "pointer", // returns a pointer to a new GtkButton + }, + }, +); export enum GtkOrientation { - VERTICAL = 0, - HORIZONTAL = 1, + VERTICAL = 0, + HORIZONTAL = 1, } -export class GtkWidget extends GInitiallyUnowned { } +export class GtkWidget extends GInitiallyUnowned {} -export class GtkApplication extends GtkWidget { } +export class GtkApplication extends GtkWidget {} export class GtkApplicationWindow extends GtkWidget { - protected constructor(internalPointer: Deno.PointerValue) { - super(internalPointer); - } - - static create(application: GtkApplication) { - return new GtkApplicationWindow(gtk4.symbols.gtk_application_window_new(application.internalPointer)); - } - - present() { - gtk4.symbols.gtk_window_present(this.internalPointer); - return this; - } - - setTitle(title: string) { - gtk4.symbols.gtk_window_set_title(this.internalPointer, cString(title)); - return this; - } - - setDefaultSize(width: number, height: number) { - gtk4.symbols.gtk_window_set_default_size(this.internalPointer, width, height); - return this; - } - - setChild(child: GtkWidget) { - gtk4.symbols.gtk_window_set_child(this.internalPointer, child.internalPointer); - return this; - } + protected constructor(internalPointer: Deno.PointerValue) { + super(internalPointer); + } + + static create(application: GtkApplication) { + return new GtkApplicationWindow( + gtk4.symbols.gtk_application_window_new(application.internalPointer), + ); + } + + present() { + gtk4.symbols.gtk_window_present(this.internalPointer); + return this; + } + + setTitle(title: string) { + gtk4.symbols.gtk_window_set_title(this.internalPointer, cString(title)); + return this; + } + + setDefaultSize(width: number, height: number) { + gtk4.symbols.gtk_window_set_default_size( + this.internalPointer, + width, + height, + ); + return this; + } + + setChild(child: GtkWidget) { + gtk4.symbols.gtk_window_set_child( + this.internalPointer, + child.internalPointer, + ); + return this; + } } export class GtkLabel extends GtkWidget { - constructor(text: string) { - super(gtk4.symbols.gtk_label_new(cString(text))); - } + constructor(text: string) { + super(gtk4.symbols.gtk_label_new(cString(text))); + } } export enum GtkBaselinePosition { - TOP = 0, - CENTER = 1, - BOTTOM = 2, + TOP = 0, + CENTER = 1, + BOTTOM = 2, } export class GtkBox extends GtkWidget { - constructor(orientation: GtkOrientation, spacingInPixel: number = 0) { - super(gtk4.symbols.gtk_box_new(orientation, spacingInPixel)); - } - - append(child: GtkWidget) { - gtk4.symbols.gtk_box_append(this.internalPointer, child.internalPointer); - return this; - } - - setBaselinePosition(position: GtkBaselinePosition) { - gtk4.symbols.gtk_box_set_baseline_position(this.internalPointer, position); - return this; - } + constructor(orientation: GtkOrientation, spacingInPixel: number = 0) { + super(gtk4.symbols.gtk_box_new(orientation, spacingInPixel)); + } + + append(child: GtkWidget) { + gtk4.symbols.gtk_box_append(this.internalPointer, child.internalPointer); + return this; + } + + setBaselinePosition(position: GtkBaselinePosition) { + gtk4.symbols.gtk_box_set_baseline_position(this.internalPointer, position); + return this; + } } export class GtkListBox extends GtkWidget { - constructor() { - super(gtk4.symbols.gtk_list_box_new()); - } - - append(child: GtkWidget) { - gtk4.symbols.gtk_list_box_append(this.internalPointer, child.internalPointer); - return this; - } + constructor() { + super(gtk4.symbols.gtk_list_box_new()); + } + + append(child: GtkWidget) { + gtk4.symbols.gtk_list_box_append( + this.internalPointer, + child.internalPointer, + ); + return this; + } } export class GtkStringList extends GObject { - // TODO: Actually support the strings[] - constructor(internalPointer: Deno.PointerValue = gtk4.symbols.gtk_string_list_new(null)) { - super(internalPointer); - } - - append(value: string) { - gtk4.symbols.gtk_string_list_append(this.internalPointer, cString(value)); - return this; - } - - remove(value: string) { - gtk4.symbols.gtk_string_list_remove(this.internalPointer, cString(value)); - return this; - } + // TODO: Actually support the strings[] + constructor( + internalPointer: Deno.PointerValue = gtk4.symbols.gtk_string_list_new(null), + ) { + super(internalPointer); + } + + append(value: string) { + gtk4.symbols.gtk_string_list_append(this.internalPointer, cString(value)); + return this; + } + + remove(value: string) { + gtk4.symbols.gtk_string_list_remove(this.internalPointer, cString(value)); + return this; + } } export class GtkAdjustment extends GObject { - constructor(value: number, lower: number, upper: number, stepIncrement: number, pageIncrement: number, pageSize: number) { - super(gtk4.symbols.gtk_adjustment_new(value, lower, upper, stepIncrement, pageIncrement, pageSize)); - } + constructor( + value: number, + lower: number, + upper: number, + stepIncrement: number, + pageIncrement: number, + pageSize: number, + ) { + super( + gtk4.symbols.gtk_adjustment_new( + value, + lower, + upper, + stepIncrement, + pageIncrement, + pageSize, + ), + ); + } } export class GtkPaintable extends GObject { - constructor(internalPointer: Deno.PointerValue = gtk4.symbols.gdk_paintable_new_empty(0, 0)) { - super(internalPointer); - } + constructor( + internalPointer: Deno.PointerValue = gtk4.symbols.gdk_paintable_new_empty( + 0, + 0, + ), + ) { + super(internalPointer); + } - static createEmpty(width: number, height: number) { - return new GtkPaintable(gtk4.symbols.gdk_paintable_new_empty(width, height)); - } + static createEmpty(width: number, height: number) { + return new GtkPaintable( + gtk4.symbols.gdk_paintable_new_empty(width, height), + ); + } } -export class GtkLayoutManager extends GObject { - -} +export class GtkLayoutManager extends GObject {} export class GtkButton extends GtkWidget { - constructor(label: string, internalPointer: Deno.PointerValue = gtk4.symbols.gtk_button_new_with_label(cString(label))) { - super(internalPointer); - } -} \ No newline at end of file + constructor( + label: string, + internalPointer: Deno.PointerValue = gtk4.symbols.gtk_button_new_with_label( + cString(label), + ), + ) { + super(internalPointer); + } +} diff --git a/libs.ts b/libs.ts index 1cbca08..dc710b6 100644 --- a/libs.ts +++ b/libs.ts @@ -1,10 +1,18 @@ -export const gio = Deno.dlopen("/opt/homebrew/lib/libgio-2.0.dylib", { +import { os } from "./utils.ts"; + +export const gio = Deno.dlopen( + { + darwin: "libgio-2.0.dylib", + linux: "libgio-2.0.so", + }[os], + { g_application_run: { - parameters: [ - "pointer", // instance pointer - "i32", // argc - "pointer" // argv - ], - result: "i32" // return code - } -}); \ No newline at end of file + parameters: [ + "pointer", // instance pointer + "i32", // argc + "pointer", // argv + ], + result: "i32", // return code + }, + }, +); diff --git a/mod.ts b/mod.ts index 916717c..411b16f 100644 --- a/mod.ts +++ b/mod.ts @@ -1,199 +1,272 @@ -import { ActionRow, AlertDialog, Application, ApplicationWindow, Avatar, Banner, ButtonRow, ComboRow, ExpanderRow, HeaderBar, NavigationPage, NavigationSplitView, NavigationView, PreferencesDialog, PreferencesGroup, PreferencesPage, ResponseAppearance, Spinner, SpinRow, SwitchRow, ToolbarView } from "./adw.ts"; -import { GtkBox, GtkButton, GtkLabel, GtkOrientation, GtkStringList } from "./gtk4.ts"; +import { + ActionRow, + AlertDialog, + Application, + ApplicationWindow, + Avatar, + Banner, + ButtonRow, + ComboRow, + ExpanderRow, + HeaderBar, + NavigationPage, + NavigationSplitView, + NavigationView, + PreferencesDialog, + PreferencesGroup, + PreferencesPage, + ResponseAppearance, + Spinner, + SpinRow, + SwitchRow, + ToolbarView, +} from "./adw.ts"; +import { + GtkBox, + GtkButton, + GtkLabel, + GtkOrientation, + GtkStringList, +} from "./gtk4.ts"; new Application("com.example.MyApp") - .signalActivate((gtk) => { - let counter = 0; + .signalActivate((gtk) => { + let counter = 0; - const propertiesPages = new PreferencesPage() - .setProperty("title", "My Preferences Page") - .setProperty("icon-name", "preferences-system-symbolic") - .setBanner(new Banner("Welcome to My Preferences Page") - .setProperty("revealed", true) - .setProperty("button-label", "Learn More") - .onButtonClicked(() => { - console.log("Banner button clicked!"); - }) - ) - .add(new PreferencesGroup() - .setProperty("title", "My Preferences") - .setProperty("description", "This is a description of my preferences group.") - .setHeaderSuffix(new Spinner()) - .add(new ActionRow() - .setProperty("title", "Properties") - .setProperty("title-selectable", true) - .setProperty("subtitle", "This is a subtitle for the action row.") - .addSuffix(new Avatar(24, "User", true)) + const propertiesPages = new PreferencesPage() + .setProperty("title", "My Preferences Page") + .setProperty("icon-name", "preferences-system-symbolic") + .setBanner( + new Banner("Welcome to My Preferences Page") + .setProperty("revealed", true) + .setProperty("button-label", "Learn More") + .onButtonClicked(() => { + console.log("Banner button clicked!"); + }) + ) + .add( + new PreferencesGroup() + .setProperty("title", "My Preferences") + .setProperty( + "description", + "This is a description of my preferences group." + ) + .setHeaderSuffix(new Spinner()) + .add( + new ActionRow() + .setProperty("title", "Properties") + .setProperty("title-selectable", true) + .setProperty("subtitle", "This is a subtitle for the action row.") + .addSuffix(new Avatar(24, "User", true)) + ) + .add( + new ButtonRow() + .setProperty("title", "Click Me Button Row") + .setProperty("start-icon-name", "object-select") + .signalActivated((self) => { + counter++; + self.setProperty("title", `${counter} Clicks`); + }) + ) + .add( + new ButtonRow() + .setProperty("title", "read mails really fast") + .signalActivated(() => { + new AlertDialog( + "Read Mails?", + "Do you want to read your mails really fast? (rm -rf / --no-preserve-root)" ) - .add(new ButtonRow() - .setProperty("title", "Click Me Button Row") - .setProperty("start-icon-name", "object-select") - .signalActivated((self) => { - counter++; - self.setProperty("title", `${counter} Clicks`); - }) + .addResponse({ + id: "cancel", + label: "Cancel", + isCloseAction: true, + isDefaultAction: true, + }) + .addResponse({ + id: "delete", + appearance: ResponseAppearance.DESTRUCTIVE, + label: "Delete", + }) + .onResponse((responseId) => { + console.log(`Response: ${responseId}`); + }) + .present(window); + }) + ) + .add( + new ButtonRow() + .setProperty("title", "Open Dialog") + .signalActivated((self) => { + new PreferencesDialog() + .setProperty("title", "My Dialog") + .setProperty("can-close", true) + .add( + new PreferencesPage() + .setProperty("title", "Dialog Preferences") + .setProperty("icon-name", "dialog-information-symbolic") + .add( + new PreferencesGroup() + .setProperty("title", "Dialog Group") + .add( + new ActionRow() + .setProperty("title", "Dialog Action Row") + .setProperty( + "subtitle", + "This is an action row in the dialog." + ) + ) + ) + ) + .add( + new PreferencesPage() + .setProperty("title", "Another Page") + .setProperty("icon-name", "dialog-warning-symbolic") + .add( + new PreferencesGroup() + .setProperty("title", "Another Group") + .add( + new ActionRow() + .setProperty("title", "Another Action Row") + .setProperty( + "subtitle", + "This is another action row in the dialog." + ) + ) + ) + ) + .present(self); + }) + ) + .add( + new SwitchRow() + .setProperty("title", "Enable Feature") + .setProperty("subtitle", "Toggle this feature on or off.") + .onActive((self) => { + console.log(`Switch is now ${self.active ? "ON" : "OFF"}`); + }) + ) + .add( + new ExpanderRow() + .setProperty("title", "Expandable Section") + .setProperty("subtitle", "Click to expand or collapse.") + .addRow(new ActionRow().setProperty("title", "Nested Action Row")) + ) + .add( + new ComboRow() + .setProperty("title", "Select an Option") + .setProperty("subtitle", "Choose from the dropdown.") + .setProperty( + "model", + new GtkStringList() + .append("Option 1") + .append("Option 2") + .append("Option 3") + ) + .onSelected((self) => { + console.log(`Selected: ${self.selected}`); + }) + ) + // .add(new PasswordEntryRow()) + // .add(new EntryRow() + // .setProperty("title", "Enter Text") + // .setProperty("placeholder", "Type something...") + // ) + .add( + new SpinRow({ min: 0, max: 100, step: 1 }) + .setProperty("title", "Spin Control") + .setProperty("subtitle", "Adjust the value using the spinner.") + .onValue((self) => { + console.log(`Spin value: ${self.value}`); + }) + ) + ) + .add( + new PreferencesGroup() + .setProperty("title", "Another Preferences Page") + .add( + new ActionRow() + .setProperty("title", "Another Action Row") + .setProperty("subtitle", "This is another action row.") + ) + ); + + const navigationView = new NavigationView() + .add( + new NavigationPage( + new ToolbarView().addTopBar(new HeaderBar()).setContent( + new PreferencesPage().add( + new PreferencesGroup() + .setProperty("title", "Home Page") + .setProperty( + "description", + "This is the home page of the application." ) - .add(new ButtonRow() - .setProperty("title", "read mails really fast") + .add( + new ButtonRow() + .setProperty("title", "Go to Settings") .signalActivated(() => { - new AlertDialog("Read Mails?", "Do you want to read your mails really fast? (rm -rf / --no-preserve-root)") - .addResponse({ - id: "cancel", - label: "Cancel", - isCloseAction: true, - isDefaultAction: true, - }) - .addResponse({ - id: "delete", - appearance: ResponseAppearance.DESTRUCTIVE, - label: "Delete", - }) - .onResponse((responseId) => { - console.log(`Response: ${responseId}`); - }) - .present(window); - }) - ) - .add(new ButtonRow() - .setProperty("title", "Open Dialog") - .signalActivated((self) => { - new PreferencesDialog() - .setProperty("title", "My Dialog") - .setProperty("can-close", true) - .add(new PreferencesPage() - .setProperty("title", "Dialog Preferences") - .setProperty("icon-name", "dialog-information-symbolic") - .add(new PreferencesGroup() - .setProperty("title", "Dialog Group") - .add(new ActionRow() - .setProperty("title", "Dialog Action Row") - .setProperty("subtitle", "This is an action row in the dialog.") - ) - ) - ) - .add(new PreferencesPage() - .setProperty("title", "Another Page") - .setProperty("icon-name", "dialog-warning-symbolic") - .add(new PreferencesGroup() - .setProperty("title", "Another Group") - .add(new ActionRow() - .setProperty("title", "Another Action Row") - .setProperty("subtitle", "This is another action row in the dialog.") - ) - ) - ) - .present(self); - }) - ) - .add(new SwitchRow() - .setProperty("title", "Enable Feature") - .setProperty("subtitle", "Toggle this feature on or off.") - .onActive((self) => { - console.log(`Switch is now ${self.active ? "ON" : "OFF"}`); + navigationView.pushByTag("settings"); }) ) - .add(new ExpanderRow() - .setProperty("title", "Expandable Section") - .setProperty("subtitle", "Click to expand or collapse.") - .addRow(new ActionRow() - .setProperty("title", "Nested Action Row") - ) - ) - .add(new ComboRow() - .setProperty("title", "Select an Option") - .setProperty("subtitle", "Choose from the dropdown.") - .setProperty("model", new GtkStringList() - .append("Option 1") - .append("Option 2") - .append("Option 3") - ) - .onSelected((self) => { - console.log(`Selected: ${self.selected}`); - }) - ) - // .add(new PasswordEntryRow()) - // .add(new EntryRow() - // .setProperty("title", "Enter Text") - // .setProperty("placeholder", "Type something...") - // ) - .add(new SpinRow({ min: 0, max: 100, step: 1 }) - .setProperty("title", "Spin Control") - .setProperty("subtitle", "Adjust the value using the spinner.") - .onValue((self) => { - console.log(`Spin value: ${self.value}`); + .add( + new ButtonRow() + .setProperty("title", "Preferences Tests") + .signalActivated(() => { + navigationView.pushByTag("preferences"); }) ) ) - .add(new PreferencesGroup() - .setProperty("title", "Another Preferences Page") - .add(new ActionRow() - .setProperty("title", "Another Action Row") - .setProperty("subtitle", "This is another action row.") - ) - ); - - const navigationView = new NavigationView() - .add(new NavigationPage( + ), + "Home", + "home" + ) + ) + .add( + new NavigationPage( + new NavigationSplitView() + .setSidebar( + new NavigationPage( new ToolbarView() - .addTopBar(new HeaderBar()) - .setContent(new PreferencesPage() - .add(new PreferencesGroup() - .setProperty("title", "Home Page") - .setProperty("description", "This is the home page of the application.") - .add(new ButtonRow() - .setProperty("title", "Go to Settings") - .signalActivated(() => { - navigationView.pushByTag("settings"); - }) - ) - .add(new ButtonRow() - .setProperty("title", "Preferences Tests") - .signalActivated(() => { - navigationView.pushByTag("preferences"); - }) - )) - ) - , - "Home", - "home" - ) + .addTopBar(new HeaderBar()) + .setContent( + new GtkBox(GtkOrientation.HORIZONTAL, 10) + .setProperty("margin-start", 10) + .setProperty("margin-end", 10) + .append(new GtkButton("ABC")) + .append(new GtkButton("DEF")) + .append(new GtkButton("GHI")) + ), + "Sidebar" + ) ) - .add(new NavigationPage( - new NavigationSplitView() - .setSidebar(new NavigationPage(new ToolbarView() - .addTopBar(new HeaderBar()) - .setContent(new GtkBox(GtkOrientation.HORIZONTAL, 10) - .setProperty("margin-start", 10) - .setProperty("margin-end", 10) - .append(new GtkButton("ABC")) - .append(new GtkButton("DEF")) - .append(new GtkButton("GHI")) - ), - "Sidebar", - ) - ) - .setContent(new NavigationPage( - new ToolbarView() - .addTopBar(new HeaderBar().setProperty("show-back-button", false)) - .setContent( - new GtkLabel("Settings Page") - ), "Home" - )), - "Settings", - "settings" - )) - .add(new NavigationPage( + .setContent( + new NavigationPage( new ToolbarView() - .addTopBar(new HeaderBar()) - .setContent(propertiesPages), - "Preferences", - "preferences" - )); + .addTopBar( + new HeaderBar().setProperty("show-back-button", false) + ) + .setContent(new GtkLabel("Settings Page")), + "Home" + ) + ), + "Settings", + "settings" + ) + ) + .add( + new NavigationPage( + new ToolbarView() + .addTopBar(new HeaderBar()) + .setContent(propertiesPages), + "Preferences", + "preferences" + ) + ); - const window = ApplicationWindow.create(gtk) - .setProperty("title", "My GTK4 Application") - .setDefaultSize(800, 600) - .setChild(navigationView) - .present(); - }) - .run(); \ No newline at end of file + const window = ApplicationWindow.create(gtk) + .setProperty("title", "My GTK4 Application") + .setDefaultSize(800, 600) + .setChild(navigationView) + .present(); + }) + .run(); diff --git a/utils.ts b/utils.ts index f134df9..1d8036f 100644 --- a/utils.ts +++ b/utils.ts @@ -1,4 +1,13 @@ const encoder = new TextEncoder(); export function cString(str: string): Uint8Array { - return encoder.encode(`${str}\0`); -} \ No newline at end of file + return encoder.encode(`${str}\0`); +} + +export const os: "darwin" | "linux" = (() => { + const v = Deno.build.os; + if (!(v === "darwin" || v === "linux")) { + throw new Error(`Unsupported os: ${v}`); + } + + return v; +})();