]> uap-core.de Git - rssreader.git/commitdiff
add new menu API
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Tue, 2 Sep 2025 17:04:36 +0000 (19:04 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Tue, 2 Sep 2025 17:04:36 +0000 (19:04 +0200)
ui-java/src/main/java/de/unixwork/ui/Application.java
ui-java/src/main/java/de/unixwork/ui/Menu.java [new file with mode: 0644]
ui-java/src/main/java/de/unixwork/ui/MenuElement.java [new file with mode: 0644]
ui-java/src/main/java/de/unixwork/ui/MenuFuncs.java
ui-java/src/main/java/de/unixwork/ui/MenuItem.java [new file with mode: 0644]
ui-java/src/test/java/de/unixwork/ui/demo/Main.java

index f2e31f376e15ad3063ba257d5f273d586e68eef2..50598d37c7bf9c77e745bece5015eac71e12cc88 100644 (file)
@@ -7,4 +7,8 @@ public interface Application {
     default void shutdown() {
 
     }
+
+    public static void setAppMenu(Menu appmenu) {
+        appmenu.create();
+    }
 }
diff --git a/ui-java/src/main/java/de/unixwork/ui/Menu.java b/ui-java/src/main/java/de/unixwork/ui/Menu.java
new file mode 100644 (file)
index 0000000..a18dcd2
--- /dev/null
@@ -0,0 +1,48 @@
+package de.unixwork.ui;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.MemorySegment;
+import java.util.LinkedList;
+
+public class Menu extends MenuElement {
+    private LinkedList<MenuElement> items = new LinkedList<>();
+    private String title;
+
+    public Menu() {
+
+    }
+
+    public Menu(String title) {
+        this.title = title;
+    }
+
+    public void add(MenuElement item) {
+        items.add(item);
+        item.setParent(this);
+    }
+
+    @Override
+    protected void create() {
+        if(parent != null) {
+            MenuFuncs ui = MenuFuncs.getInstance();
+            try (Arena arena = Arena.ofConfined()) {
+                MemorySegment label = MemorySegment.NULL;
+                if(title != null) {
+                    label = arena.allocateFrom(title);
+                }
+                ui.menu_create.invoke(label);
+                for(var item : items) {
+                    item.create();
+                }
+                ui.menu_end.invoke();
+            } catch (Throwable e) {
+                throw new RuntimeException(e);
+            }
+        } else {
+            for(var item : items) {
+                item.create();
+            }
+        }
+    }
+}
+
diff --git a/ui-java/src/main/java/de/unixwork/ui/MenuElement.java b/ui-java/src/main/java/de/unixwork/ui/MenuElement.java
new file mode 100644 (file)
index 0000000..ac2b3a3
--- /dev/null
@@ -0,0 +1,18 @@
+package de.unixwork.ui;
+
+public abstract class MenuElement {
+    Menu parent;
+
+    public void setParent(Menu parent) {
+        if(this.parent != null) {
+            throw new RuntimeException("Cannot set parent twice");
+        }
+        this.parent = parent;
+    }
+
+    public MenuElement getParent() {
+        return parent;
+    }
+
+    protected abstract void create();
+}
index 0894ed409619de13580ec5e3cd00614df422dfa3..a4e1b955c0f80b5d9d863e27256c673ca7edac76 100644 (file)
@@ -17,6 +17,9 @@ public class MenuFuncs {
     public MethodHandle menu_separator;
     public MethodHandle menu_itemlist_create;
 
+    public MethodHandle contextmenu_builder;
+    public MethodHandle menubuilder_free;
+
     public MethodHandle toolbar_item_create;
     public MethodHandle toolbar_toggleitem_create;
     public MethodHandle toolbar_menu_create;
@@ -45,6 +48,9 @@ public class MenuFuncs {
         MemorySegment ui_menu_separator_addr = lib.find("ui_menuseparator").orElseThrow();
         MemorySegment ui_menu_itemlist_create_addr = lib.find("ui_menu_itemlist_create").orElseThrow();
 
+        MemorySegment ui_contextmenu_builder_addr = lib.find("ui_contextmenu_builder").orElseThrow();
+        MemorySegment ui_menubuilder_free_addr = lib.find("ui_menubuilder_free").orElseThrow();
+
         MemorySegment ui_toolbar_item_create_addr = lib.find("ui_toolbar_item_create").orElseThrow();
         MemorySegment ui_toolbar_toggleitem_create_addr = lib.find("ui_toolbar_toggleitem_create").orElseThrow();
         MemorySegment ui_toolbar_menu_create_addr = lib.find("ui_toolbar_menu_create").orElseThrow();
@@ -61,6 +67,9 @@ public class MenuFuncs {
         menu_separator = linker.downcallHandle(ui_menu_separator_addr, sigv);
         menu_itemlist_create = linker.downcallHandle(ui_menu_itemlist_create_addr, sigv_m);
 
+        contextmenu_builder = linker.downcallHandle(ui_contextmenu_builder_addr, sigv_mm);
+        menubuilder_free = linker.downcallHandle(ui_menubuilder_free_addr, sigv_m);
+
         toolbar_item_create = linker.downcallHandle(ui_toolbar_item_create_addr, sigv_mm);
         toolbar_toggleitem_create = linker.downcallHandle(ui_toolbar_toggleitem_create_addr, sigv_mm);
         toolbar_menu_create = linker.downcallHandle(ui_toolbar_menu_create_addr, sigv_mm);
diff --git a/ui-java/src/main/java/de/unixwork/ui/MenuItem.java b/ui-java/src/main/java/de/unixwork/ui/MenuItem.java
new file mode 100644 (file)
index 0000000..862f4b9
--- /dev/null
@@ -0,0 +1,68 @@
+package de.unixwork.ui;
+
+import java.lang.foreign.Arena;
+import java.lang.foreign.MemorySegment;
+
+public class MenuItem extends MenuElement {
+    private String label;
+    private String icon;
+    private EventHandler onClick;
+
+    public MenuItem(String label, EventHandler onClick) {
+        this.label = label;
+        this.onClick = onClick;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    public String getIcon() {
+        return icon;
+    }
+
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    public EventHandler getOnClick() {
+        return onClick;
+    }
+
+    public void setOnClick(EventHandler onClick) {
+        this.onClick = onClick;
+    }
+
+    @Override
+    protected void create() {
+        MenuFuncs ui = MenuFuncs.getInstance();
+        ArgFuncs a = ArgFuncs.getInstance();
+        Toolkit toolkit = Toolkit.getInstance();
+        try (Arena arena = Arena.ofConfined()) {
+            MemorySegment args = (MemorySegment) a.menuitem_args_new.invoke();
+            if(label != null) {
+                MemorySegment cstr = arena.allocateFrom(label);
+                a.menuitem_args_set_label.invoke(args, cstr);
+            }
+            if(icon != null) {
+                MemorySegment cstr = arena.allocateFrom(icon);
+                a.menuitem_args_set_icon.invoke(args, cstr);
+            }
+            if(onClick != null) {
+                EventWrapper event = new EventWrapper(onClick);
+
+                // set toolkit args
+                a.menuitem_args_set_onclick.invoke(args, event.getCallback());
+                a.menuitem_args_set_onclickdata.invoke(args, event.getUserData());
+            }
+            ui.menuitem_create.invoke(args);
+            a.menuitem_args_free.invoke(args);
+        } catch (Throwable e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
index 9210823a83d8fcb0e0b3670449d2c27513ae644c..9c7b9599ab01afe8b15aa934497b01b390295086 100644 (file)
@@ -70,6 +70,7 @@ public class Main implements Application{
         System.out.println("UI Demo");
         Toolkit.init("testapp");
 
+        /*
         AppMenu.menu("File", () -> {
             AppMenu.menuItem("Open", event -> {
                 System.out.println("Open");
@@ -79,6 +80,18 @@ public class Main implements Application{
                 System.exit(0);
             });
         });
+        */
+        Menu appmenu = new Menu();
+        Menu fileMenu = new Menu("File");
+        appmenu.add(fileMenu);
+        fileMenu.add(new MenuItem("Open", event -> {
+            System.out.println("Open");
+        }));
+        fileMenu.add(new MenuItem("Exit", event -> {
+            System.out.println("Exit");
+            System.exit(0);
+        }));
+        Application.setAppMenu(appmenu);
 
         Toolbar.item("open", "Open", event -> {
             System.out.println("Toolbar Open");