MethodHandle list_args_set_ondragcompletedata;
MethodHandle list_args_set_ondrop;
MethodHandle list_args_set_ondropdata;
+ MethodHandle list_args_set_onsave;
+ MethodHandle list_args_set_onsavedata;
MethodHandle list_args_set_multiselection;
MethodHandle list_args_set_contextmenu;
MethodHandle list_args_set_groups;
MemorySegment ui_list_args_set_ondragcompletedata_addr = lib.find("ui_list_args_set_ondragcompletedata").orElseThrow();
MemorySegment ui_list_args_set_ondrop_addr = lib.find("ui_list_args_set_ondrop").orElseThrow();
MemorySegment ui_list_args_set_ondropdata_addr = lib.find("ui_list_args_set_ondropdata").orElseThrow();
+ MemorySegment ui_list_args_set_onsave_addr = lib.find("ui_list_args_set_onsave").orElseThrow();
+ MemorySegment ui_list_args_set_onsavedata_addr = lib.find("ui_list_args_set_onsavedata").orElseThrow();
MemorySegment ui_list_args_set_multiselection_addr = lib.find("ui_list_args_set_multiselection").orElseThrow();
MemorySegment ui_list_args_set_contextmenu_addr = lib.find("ui_list_args_set_contextmenu").orElseThrow();
MemorySegment ui_list_args_set_groups_addr = lib.find("ui_list_args_set_groups").orElseThrow();
list_args_set_ondragcompletedata = linker.downcallHandle(ui_list_args_set_ondragcompletedata_addr, sigv_mm);
list_args_set_ondrop = linker.downcallHandle(ui_list_args_set_ondrop_addr, sigv_mm);
list_args_set_ondropdata = linker.downcallHandle(ui_list_args_set_ondropdata_addr, sigv_mm);
+ list_args_set_onsave = linker.downcallHandle(ui_list_args_set_onsave_addr, sigv_mm);
+ list_args_set_onsavedata = linker.downcallHandle(ui_list_args_set_onsavedata_addr, sigv_mm);
list_args_set_multiselection = linker.downcallHandle(ui_list_args_set_multiselection_addr, sigv_mb);
list_args_set_contextmenu = linker.downcallHandle(ui_list_args_set_contextmenu_addr, sigv_mm);
list_args_set_groups = linker.downcallHandle(ui_list_args_set_groups_addr, sigv_mmi);
package de.unixwork.ui;
@FunctionalInterface
-public interface ListSaveFunc {
+public interface ListSaveHandler {
public boolean save(UiList list, int row, int column, Object value);
}
package de.unixwork.ui;
+import java.lang.foreign.Arena;
+import java.lang.foreign.MemorySegment;
+import java.lang.foreign.ValueLayout;
+
public class ListSaveWrapper {
+ private MemorySegment callback;
+ private MemorySegment userdata;
+
+ public ListSaveWrapper(UiObject obj, ListSaveHandler handler) {
+ Arena objArena = obj.getArena(); // very important to use the obj arena
+ callback = Toolkit.getInstance().eventHandler;
+
+ long index = obj.addListSaveHandler(handler);
+
+ userdata = objArena.allocate(ValueLayout.JAVA_LONG, 2);
+ userdata.setAtIndex(ValueLayout.JAVA_LONG, 0, obj.ptr.address());
+ userdata.setAtIndex(ValueLayout.JAVA_LONG, 1, index);
+ }
+
+ public static boolean onSaveHandler(MemorySegment list, int row, int col, MemorySegment value, MemorySegment userData) {
+ Toolkit tk = Toolkit.getInstance();
+ ToolkitFuncs ui = ToolkitFuncs.getInstance();
+
+ userData = userData.reinterpret(16);
+ long objPtr = userData.getAtIndex(ValueLayout.JAVA_LONG, 0);
+ long handlerIndex = userData.getAtIndex(ValueLayout.JAVA_LONG, 1);
+ UiObject obj = tk.getToplevelObject(objPtr);
+ if(obj == null) {
+ return false;
+ }
+ ListSaveHandler handler = obj.getListSaveHandler((int)handlerIndex);
+ if(handler == null) {
+ return false;
+ }
+
+ UiList uilist = Toolkit.listPtrToObject(list);
+
+ Object valueObj = null;
+ try {
+ if((boolean) ui.cell_value_is_string.invoke(value)) {
+ MemorySegment cstr = (MemorySegment) ui.cell_value_get_string.invoke(value);
+ valueObj = (String)cstr.getString(0);
+ } else if((boolean) ui.cell_value_is_int.invoke(value)) {
+ valueObj = ui.cell_value_get_int.invoke(value);
+ }
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+
+ return handler.save(uilist, row, col, valueObj);
+ }
+
+ public MemorySegment getCallback() {
+ return callback;
+ }
+
+ public MemorySegment getUserData() {
+ return userdata;
+ }
}
private EventHandler onDragStart;
private EventHandler onDragComplete;
private EventHandler onDrop;
+ private ListSaveHandler onSave;
private boolean multiselection;
private Menu contextMenu;
// TODO: contextmenu
return this;
}
+ public TableViewBuilder<T> onSave(ListSaveHandler onSave) {
+ this.onSave = onSave;
+ return this;
+ }
+
public TableViewBuilder<T> states(int... states) {
this.states = states;
return this;
ui.list_args_set_ondrop.invoke(args, event.getCallback());
ui.list_args_set_ondropdata.invoke(args, event.getUserData());
}
+ if (onSave != null) {
+ ListSaveWrapper handler = new ListSaveWrapper(obj, onSave);
+ ui.list_args_set_onsave.invoke(args, handler.getCallback());
+ ui.list_args_set_onsavedata.invoke(args, handler.getUserData());
+ }
if (contextMenu != null) {
menuBuilder = contextMenu.createMenuBuilder();
ui.list_args_set_contextmenu.invoke(args, menuBuilder);
protected MemorySegment eventHandler;
protected MemorySegment globalEventHandler;
protected MemorySegment oneshotEventHandler;
+ protected MemorySegment onSaveHandler;
private HashMap<Integer, ThreadCallback> threadCallbacks = new HashMap<>();
oneshotCallbackMethod,
handlerSig,
staticArena);
+
+ try {
+ MethodHandle onSaveMethod = MethodHandles.lookup().findStatic(
+ ListSaveWrapper.class,
+ "onSaveHandler",
+ MethodType.methodType(boolean.class, MemorySegment.class, int.class, int.class, MemorySegment.class, MemorySegment.class));
+
+ onSaveHandler = linker.upcallStub(
+ onSaveMethod,
+ FunctionDescriptor.of(ValueLayout.JAVA_BOOLEAN, ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS),
+ staticArena);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
}
public static Toolkit getInstance() {
public MethodHandle textstyle_set_color;
public MethodHandle textstyle_enable_color;
+ public MethodHandle cell_value_is_string;
+ public MethodHandle cell_value_is_int;
+ public MethodHandle cell_value_get_string;
+ public MethodHandle cell_value_get_int;
+
public MemorySegment ui_set_visible_addr;
public MemorySegment ui_set_enabled_addr;
FunctionDescriptor sigv_mdd = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_DOUBLE, ValueLayout.JAVA_DOUBLE);
FunctionDescriptor sigv_mmmi = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT);
FunctionDescriptor sigv_mmmmi = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT);
+ FunctionDescriptor sigb_m = FunctionDescriptor.of(ValueLayout.JAVA_BOOLEAN, ValueLayout.ADDRESS);
MemorySegment object_get_context_addr = lib.find("ui_object_get_context").orElseThrow();
MemorySegment textstyle_set_color_addr = lib.find("ui_textstyle_set_color").orElseThrow();
MemorySegment textstyle_enable_color_addr = lib.find("ui_textstyle_enable_color").orElseThrow();
+ MemorySegment cell_value_is_string_addr = lib.find("ui_cell_value_is_string").orElseThrow();
+ MemorySegment cell_value_is_int_addr = lib.find("ui_cell_value_is_int").orElseThrow();
+ MemorySegment cell_value_get_string_addr = lib.find("ui_cell_value_get_string").orElseThrow();
+ MemorySegment cell_value_get_int_addr = lib.find("ui_cell_value_get_int").orElseThrow();
+
ui_set_visible_addr = lib.find("ui_set_visible").orElseThrow();
ui_set_enabled_addr = lib.find("ui_set_enabled").orElseThrow();
MemorySegment ui_widget_set_groups2_addr = lib.find("ui_widget_set_groups2").orElseThrow();
textstyle_set_color = linker.downcallHandle(textstyle_set_color_addr, sigv_miii);
textstyle_enable_color = linker.downcallHandle(textstyle_enable_color_addr, sigv_mb);
+ cell_value_is_string = linker.downcallHandle(cell_value_is_string_addr, sigb_m);
+ cell_value_is_int = linker.downcallHandle(cell_value_is_int_addr, sigb_m);
+ cell_value_get_string = linker.downcallHandle(cell_value_get_string_addr, sigm_m);
+ cell_value_get_int = linker.downcallHandle(cell_value_get_int_addr, sigl_m);
+
set_enabled = linker.downcallHandle(ui_set_enabled_addr, sigv_mi);
set_visible = linker.downcallHandle(ui_set_visible_addr, sigv_mi);
set_widget_groups2 = linker.downcallHandle(ui_widget_set_groups2_addr, sigv_mmmmi);
private ArrayList<EventHandler> eventHandlers = new ArrayList<>();
private ArrayList<ObjectDestroyHandler> closeHandlers = new ArrayList<>();
+ private ArrayList<ListSaveHandler> listSaveHandlers = new ArrayList<>();
private Arena arena;
return eventHandlers.get(index);
}
+ public long addListSaveHandler(ListSaveHandler handler) {
+ listSaveHandlers.add(handler);
+ return listSaveHandlers.size() - 1;
+ }
+
+ public ListSaveHandler getListSaveHandler(int index) {
+ return listSaveHandlers.get(index);
+ }
+
public Arena getArena() {
if (arena == null) {
arena = Arena.ofShared();