From 89889aa84c8ec39c8160796c135dde690c4008d5 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Wed, 11 Jun 2025 22:18:35 +0200 Subject: [PATCH] add first wrapper for toolkit button functions --- .../main/java/de/unixwork/ui/ArgFuncs.java | 62 +++++++ .../src/main/java/de/unixwork/ui/Button.java | 18 ++ .../main/java/de/unixwork/ui/ButtonArgs.java | 165 ++++++++++++++++++ .../main/java/de/unixwork/ui/ButtonFuncs.java | 28 +++ .../test/java/de/unixwork/ui/demo/Main.java | 1 + 5 files changed, 274 insertions(+) create mode 100644 ui-java/src/main/java/de/unixwork/ui/Button.java create mode 100644 ui-java/src/main/java/de/unixwork/ui/ButtonArgs.java create mode 100644 ui-java/src/main/java/de/unixwork/ui/ButtonFuncs.java diff --git a/ui-java/src/main/java/de/unixwork/ui/ArgFuncs.java b/ui-java/src/main/java/de/unixwork/ui/ArgFuncs.java index b1b18f8..8024d19 100644 --- a/ui-java/src/main/java/de/unixwork/ui/ArgFuncs.java +++ b/ui-java/src/main/java/de/unixwork/ui/ArgFuncs.java @@ -12,10 +12,32 @@ class ArgFuncs { MethodHandle menuitem_args_set_icon; MethodHandle menuitem_args_free; + MethodHandle button_args_new; + MethodHandle button_args_set_fill; + MethodHandle button_args_set_hexpand; + MethodHandle button_args_set_vexpand; + MethodHandle button_args_set_hfill; + MethodHandle button_args_set_vfill; + MethodHandle button_args_set_override_defaults; + MethodHandle button_args_set_colspan; + MethodHandle button_args_set_rowspan; + MethodHandle button_args_set_name; + MethodHandle button_args_set_style_class; + MethodHandle button_args_set_label; + MethodHandle button_args_set_stockid; + MethodHandle button_args_set_icon; + MethodHandle button_args_set_labeltype; + MethodHandle button_args_set_onclick; + MethodHandle button_args_set_onclickdata; + MethodHandle button_args_set_groups; + MethodHandle button_args_free; + private ArgFuncs(Linker linker, SymbolLookup lib) { FunctionDescriptor sigm = FunctionDescriptor.of(ValueLayout.ADDRESS); FunctionDescriptor sigv_m = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS); FunctionDescriptor sigv_mm = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS); + FunctionDescriptor sigv_mb = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_BOOLEAN); + FunctionDescriptor sigv_mi = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT); MemorySegment ui_menuitem_args_new_addr = lib.find("ui_menuitem_args_new").orElseThrow(); MemorySegment ui_menuitem_args_set_label_addr = lib.find("ui_menuitem_args_set_label").orElseThrow(); @@ -25,11 +47,51 @@ class ArgFuncs { MemorySegment ui_menuitem_args_set_onclickdata_addr = lib.find("ui_menuitem_args_set_onclickdata").orElseThrow(); MemorySegment ui_menuitem_args_free_addr = lib.find("ui_menuitem_args_free").orElseThrow(); + MemorySegment ui_button_args_new_addr = lib.find("ui_button_args_new").orElseThrow(); + MemorySegment ui_button_args_set_fill_addr = lib.find("ui_button_args_set_fill").orElseThrow(); + MemorySegment ui_button_args_set_hexpand_addr = lib.find("ui_button_args_set_hexpand").orElseThrow(); + MemorySegment ui_button_args_set_vexpand_addr = lib.find("ui_button_args_set_vexpand").orElseThrow(); + MemorySegment ui_button_args_set_hfill_addr = lib.find("ui_button_args_set_hfill").orElseThrow(); + MemorySegment ui_button_args_set_vfill_addr = lib.find("ui_button_args_set_vfill").orElseThrow(); + MemorySegment ui_button_args_set_override_defaults_addr = lib.find("ui_button_args_set_override_defaults").orElseThrow(); + MemorySegment ui_button_args_set_colspan_addr = lib.find("ui_button_args_set_colspan").orElseThrow(); + MemorySegment ui_button_args_set_rowspan_addr = lib.find("ui_button_args_set_rowspan").orElseThrow(); + MemorySegment ui_button_args_set_name_addr = lib.find("ui_button_args_set_name").orElseThrow(); + MemorySegment ui_button_args_set_style_class_addr = lib.find("ui_button_args_set_style_class").orElseThrow(); + MemorySegment ui_button_args_set_label_addr = lib.find("ui_button_args_set_label").orElseThrow(); + MemorySegment ui_button_args_set_stockid_addr = lib.find("ui_button_args_set_stockid").orElseThrow(); + MemorySegment ui_button_args_set_icon_addr = lib.find("ui_button_args_set_icon").orElseThrow(); + MemorySegment ui_button_args_set_labeltype_addr = lib.find("ui_button_args_set_labeltype").orElseThrow(); + MemorySegment ui_button_args_set_onclick_addr = lib.find("ui_button_args_set_onclick").orElseThrow(); + MemorySegment ui_button_args_set_onclickdata_addr = lib.find("ui_button_args_set_onclickdata").orElseThrow(); + MemorySegment ui_button_args_set_groups_addr = lib.find("ui_button_args_set_groups").orElseThrow(); + MemorySegment ui_button_args_free_addr = lib.find("ui_button_args_free").orElseThrow(); + menuitem_args_new = linker.downcallHandle(ui_menuitem_args_new_addr, sigm); menuitem_args_set_label = linker.downcallHandle(ui_menuitem_args_set_label_addr, sigv_mm); menuitem_args_set_stockid = linker.downcallHandle(ui_menuitem_args_set_stockid_addr, sigv_mm); menuitem_args_set_icon = linker.downcallHandle(ui_menuitem_args_set_icon_addr, sigv_mm); menuitem_args_free = linker.downcallHandle(ui_menuitem_args_free_addr, sigv_m); + + button_args_new = linker.downcallHandle(ui_button_args_new_addr, sigm); + button_args_set_fill = linker.downcallHandle(ui_button_args_set_fill_addr, sigm); + button_args_set_hexpand = linker.downcallHandle(ui_button_args_set_hexpand_addr, sigv_mb); + button_args_set_vexpand = linker.downcallHandle(ui_button_args_set_vexpand_addr, sigv_mb); + button_args_set_hfill = linker.downcallHandle(ui_button_args_set_hfill_addr, sigv_mb); + button_args_set_vfill = linker.downcallHandle(ui_button_args_set_vfill_addr, sigv_mb); + button_args_set_override_defaults = linker.downcallHandle(ui_button_args_set_override_defaults_addr, sigv_mb); + button_args_set_colspan = linker.downcallHandle(ui_button_args_set_colspan_addr, sigv_mi); + button_args_set_rowspan = linker.downcallHandle(ui_button_args_set_rowspan_addr, sigv_mi); + button_args_set_name = linker.downcallHandle(ui_button_args_set_name_addr, sigv_mm); + button_args_set_style_class = linker.downcallHandle(ui_button_args_set_style_class_addr, sigv_mm); + button_args_set_label = linker.downcallHandle(ui_button_args_set_label_addr, sigv_mm); + button_args_set_stockid = linker.downcallHandle(ui_button_args_set_stockid_addr, sigv_mm); + button_args_set_icon = linker.downcallHandle(ui_button_args_set_icon_addr, sigv_mm); + button_args_set_labeltype = linker.downcallHandle(ui_button_args_set_labeltype_addr, sigv_mi); + button_args_set_onclick = linker.downcallHandle(ui_button_args_set_onclick_addr, sigv_mm); + button_args_set_onclickdata = linker.downcallHandle(ui_button_args_set_onclickdata_addr, sigv_mm); + button_args_set_groups = linker.downcallHandle(ui_button_args_set_groups_addr, sigv_mm); + button_args_free = linker.downcallHandle(ui_button_args_free_addr, sigv_m); } static ArgFuncs getInstance() { diff --git a/ui-java/src/main/java/de/unixwork/ui/Button.java b/ui-java/src/main/java/de/unixwork/ui/Button.java new file mode 100644 index 0000000..d9f7b4b --- /dev/null +++ b/ui-java/src/main/java/de/unixwork/ui/Button.java @@ -0,0 +1,18 @@ +package de.unixwork.ui; + +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; + +public class Button { + public static void createButton(UiObject obj, ButtonArgs args) { + ButtonFuncs ui = ButtonFuncs.getInstance(); + try (Arena arena = Arena.ofConfined()) { + MemorySegment buttonArgs = args.createButtonArgs(obj, arena); + MemorySegment widget = (MemorySegment) ui.button_create.invoke(obj.ptr, buttonArgs); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } +} diff --git a/ui-java/src/main/java/de/unixwork/ui/ButtonArgs.java b/ui-java/src/main/java/de/unixwork/ui/ButtonArgs.java new file mode 100644 index 0000000..ce22661 --- /dev/null +++ b/ui-java/src/main/java/de/unixwork/ui/ButtonArgs.java @@ -0,0 +1,165 @@ +package de.unixwork.ui; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; + +public class ButtonArgs { + + private boolean fill; + private boolean hexpand; + private boolean vexpand; + private boolean hfill; + private boolean vfill; + private boolean overrideDefaults; + private int colspan; + private int rowspan; + private String name; + private String styleClass; + private String label; + private String stockId; + private String icon; + private int labelType; + private EventHandler onClick; + private int[] states; + + public ButtonArgs() { + + } + + public ButtonArgs fill(boolean fill) { + this.fill = fill; + return this; + } + + public ButtonArgs hexpand(boolean hexpand) { + this.hexpand = hexpand; + return this; + } + + public ButtonArgs vexpand(boolean vexpand) { + this.vexpand = vexpand; + return this; + } + + public ButtonArgs hfill(boolean hfill) { + this.hfill = hfill; + return this; + } + + public ButtonArgs vfill(boolean vfill) { + this.vfill = vfill; + return this; + } + + public ButtonArgs overrideDefaults(boolean overrideDefaults) { + this.overrideDefaults = overrideDefaults; + return this; + } + + public ButtonArgs colspan(int colspan) { + this.colspan = colspan; + return this; + } + + public ButtonArgs rowspan(int rowspan) { + this.rowspan = rowspan; + return this; + } + + public ButtonArgs name(String name) { + this.name = name; + return this; + } + + public ButtonArgs styleClass(String styleClass) { + this.styleClass = styleClass; + return this; + } + + public ButtonArgs label(String label) { + this.label = label; + return this; + } + + public ButtonArgs stockId(String stockId) { + this.stockId = stockId; + return this; + } + + public ButtonArgs icon(String icon) { + this.icon = icon; + return this; + } + + public ButtonArgs labelType(int labelType) { + this.labelType = labelType; + return this; + } + + public ButtonArgs onClick(EventHandler onClick) { + this.onClick = onClick; + return this; + } + + public ButtonArgs states(int... states) { + this.states = states; + return this; + } + + public MemorySegment createButtonArgs(UiObject parent, Arena arena) throws Throwable { + ArgFuncs ui = ArgFuncs.getInstance(); + + MemorySegment args = (MemorySegment)ui.button_args_new.invoke(); + if(fill) { + // TODO + } + if(hexpand) { + ui.button_args_set_hexpand.invoke(args, hexpand); + } + if(vexpand) { + ui.button_args_set_vexpand.invoke(args, vexpand); + } + if(hfill) { + ui.button_args_set_hfill.invoke(args, hfill); + } + if(vfill) { + ui.button_args_set_vfill.invoke(args, vfill); + } + if(overrideDefaults) { + ui.button_args_set_override_defaults.invoke(args, overrideDefaults); + } + if(colspan > 0) { + ui.button_args_set_colspan.invoke(args, colspan); + } + if(rowspan > 0) { + ui.button_args_set_rowspan.invoke(args, rowspan); + } + if(name != null) { + MemorySegment cstr = arena.allocateFrom(name); + ui.button_args_set_name.invoke(args, cstr); + } + if(styleClass != null) { + MemorySegment cstr = arena.allocateFrom(styleClass); + ui.button_args_set_style_class.invoke(args, cstr); + } + if(label != null) { + MemorySegment cstr = arena.allocateFrom(label); + ui.button_args_set_label.invoke(args, cstr); + } + if(stockId != null) { + MemorySegment cstr = arena.allocateFrom(stockId); + ui.button_args_set_stockid.invoke(args, cstr); + } + if(icon != null) { + MemorySegment cstr = arena.allocateFrom(icon); + ui.button_args_set_icon.invoke(args, cstr); + } + ui.button_args_set_labeltype.invoke(args, labelType); + + if(onClick != null) { + // TODO + } + + return args; + } +} diff --git a/ui-java/src/main/java/de/unixwork/ui/ButtonFuncs.java b/ui-java/src/main/java/de/unixwork/ui/ButtonFuncs.java new file mode 100644 index 0000000..507d39c --- /dev/null +++ b/ui-java/src/main/java/de/unixwork/ui/ButtonFuncs.java @@ -0,0 +1,28 @@ +package de.unixwork.ui; + +import java.lang.foreign.*; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +public class ButtonFuncs { + static ButtonFuncs instance; + + public MethodHandle button_create; + + private ButtonFuncs(Linker linker, SymbolLookup lib) { + // void* func(void*, void*) + FunctionDescriptor sigm_mm = FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS); + + MemorySegment ui_button_create_addr = lib.find("ui_button_create").orElseThrow(); + + button_create = linker.downcallHandle(ui_button_create_addr, sigm_mm); + } + + static ButtonFuncs getInstance() { + if (instance == null) { + Toolkit toolkit = Toolkit.getInstance(); + instance = new ButtonFuncs(toolkit.getLinker(), toolkit.getSymbolLookup()); + } + return instance; + } +} diff --git a/ui-java/src/test/java/de/unixwork/ui/demo/Main.java b/ui-java/src/test/java/de/unixwork/ui/demo/Main.java index bda29de..06ab562 100644 --- a/ui-java/src/test/java/de/unixwork/ui/demo/Main.java +++ b/ui-java/src/test/java/de/unixwork/ui/demo/Main.java @@ -5,6 +5,7 @@ import de.unixwork.ui.*; public class Main implements Application{ public void startup() { UiObject window = UiObject.createWindow("Test Window"); + Button.createButton(window, new ButtonArgs().label("Hello World!")); window.show(); } -- 2.43.5