MethodHandle menuitem_args_set_label;
MethodHandle menuitem_args_set_stockid;
MethodHandle menuitem_args_set_icon;
+ MethodHandle menuitem_args_set_onclick;
+ MethodHandle menuitem_args_set_onclickdata;
MethodHandle menuitem_args_free;
MethodHandle menutoggleitem_args_new;
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_set_onclick = linker.downcallHandle(ui_menuitem_args_set_onclick_addr, sigv_mm);
+ menuitem_args_set_onclickdata = linker.downcallHandle(ui_menuitem_args_set_onclickdata_addr, sigv_mm);
menuitem_args_free = linker.downcallHandle(ui_menuitem_args_free_addr, sigv_m);
menutoggleitem_args_new = linker.downcallHandle(ui_menutoggleitem_args_new_addr, sigm);
package de.unixwork.ui;
+import javax.tools.Tool;
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.MemorySegment;
private MemorySegment userdata;
public EventWrapper(UiObject obj, EventHandler handler) {
- // We need to create an upcall stub for the static ButtonBuilder.eventHandler method
+ // We need to create an upcall stub for the static EventWrapper.eventHandler method
// Also, the event handler must be registered in the object and the returned index
// is used as callback userdata. This way we can map the userdata to the java
// EventHandler object
+ Arena objArena = obj.getArena(); // very important to use the obj arena
+ initCallback(objArena, "eventHandler");
+
+ long index = obj.addEventHandler(handler);
+ // use index as callback userdata, like casting it to intptr_t/void*
+ userdata = MemorySegment.ofAddress(index);
+ }
+
+ public EventWrapper(EventHandler handler) {
+ Toolkit toolkit = Toolkit.getInstance();
+ initCallback(toolkit.getStaticArena(), "globalEventHandler");
+ long index = toolkit.addEventHandler(handler);
+ userdata = MemorySegment.ofAddress(index);
+ }
+
+ private void initCallback(Arena arena, String methodName) {
Toolkit toolkit = Toolkit.getInstance();
// void callback(UiEvent *event, void *userdata)
FunctionDescriptor handlerSig = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS);
try {
callbackMethod = MethodHandles.lookup().findStatic(
EventWrapper.class,
- "eventHandler",
+ methodName,
MethodType.methodType(void.class, MemorySegment.class, MemorySegment.class));
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
- Arena objArena = obj.getArena();
+
callback = toolkit.getLinker().upcallStub(
callbackMethod,
handlerSig,
- obj.getArena()); // very important to use the obj arena
-
- long index = obj.addEventHandler(handler);
- // use index as callback userdata, like casting it to intptr_t/void*
- userdata = MemorySegment.ofAddress(index);
+ arena);
}
public MemorySegment getCallback() {
Event e = new Event(event);
UiObject obj = e.getObject();
EventHandler handler = obj.getEventHandler(eventHandlerIndex);
- handler.callback(e);
+ if(handler != null) {
+ handler.callback(e);
+ } // else: error?
+ }
+
+ public static void globalEventHandler(MemorySegment event, MemorySegment userdata) {
+ int eventHandlerIndex = (int)userdata.address();
+
+ Event e = new Event(event);
+ UiObject obj = e.getObject();
+ EventHandler handler = Toolkit.getInstance().getEventHandler(eventHandlerIndex);
+ if(handler != null) {
+ handler.callback(e);
+ } // else: error?
}
}
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
+import java.util.ArrayList;
import java.util.HashMap;
public class Toolkit {
private SymbolLookup lib;
private MethodHandle mainFunc;
+ private ArrayList<EventHandler> eventHandlers = new ArrayList<>();
+
protected MemorySegment listFirst;
protected MemorySegment listNext;
protected MemorySegment listGet;
// TODO: remove this notice when subobjects are removed from toolkit
}
+ public long addEventHandler(EventHandler handler) {
+ eventHandlers.add(handler);
+ return eventHandlers.size() - 1;
+ }
+
+ public EventHandler getEventHandler(int index) {
+ return eventHandlers.get(index);
+ }
+
public Context getContext(long address) {
return contexts.get(address);
}