]> uap-core.de Git - rssreader.git/commitdiff
add UiList first/next/get implementation
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Thu, 26 Jun 2025 20:27:48 +0000 (22:27 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Thu, 26 Jun 2025 20:27:48 +0000 (22:27 +0200)
ui-java/src/main/java/de/unixwork/ui/CUtils.java
ui-java/src/main/java/de/unixwork/ui/Context.java
ui-java/src/main/java/de/unixwork/ui/ListFuncs.java
ui-java/src/main/java/de/unixwork/ui/ListView.java
ui-java/src/main/java/de/unixwork/ui/ListViewBuilder.java
ui-java/src/main/java/de/unixwork/ui/Toolkit.java
ui-java/src/main/java/de/unixwork/ui/ToolkitFuncs.java
ui-java/src/main/java/de/unixwork/ui/UiList.java
ui-java/src/test/java/de/unixwork/ui/demo/Main.java

index 0be062c2d239b57512d0c9e5eb45f685d3547b41..49e364d4cb6bd2fa54ab282dc66c16eb6edf832a 100644 (file)
@@ -18,8 +18,7 @@ public class CUtils {
         try {
             long size = utf8.length + 1;
             MemorySegment cstr = (MemorySegment) tk.malloc.invoke(size);
-            MemorySegment segment = MemorySegment.ofAddress(cstr.address());
-            ByteBuffer buf = segment.asByteBuffer();
+            ByteBuffer buf = cstr.asByteBuffer();
             buf.put(utf8);
             buf.put((byte) 0);
             return cstr;
index 36c3da412087b5a3f9d28ab59acdb800aee692e6..ffd680ea951c1e4e62b840cc8d8345f238772eaf 100644 (file)
@@ -63,6 +63,14 @@ public abstract class Context {
         return funcData;
     }
 
+    public UiList<?> getList(int index) {
+        return lists.get(index);
+    }
+
+    public ListValueConverter getValueConverter(int index) {
+        return converters.get(index);
+    }
+
 
     public void attach(Document doc) {
         ToolkitFuncs ui = ToolkitFuncs.getInstance();
index a094ee7938fe47df8731b40cd72c08b25c278b6d..b0105fc5aaecec5d4c62f4ac756d0075f7f1c871 100644 (file)
@@ -6,6 +6,18 @@ import java.lang.invoke.MethodHandle;
 public class ListFuncs {
     static ListFuncs instance;
 
+    public MethodHandle list_class_set_first;
+    public MethodHandle list_class_set_next;
+    public MethodHandle list_class_set_get;
+    public MethodHandle list_class_set_count;
+    public MethodHandle list_class_set_data;
+    public MethodHandle list_class_set_iter;
+
+    public MethodHandle list_get_data;
+    public MethodHandle list_set_data;
+    public MethodHandle list_get_iter;
+    public MethodHandle list_set_iter;
+
     public MethodHandle listview_create;
     public MethodHandle table_create;
     public MethodHandle combobox_create;
@@ -14,12 +26,38 @@ public class ListFuncs {
     private ListFuncs(Linker linker, SymbolLookup lib) {
         // void* func(void*, void*)
         FunctionDescriptor sigm_mm = FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS);
+        FunctionDescriptor sigm_m = FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS);
+        FunctionDescriptor sigv_mm = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS);
+
+        MemorySegment ui_list_class_set_first_addr = lib.find("ui_list_class_set_first").orElseThrow();
+        MemorySegment ui_list_class_set_next_addr = lib.find("ui_list_class_set_next").orElseThrow();
+        MemorySegment ui_list_class_set_get_addr = lib.find("ui_list_class_set_get").orElseThrow();
+        MemorySegment ui_list_class_set_count_addr = lib.find("ui_list_class_set_count").orElseThrow();
+        MemorySegment ui_list_class_set_data_addr = lib.find("ui_list_class_set_data").orElseThrow();
+        MemorySegment ui_list_class_set_iter_addr = lib.find("ui_list_class_set_iter").orElseThrow();
+
+        MemorySegment ui_list_get_data_addr = lib.find("ui_list_get_data").orElseThrow();
+        MemorySegment ui_list_set_data_addr = lib.find("ui_list_set_data").orElseThrow();
+        MemorySegment ui_list_get_iter_addr = lib.find("ui_list_get_iter").orElseThrow();
+        MemorySegment ui_list_set_iter_addr = lib.find("ui_list_set_iter").orElseThrow();
 
         MemorySegment ui_listview_create_addr = lib.find("ui_listview_create").orElseThrow();
         MemorySegment ui_table_create_addr = lib.find("ui_table_create").orElseThrow();
         MemorySegment ui_combobox_create_addr = lib.find("ui_combobox_create").orElseThrow();
         MemorySegment ui_sourcelist_create_addr = lib.find("ui_sourcelist_create").orElseThrow();
 
+        list_class_set_first = linker.downcallHandle(ui_list_class_set_first_addr, sigv_mm);
+        list_class_set_next = linker.downcallHandle(ui_list_class_set_next_addr, sigv_mm);
+        list_class_set_get = linker.downcallHandle(ui_list_class_set_get_addr, sigv_mm);
+        list_class_set_count = linker.downcallHandle(ui_list_class_set_count_addr, sigv_mm);
+        list_class_set_data = linker.downcallHandle(ui_list_class_set_data_addr, sigv_mm);
+        list_class_set_iter = linker.downcallHandle(ui_list_class_set_iter_addr, sigv_mm);
+
+        list_get_data = linker.downcallHandle(ui_list_get_data_addr, sigm_m);
+        list_set_data = linker.downcallHandle(ui_list_set_data_addr, sigm_mm);
+        list_get_iter = linker.downcallHandle(ui_list_get_iter_addr, sigm_m);
+        list_set_iter = linker.downcallHandle(ui_list_set_iter_addr, sigm_mm);
+
         listview_create = linker.downcallHandle(ui_listview_create_addr, sigm_mm);
         table_create = linker.downcallHandle(ui_table_create_addr, sigm_mm);
         combobox_create = linker.downcallHandle(ui_combobox_create_addr, sigm_mm);
index 3806309e6c41de363ae848b0ed74b85deaabf22f..151c201e904953f6cc66e8b0d303087b6d1bdf59 100644 (file)
@@ -3,8 +3,8 @@ package de.unixwork.ui;
 public class ListView {
 
 
-    public static ListViewBuilder list(UiObject obj) {
+    public static <T> ListViewBuilder<T> list(UiObject obj) {
         ListFuncs ui = ListFuncs.getInstance();
-        return new ListViewBuilder(obj, ui.listview_create);
+        return new ListViewBuilder<T>(obj, ui.listview_create);
     }
 }
index 0af74c87aa081a929751775cb01babe4dc66d858..7f8563745b9f5d8f872af4a63ef679fa61e783e9 100644 (file)
@@ -34,82 +34,88 @@ public class ListViewBuilder<T> extends AbstractWidgetBuilder {
         this.widgetConstructor = widgetConstructor;
     }
 
-    public ListViewBuilder fill(boolean fill) {
+    public ListViewBuilder<T> fill(boolean fill) {
         this.fill = fill;
         return this;
     }
 
-    public ListViewBuilder hexpand(boolean hexpand) {
+    public ListViewBuilder<T> hexpand(boolean hexpand) {
         this.hexpand = hexpand;
         return this;
     }
 
-    public ListViewBuilder vexpand(boolean vexpand) {
+    public ListViewBuilder<T> vexpand(boolean vexpand) {
         this.vexpand = vexpand;
         return this;
     }
 
-    public ListViewBuilder hfill(boolean hfill) {
+    public ListViewBuilder<T> hfill(boolean hfill) {
         this.hfill = hfill;
         return this;
     }
 
-    public ListViewBuilder vfill(boolean vfill) {
+    public ListViewBuilder<T> vfill(boolean vfill) {
         this.vfill = vfill;
         return this;
     }
 
-    public ListViewBuilder overrideDefaults(boolean overrideDefaults) {
+    public ListViewBuilder<T> overrideDefaults(boolean overrideDefaults) {
         this.overrideDefaults = overrideDefaults;
         return this;
     }
 
-    public ListViewBuilder colspan(int colspan) {
+    public ListViewBuilder<T> colspan(int colspan) {
         this.colspan = colspan;
         return this;
     }
 
-    public ListViewBuilder rowspan(int rowspan) {
+    public ListViewBuilder<T> rowspan(int rowspan) {
         this.rowspan = rowspan;
         return this;
     }
 
-    public ListViewBuilder name(String name) {
+    public ListViewBuilder<T> name(String name) {
         this.name = name;
         return this;
     }
 
-    public ListViewBuilder styleClass(String styleClass) {
+
+    public ListViewBuilder<T> styleClass(String styleClass) {
         this.styleClass = styleClass;
         return this;
     }
 
-    public ListViewBuilder varname(String varname) {
+    public ListViewBuilder<T> varname(String varname) {
         this.varname = varname;
         return this;
     }
 
-    public ListViewBuilder onActivate(EventHandler onActivate) {
+    public ListViewBuilder<T> getvalue(ListValueConverter<T> getvalue) {
+        this.getvalue = getvalue;
+        return this;
+    }
+
+    public ListViewBuilder<T> onActivate(EventHandler onActivate) {
         this.onActivate = onActivate;
         return this;
     }
 
-    public ListViewBuilder onDragStart(EventHandler onDragStart) {
+    public ListViewBuilder<T> onDragStart(EventHandler onDragStart) {
         this.onDragStart = onDragStart;
         return this;
     }
 
-    public ListViewBuilder onDragComplete(EventHandler onDragComplete) {
+    public ListViewBuilder<T> onDragComplete(EventHandler onDragComplete) {
         this.onDragComplete = onDragComplete;
         return this;
     }
 
-    public ListViewBuilder onDrop(EventHandler onDrop) {
+    public ListViewBuilder<T> onDrop(EventHandler onDrop) {
         this.onDrop = onDrop;
         return this;
     }
 
-    public ListViewBuilder states(int... states) {
+    public ListViewBuilder<T> states(int... states) {
         this.states = states;
         return this;
     }
index 7a7e44d968a361e78ec0199e2c1f1696d2a6554f..6c1e13b350bb6a9c10595a6e785118a0b1633051 100644 (file)
@@ -111,11 +111,23 @@ public class Toolkit {
             MethodHandle getvalue = MethodHandles.lookup().findStatic(
                     Toolkit.class,
                     "getValue",
-                    MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, int.class, int.class, MemorySegment.class));
+                    MethodType.methodType(MemorySegment.class,
+                            MemorySegment.class,
+                            MemorySegment.class,
+                            int.class,
+                            int.class,
+                            MemorySegment.class,
+                            MemorySegment.class));
 
             getValue = linker.upcallStub(
                     getvalue,
-                    FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.ADDRESS),
+                    FunctionDescriptor.of(ValueLayout.ADDRESS,
+                            ValueLayout.ADDRESS,
+                            ValueLayout.ADDRESS,
+                            ValueLayout.JAVA_INT,
+                            ValueLayout.JAVA_INT,
+                            ValueLayout.ADDRESS,
+                            ValueLayout.ADDRESS),
                     staticArena);
         } catch (NoSuchMethodException e) {
             throw new RuntimeException(e);
@@ -312,8 +324,22 @@ public class Toolkit {
     /*
      * list getvaluefunc wrapper
      */
-    public static MemorySegment getValue(MemorySegment list, MemorySegment elm, int row, int col, MemorySegment userdata) {
-
+    public static MemorySegment getValue(MemorySegment list, MemorySegment elm, int row, int col, MemorySegment userdata, MemorySegment freeValue) {
+        long ctxPtr = userdata.getAtIndex(ValueLayout.JAVA_LONG, 0);
+        long converterIndex = userdata.getAtIndex(ValueLayout.JAVA_LONG, 1);
+
+        long listCtxPtr = list.getAtIndex(ValueLayout.JAVA_LONG, 0);
+        long listIndex = list.getAtIndex(ValueLayout.JAVA_LONG, 1);
+        Context listCtx = Toolkit.getInstance().getContext(listCtxPtr);
+        UiList uilist = listCtx.getList((int)listIndex);
+
+        Context ctx = Toolkit.getInstance().getContext(ctxPtr);
+        ListValueConverter conv = ctx.getValueConverter((int)converterIndex);
+        Object value = conv.getValue(null, col);
+        if(value instanceof String) {
+            freeValue.setAtIndex(ValueLayout.JAVA_BOOLEAN, 0, true);
+            return CUtils.cstring((String)value);
+        }
 
         return MemorySegment.NULL;
     }
index 9dd4ea9363dd6bc80d9820609f4bf8bfc56d87b1..f858b75a06fc37e9c9a3ff0642629b116c10db3f 100644 (file)
@@ -114,7 +114,7 @@ public class ToolkitFuncs {
         range_new = linker.downcallHandle(range_new_addr, sigm_mm);
         generic_new = linker.downcallHandle(generic_new_addr, sigm_mm);
         list_new =  linker.downcallHandle(list_new_addr, sigm_mm);
-        list_new2 =  linker.downcallHandle(list_new_addr, FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS));
+        list_new2 =  linker.downcallHandle(list_new2_addr, FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS));
 
         string_set = linker.downcallHandle(string_set_addr, sigv_mm);
         string_get = linker.downcallHandle(string_get_addr, sigm_m);
index fc1296f1ee1bf0938a1880499eba4b5df7f3699e..f11f18d5c3ca9552b1c54003fd3eda8dfad92b5d 100644 (file)
@@ -12,6 +12,7 @@ import java.util.ArrayList;
 public class UiList<T> extends ArrayList<T> {
     protected MemorySegment valuePtr;
     protected MemorySegment dataPtr;
+    protected int iter = 0;
 
     protected UiList(Context ctx, String name, MemorySegment listObj) {
         super();
@@ -45,23 +46,63 @@ public class UiList<T> extends ArrayList<T> {
     }
 
     private static void initList(MemorySegment ctx, MemorySegment list, MemorySegment userData) {
-        // TODO
+        ListFuncs ui = ListFuncs.getInstance();
+        Toolkit toolkit = Toolkit.getInstance();
+
+        try {
+            ui.list_class_set_first.invoke(list, toolkit.listFirst);
+            ui.list_class_set_next.invoke(list, toolkit.listNext);
+            ui.list_class_set_get.invoke(list, toolkit.listGet);
+            ui.list_class_set_count.invoke(list, toolkit.listCount);
+            ui.list_set_data.invoke(list, userData);
+        } catch (Throwable e) {
+            throw new RuntimeException(e);
+        }
     }
 
-    protected static MemorySegment first(MemorySegment list) {
-        return MemorySegment.NULL;
+    public static UiList<?> getList(MemorySegment ls) {
+        ListFuncs ui = ListFuncs.getInstance();
+        try {
+            MemorySegment data = ((MemorySegment)ui.list_get_data.invoke(ls));
+            data = data.reinterpret(16);
+            long ctxPtr = data.getAtIndex(ValueLayout.JAVA_LONG, 0);
+            long listIndex = data.getAtIndex(ValueLayout.JAVA_LONG, 1);
+            Context ctx = Toolkit.getInstance().getContext(ctxPtr);
+            return ctx.getList((int)listIndex);
+        } catch (Throwable e) {
+            throw new RuntimeException(e);
+        }
     }
 
-    protected static MemorySegment next(MemorySegment list) {
-        return MemorySegment.NULL;
+    protected static MemorySegment first(MemorySegment ls) {
+        UiList list = UiList.getList(ls);
+        if(list.size() == 0) {
+            return MemorySegment.NULL;
+        }
+        list.iter = 0;
+        return MemorySegment.ofAddress(1); // we use iter+1 as fake element pointer
     }
 
-    protected static MemorySegment get(MemorySegment list, int index) {
-        return MemorySegment.NULL;
+    protected static MemorySegment next(MemorySegment ls) {
+        UiList list = UiList.getList(ls);
+        if(list.iter >= list.size()) {
+            return MemorySegment.NULL;
+        }
+        list.iter++;
+        return MemorySegment.ofAddress(list.iter+1); // we use iter+1 as fake element pointer
     }
 
-    protected static int count(MemorySegment list) {
-        return 0;
+    protected static MemorySegment get(MemorySegment ls, int index) {
+        UiList list = UiList.getList(ls);
+        if(index  >= list.size()) {
+            return MemorySegment.NULL;
+        }
+        list.iter = index;
+        return MemorySegment.ofAddress(list.iter+1);
     }
 
+    protected static int count(MemorySegment ls) {
+        UiList list = UiList.getList(ls);
+        return list.size();
+    }
 }
index cacfb338b4a3bd870af5449d0e7875c3af5829b0..b044a5f2b23015106c5a087d9b52a7332346ad49 100644 (file)
@@ -7,6 +7,12 @@ import static java.awt.SystemColor.window;
 public class Main implements Application{
     public void startup() {
         UiObject window = UiObject.createWindow("Test Window");
+        UiList<String> mylist = window.list("mylist");
+        mylist.add("Test1");
+        mylist.add("Test2");
+        mylist.add("Test3");
+        mylist.add("Test4");
+
         Button.button(window).label("Click Me").onClick(event -> {
             System.out.println("Clicked");
         }).create();
@@ -20,6 +26,9 @@ public class Main implements Application{
             Button.button(window).label("B3").create();
             Container.vbox(window).create(() -> {
                 Button.button(window).label("Test").create();
+                ListView.<String>list(window).varname("mylist").getvalue((elm, col) -> {
+                    return elm;
+                }).create();
             });
         }