Skip to content

Commit e56990f

Browse files
committed
Simplify drag'n'drop API with ability to directly transfer Java objects
1 parent 236a6de commit e56990f

File tree

2 files changed

+78
-9
lines changed

2 files changed

+78
-9
lines changed

imgui-binding/src/main/java/imgui/ImGui.java

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.io.IOException;
1313
import java.io.InputStream;
1414
import java.io.UncheckedIOException;
15+
import java.lang.ref.WeakReference;
1516
import java.nio.file.Files;
1617
import java.nio.file.Path;
1718
import java.nio.file.Paths;
@@ -4266,6 +4267,9 @@ public static void setNextWindowClass(ImGuiWindowClass windowClass) {
42664267
// Drag and Drop
42674268
// - [BETA API] API may evolve!
42684269

4270+
private static WeakReference<Object> objectPayloadRef = null;
4271+
private static final byte[] OBJECT_PAYLOAD_PLACEHOLDER_DATA = new byte[1];
4272+
42694273
/**
42704274
* Call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource()
42714275
*/
@@ -4280,19 +4284,48 @@ public static void setNextWindowClass(ImGuiWindowClass windowClass) {
42804284
return ImGui::BeginDragDropSource(imGuiDragDropFlags);
42814285
*/
42824286

4287+
/**
4288+
* Type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types.
4289+
* <p>
4290+
* BINDING NOTICE: Alternative for {@link #setDragDropPayload(String, byte[])}.
4291+
* Using this method any Java object can be used for payload.
4292+
* Binding layer stores a reference to the object in a form of {@link WeakReference}.
4293+
*/
4294+
public static boolean setDragDropPayloadObject(String type, Object payload) {
4295+
return setDragDropPayloadObject(type, payload, 0);
4296+
}
4297+
4298+
/**
4299+
* Type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types.
4300+
* <p>
4301+
* BINDING NOTICE: Alternative for {@link #setDragDropPayload(String, byte[], int)}.
4302+
* Using this method any Java object can be used for payload.
4303+
* Binding layer stores a reference to the object in a form of {@link WeakReference}.
4304+
*/
4305+
public static boolean setDragDropPayloadObject(String type, Object payload, int imGuiCond) {
4306+
if (objectPayloadRef == null || objectPayloadRef.get() != payload) {
4307+
objectPayloadRef = new WeakReference<>(payload);
4308+
}
4309+
return setDragDropPayload(type, OBJECT_PAYLOAD_PLACEHOLDER_DATA, imGuiCond);
4310+
}
4311+
42834312
/**
42844313
* Type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types.
42854314
* Data is copied and held by imgui.
42864315
*/
4287-
public static native boolean setDragDropPayload(String type, byte[] data, int sz); /*
4288-
return ImGui::SetDragDropPayload(type, &data[0], sz);
4289-
*/
4316+
public static boolean setDragDropPayload(String type, byte[] data) {
4317+
return nSetDragDropPayload(type, data, data.length, 0);
4318+
}
42904319

42914320
/**
42924321
* Type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types.
42934322
* Data is copied and held by imgui.
42944323
*/
4295-
public static native boolean setDragDropPayload(String type, byte[] data, int sz, int imGuiCond); /*
4324+
public static boolean setDragDropPayload(String type, byte[] data, int imGuiCond) {
4325+
return nSetDragDropPayload(type, data, data.length, imGuiCond);
4326+
}
4327+
4328+
private static native boolean nSetDragDropPayload(String type, byte[] data, int sz, int imGuiCond); /*
42964329
return ImGui::SetDragDropPayload(type, &data[0], sz, imGuiCond);
42974330
*/
42984331

@@ -4310,6 +4343,30 @@ public static void setNextWindowClass(ImGuiWindowClass windowClass) {
43104343
return ImGui::BeginDragDropTarget();
43114344
*/
43124345

4346+
/**
4347+
* Accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released.
4348+
* <p>
4349+
* BINDING NOTICE: Alternative for {@link #acceptDragDropPayload(String)}.
4350+
* Use in combination with {@link #setDragDropPayloadObject(String, Object)}.
4351+
*/
4352+
public static Object acceptDragDropPayloadObject(String type) {
4353+
return acceptDragDropPayloadObject(type, 0);
4354+
}
4355+
4356+
/**
4357+
* Accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released.
4358+
* <p>
4359+
* BINDING NOTICE: Alternative for {@link #acceptDragDropPayload(String, int)}.
4360+
* Use in combination with {@link #setDragDropPayloadObject(String, Object)}.
4361+
*/
4362+
public static Object acceptDragDropPayloadObject(String type, int imGuiDragDropFlags) {
4363+
return nAcceptDragDropPayloadObject(type, imGuiDragDropFlags) ? objectPayloadRef.get() : null;
4364+
}
4365+
4366+
private static native boolean nAcceptDragDropPayloadObject(String type, int imGuiDragDropFlags); /*
4367+
return ImGui::AcceptDragDropPayload(type, imGuiDragDropFlags) != NULL;
4368+
*/
4369+
43134370
/**
43144371
* Accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released.
43154372
*/
@@ -4342,7 +4399,20 @@ public static byte[] acceptDragDropPayload(String type, int imGuiDragDropFlags)
43424399

43434400
/**
43444401
* Peek directly into the current payload from anywhere. May return NULL. use ImGuiPayload::IsDataType() to test for the payload type.
4345-
* TODO implement ImGuiPayload class
4402+
* <p>
4403+
* BINDING NOTICE: Binding alternative for {@link #getDragDropPayload()}.
4404+
* Use in combination with {@link #setDragDropPayloadObject(String, Object)}.
4405+
*/
4406+
public static Object getDragDropPayloadObject() {
4407+
return nGetDragDropPayloadObjectObject() ? objectPayloadRef.get() : null;
4408+
}
4409+
4410+
private static native boolean nGetDragDropPayloadObjectObject(); /*
4411+
return ImGui::GetDragDropPayload() != NULL;
4412+
*/
4413+
4414+
/**
4415+
* Peek directly into the current payload from anywhere. May return NULL. use ImGuiPayload::IsDataType() to test for the payload type.
43464416
*/
43474417
public static native byte[] getDragDropPayload(); /*
43484418
if (const ImGuiPayload* payload = ImGui::GetDragDropPayload()) {

imgui-lwjgl3/src/test/java/ExampleUi.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ final class ExampleUi {
2424
private static final int LIMEGREEN_COLOR = ImColor.rgbToColor("#32CD32");
2525

2626
// Test data for payload
27-
private final byte[] testPayload = "Test Payload".getBytes();
2827
private String dropTargetText = "Drop Here";
2928

3029
// To modify background color dynamically
@@ -64,16 +63,16 @@ void render() {
6463
// Drag'n'Drop functionality
6564
ImGui.button("Drag me");
6665
if (ImGui.beginDragDropSource()) {
67-
ImGui.setDragDropPayload("payload_type", testPayload, testPayload.length);
66+
ImGui.setDragDropPayloadObject("payload_type", "Test Payload");
6867
ImGui.text("Drag started");
6968
ImGui.endDragDropSource();
7069
}
7170
ImGui.sameLine();
7271
ImGui.text(dropTargetText);
7372
if (ImGui.beginDragDropTarget()) {
74-
final byte[] payload = ImGui.acceptDragDropPayload("payload_type");
73+
final Object payload = ImGui.acceptDragDropPayloadObject("payload_type");
7574
if (payload != null) {
76-
dropTargetText = new String(payload);
75+
dropTargetText = (String) payload;
7776
}
7877
ImGui.endDragDropTarget();
7978
}

0 commit comments

Comments
 (0)