From a2d5ba0035112d30f366a9a5d7bde326d2601153 Mon Sep 17 00:00:00 2001 From: Danil Dubrovksy Date: Sun, 17 Jan 2021 15:27:50 +0300 Subject: [PATCH 1/3] [Binding] Implemented java bindings for imnodes and imgui-node-editor. Implemented simple graph editor to demonstrate both imnodes and imgui-node-editor usage. --- .gitmodules | 6 + .../groovy/imgui/generate/GenerateLibs.groovy | 4 + .../src/main/java/imgui/imnodes/ImNodes.java | 480 +++++++++++++++ .../imgui/imnodes/ImNodesAttributeFlags.java | 28 + .../java/imgui/imnodes/ImNodesColorStyle.java | 25 + .../java/imgui/imnodes/ImNodesContext.java | 43 ++ .../java/imgui/imnodes/ImNodesPinShape.java | 17 + .../java/imgui/imnodes/ImNodesStyleVar.java | 22 + .../java/imgui/nodeditor/ImNodeEditor.java | 548 ++++++++++++++++++ .../imgui/nodeditor/ImNodeEditorContext.java | 42 ++ .../imgui/nodeditor/ImNodeEditorPinKind.java | 11 + .../nodeditor/ImNodeEditorStyleColor.java | 27 + .../imgui/nodeditor/ImNodeEditorStyleVar.java | 32 + imgui-lwjgl3/src/test/java/ExampleUi.java | 294 +++++++++- .../src/test/java/ImGuiGlfwExample.java | 32 +- imgui-node-editor | 1 + imnodes | 1 + 17 files changed, 1609 insertions(+), 4 deletions(-) create mode 100644 imgui-binding/src/main/java/imgui/imnodes/ImNodes.java create mode 100644 imgui-binding/src/main/java/imgui/imnodes/ImNodesAttributeFlags.java create mode 100644 imgui-binding/src/main/java/imgui/imnodes/ImNodesColorStyle.java create mode 100644 imgui-binding/src/main/java/imgui/imnodes/ImNodesContext.java create mode 100644 imgui-binding/src/main/java/imgui/imnodes/ImNodesPinShape.java create mode 100644 imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleVar.java create mode 100644 imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditor.java create mode 100644 imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorContext.java create mode 100644 imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorPinKind.java create mode 100644 imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleColor.java create mode 100644 imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleVar.java create mode 160000 imgui-node-editor create mode 160000 imnodes diff --git a/.gitmodules b/.gitmodules index 028a4fb..ccdc9c4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,9 @@ [submodule "imgui"] path = imgui url = https://github.com/ocornut/imgui +[submodule "imgui-node-editor"] + path = imgui-node-editor + url = https://github.com/thedmd/imgui-node-editor.git +[submodule "imnodes"] + path = imnodes + url = https://github.com/Nelarius/imnodes.git diff --git a/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy b/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy index eb974e4..e934916 100644 --- a/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy +++ b/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy @@ -41,6 +41,10 @@ class GenerateLibs extends DefaultTask { project.copy { CopySpec spec -> spec.from(project.rootProject.file('imgui')) { CopySpec it -> it.include('*.h', '*.cpp') } + spec.from(project.rootProject.file('imnodes')) { CopySpec it -> it.include('*.h', '*.cpp') } + + spec.from(project.rootProject.file('imgui-node-editor')) { CopySpec it -> it.include('*.h', '*.cpp', '*.inl') } + if (withFreeType) { spec.from(project.rootProject.file('imgui/misc/freetype')) { CopySpec it -> it.include('*.h', '*.cpp') } } diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodes.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodes.java new file mode 100644 index 0000000..c4762e6 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodes.java @@ -0,0 +1,480 @@ +package imgui.imnodes; + +import imgui.ImVec2; +import imgui.type.ImBoolean; +import imgui.type.ImInt; + +/** + * Bindings for Imnodes (https://github.com/Nelarius/imnodes/) + * Original library author - Johann Muszynski (https://github.com/Nelarius) + * + * Refer to the library's Github page for examples and support + */ +public final class ImNodes { + + private ImNodes() { } + + /*JNI + #include + #include + #include + #include "jni_common.h" + #include "jni_binding_struct.h" + */ + + // An editor context corresponds to a set of nodes in a single workspace (created with a single + // Begin/EndNodeEditor pair) + // + // By default, the library creates an editor context behind the scenes, so using any of the imnodes + // functions doesn't require you to explicitly create a context. + + public static ImNodesContext editorContextCreate() { + return new ImNodesContext(); + } + + public static void editorContextFree(final ImNodesContext context) { + context.destroy(); + } + + public static void editorContextSet(final ImNodesContext context) { + nEditorContextSet(context.ptr); + } + + private static native void nEditorContextSet(long ptr); /* + imnodes::EditorContextSet((imnodes::EditorContext*)ptr); + */ + + /** + * Initialize the node editor system. + */ + public static native void initialize(); /* + imnodes::Initialize(); + */ + + public static native void shutdown(); /* + imnodes::Shutdown(); + */ + + // Style presets matching the dear imgui styles of the same name. + + public static native void styleColorsDark(); /* + imnodes::StyleColorsDark(); + */ + public static native void styleColorsClassic(); /* + imnodes::StyleColorsClassic(); + */ + public static native void styleColorsLight(); /* + imnodes::StyleColorsLight(); + */ + + /** + * Use PushColorStyle and PopColorStyle to modify ImNodesColorStyle mid-frame. + */ + public static native void pushColorStyle(int imNodesStyleColor, int color); /* + imnodes::PushColorStyle((imnodes::ColorStyle)imNodesStyleColor, color); + */ + + public static native void popColorStyle(); /* + imnodes::PopColorStyle(); + */ + + public static native void pushStyleVar(int imNodesStyleVar, float value); /* + imnodes::PushStyleVar((imnodes::StyleVar)imNodesStyleVar, value); + */ + + public static native void popStyleVar(); /* + imnodes::PopStyleVar(); + */ + + /** + * The top-level function call. Call this before calling BeginNode/EndNode. Calling this function + * will result the node editor grid workspace being rendered. + */ + public static native void beginNodeEditor(); /* + imnodes::BeginNodeEditor(); + */ + + public static native void endNodeEditor(); /* + imnodes::EndNodeEditor(); + */ + + public static native void beginNode(int node); /* + imnodes::BeginNode(node); + */ + + public static native void endNode(); /* + imnodes::EndNode(); + */ + + /** + * Render a link between attributes. + * The attributes ids used here must match the ids used in Begin(Input|Output)Attribute function + * calls. The order of source and target doesn't make a difference for rendering the link. + */ + public static native void link(int id, int source, int target); /* + imnodes::Link(id, source, target); + */ + + /** + * Place your node title bar content (such as the node title, using ImGui::Text) between the + * following function calls. These functions have to be called before adding any attributes, or the + * layout of the node will be incorrect. + */ + public static native void beginNodeTitleBar(); /* + imnodes::BeginNodeTitleBar(); + */ + + public static native void endNodeTitleBar(); /* + imnodes::EndNodeTitleBar(); + */ + + // Attributes are ImGui UI elements embedded within the node. Attributes can have pin shapes + // rendered next to them. Links are created between pins. + // + // The activity status of an attribute can be checked via the IsAttributeActive() and + // IsAnyAttributeActive() function calls. This is one easy way of checking for any changes made to + // an attribute's drag float UI, for instance. + // + // Each attribute id must be unique. + + + /** + * Create a static attribute block. A static attribute has no pin, and therefore can't be linked to + * anything. However, you can still use IsAttributeActive() and IsAnyAttributeActive() to check for + * attribute activity. + */ + public static native void beginStaticAttribute(int id); /* + imnodes::BeginStaticAttribute(id); + */ + + public static native void endStaticAttribute(); /* + imnodes::EndStaticAttribute(); + */ + + /** + * Create an input attribute block. The pin is rendered on left side. + */ + public static void beginInputAttribute(final int id) { + beginInputAttribute(id, ImNodesPinShape.CircleFilled); + } + + public static native void beginInputAttribute(int id, int imNodesPinShape); /* + imnodes::BeginInputAttribute(id, (imnodes::PinShape)imNodesPinShape); + */ + + public static native void endInputAttribute(); /* + imnodes::EndInputAttribute(); + */ + + /** + * Create an output attribute block. The pin is rendered on the right side. + */ + public static void beginOutputAttribute(final int id) { + beginOutputAttribute(id, ImNodesPinShape.CircleFilled); + } + + public static native void beginOutputAttribute(int id, int imNodesPinShape); /* + imnodes::BeginOutputAttribute(id, (imnodes::PinShape)imNodesPinShape); + */ + + /** + * Push a single AttributeFlags value. By default, only AttributeFlags_None is set. + */ + public static native void pushAttributeFlag(int imNodesAttributeFlags); /* + imnodes::PushAttributeFlag((imnodes::AttributeFlags)imNodesAttributeFlags); + */ + + public static native void endOutputAttribute(); /* + imnodes::EndOutputAttribute(); + */ + + /** + * Returns true if the current node editor canvas is being hovered over by the mouse, and is not + * blocked by any other windows. + */ + public static native boolean isEditorHovered(); /* + return imnodes::IsEditorHovered(); + */ + + /** + * Binding notice: getHoveredNode(), getHoveredLink() and getHoveredPin() + * return id of the hovered object. If there is no such object -1 will be returned. + * Use these functions after endNodeEditor() has been called. + * + * These methods implemented instead of the original bool imnodes::IsNodeHovered(int* node_id), + * bool imnodes::IsLinkHovered(int* link_id) and bool imnodes::IsPinHovered(int* attribute_id) for convenience. + */ + + public static native int getHoveredNode(); /* + int i; + return imnodes::IsNodeHovered(&i) ? i : -1; + */ + + public static native int getHoveredLink(); /* + int i; + return imnodes::IsLinkHovered(&i) ? i : -1; + */ + + public static native int getHoveredPin(); /* + int i; + return imnodes::IsPinHovered(&i) ? i : -1; + */ + + /** + * Binding notice: getActiveAttribute() returns id the active attribute. If there is no active attribute -1 will be returned. + * + * This method implemented instead of the original bool imnodes::IsAnyAttributeActive(int* attribute_id) for convenience. + */ + public static native int getActiveAttribute(); /* + int i; + return imnodes::IsAnyAttributeActive(&i) ? i : -1; + */ + + /** + * Was the previous attribute active? This will continuously return true while the left mouse button + * is being pressed over the UI content of the attribute. + */ + public static native boolean isAttributeActive(); /* + return imnodes::IsAttributeActive(); + */ + + // Use the following functions to query a change of state for an existing link, or new link. Call + // these after EndNodeEditor(). + + /** + * Did the user start dragging a new link from a pin? + */ + public static boolean isLinkStarted(final ImInt startAtAttributeId) { + return nIsLinkStarted(startAtAttributeId.getData()); + } + + private static native boolean nIsLinkStarted(int[] data); /* + return imnodes::IsLinkStarted(&data[0]); + */ + + /** + * Did the user drop the dragged link before attaching it to a pin? + * There are two different kinds of situations to consider when handling this event: + * 1) a link which is created at a pin and then dropped + * 2) an existing link which is detached from a pin and then dropped + * Use the including_detached_links flag to control whether this function triggers when the user + * detaches a link and drops it. + */ + public static boolean isLinkDropped(final ImInt startedAtAttributeId, final boolean includingDetachedLinks) { + return nIsLinkDropped(startedAtAttributeId.getData(), includingDetachedLinks); + } + + private static native boolean nIsLinkDropped(int[] data, boolean includingDetachedLinks); /* + return imnodes::IsLinkDropped(&data[0], includingDetachedLinks); + */ + + /** + * Did the user finish creating a new link? + */ + public static boolean isLinkCreated(final ImInt startedAtAttributeId, final ImInt endedAtAttributeId) { + return nIsLinkCreated(startedAtAttributeId.getData(), endedAtAttributeId.getData()); + } + + private static native boolean nIsLinkCreated(int[] sourceAttribute, int[] targetAttribute); /* + return imnodes::IsLinkCreated(&sourceAttribute[0], &targetAttribute[0]); + */ + + public static boolean isLinkCreated(final ImInt startedAtNodeId, final ImInt startedAtAttributeId, + final ImInt endedAtNodeId, final ImInt endedAtAttributeId, + final ImBoolean createdFromSnap) { + return nIsLinkCreated(startedAtNodeId.getData(), startedAtAttributeId.getData(), endedAtNodeId.getData(), endedAtAttributeId.getData(), createdFromSnap.getData()); + } + + private static native boolean nIsLinkCreated(int[] startedAtNodeId, int[] startedAtAttributeId, int[] endedAtNodeId, int[] endedAtAttributeId, boolean[] createdFromSnap); /* + return imnodes::IsLinkCreated(&startedAtNodeId[0], &startedAtAttributeId[0], &endedAtNodeId[0], &endedAtAttributeId[0], &createdFromSnap[0]); + */ + + /** + * Was an existing link detached from a pin by the user? The detached link's id is assigned to the + * output argument link_id. + */ + public static boolean isLinkDestroyed(final ImInt linkId) { + return nIsLinkDestroyed(linkId.getData()); + } + + private static native boolean nIsLinkDestroyed(int[] linkId); /* + return imnodes::IsLinkDestroyed(&linkId[0]); + */ + + /** + * Use The following two functions to query the number of selected nodes or links in the current + * editor. Use after calling EndNodeEditor(). + */ + public static native int numSelectedNodes(); /* + return imnodes::NumSelectedNodes(); + */ + + public static native int numSelectedLinks(); /* + return imnodes::NumSelectedLinks(); + */ + + /** + * Get the selected node/link ids. The pointer argument should point to an integer array with at + * least as many elements as the respective NumSelectedNodes/NumSelectedLinks function call + * returned. + */ + public static native void getSelectedNodes(int[] nodeIds); /* + imnodes::GetSelectedNodes(&nodeIds[0]); + */ + + public static native void getSelectedLinks(int[] linkIds); /* + imnodes::GetSelectedLinks(&linkIds[0]); + */ + + /** + * Clears the list of selected nodes/links. Useful if you want to delete a selected node or link. + */ + public static native void clearNodeSelection(); /* + imnodes::ClearNodeSelection(); + */ + + public static native void clearLinkSelection(); /* + imnodes::ClearLinkSelection(); + */ + + + /** + * Enable or disable the ability to click and drag a specific node. + */ + public static native void setNodeDraggable(int node, boolean isDraggable); /* + imnodes::SetNodeDraggable(node, isDraggable); + */ + + public static native void getNodeDimensions(int node, ImVec2 result); /* + ImVec2 dst = imnodes::GetNodeDimensions(node); + Jni::ImVec2Cpy(env, &dst, result); + */ + + public static native float getNodeDimensionsX(int node); /* + return imnodes::GetNodeDimensions(node).x; + */ + + public static native float getNodeDimensionsY(int node); /* + return imnodes::GetNodeDimensions(node).y; + */ + + + // The node's position can be expressed in three coordinate systems: + // * screen space coordinates, -- the origin is the upper left corner of the window. + // * editor space coordinates -- the origin is the upper left corner of the node editor window + // * grid space coordinates, -- the origin is the upper left corner of the node editor window, + // translated by the current editor panning vector (see EditorContextGetPanning() and + // EditorContextResetPanning()) + // Use the following functions to get and set the node's coordinates in these coordinate systems. + + public static native void setNodeScreenSpacePos(int node, float x, float y); /* + imnodes::SetNodeScreenSpacePos(node, ImVec2(x, y)); + */ + + public static native void setNodeEditorSpacePos(int node, float x, float y); /* + imnodes::SetNodeEditorSpacePos(node, ImVec2(x, y)); + */ + + public static native void setNodeGridSpacePos(int node, float x, float y); /* + imnodes::SetNodeGridSpacePos(node, ImVec2(x, y)); + */ + + public static native void getNodeScreenSpacePos(int node, ImVec2 result); /* + ImVec2 dst = imnodes::GetNodeScreenSpacePos(node); + Jni::ImVec2Cpy(env, &dst, result); + */ + + public static native float getNodeScreenSpacePosX(int node); /* + return imnodes::GetNodeScreenSpacePos(node).x; + */ + + public static native float getNodeScreenSpacePosY(int node); /* + return imnodes::GetNodeScreenSpacePos(node).y; + */ + + public static native void getNodeEditorSpacePos(int node, ImVec2 result); /* + ImVec2 dst = imnodes::GetNodeEditorSpacePos(node); + Jni::ImVec2Cpy(env, &dst, result); + */ + + public static native float getNodeEditorSpacePosX(int node); /* + return imnodes::GetNodeEditorSpacePos(node).x; + */ + + public static native float getNodeEditorSpacePosY(int node); /* + return imnodes::GetNodeEditorSpacePos(node).y; + */ + + public static native void getNodeGridSpacePos(int node, ImVec2 dst); /* + ImVec2 result = imnodes::GetNodeGridSpacePos(node); + Jni::ImVec2Cpy(env, &result, dst); + */ + + public static native float getNodeGridSpacePosX(int node); /* + return imnodes::GetNodeGridSpacePos(node).x; + */ + + public static native float getNodeGridSpacePosY(int node); /* + return imnodes::GetNodeGridSpacePos(node).y; + */ + + public static native void editorResetPanning(float x, float y); /* + imnodes::EditorContextResetPanning(ImVec2(x, y)); + */ + + public static native void editorMoveToNode(int node); /* + imnodes::EditorContextMoveToNode(node); + */ + + // Use the following functions to write the editor context's state to a string, or directly to a + // file. The editor context is serialized in the INI file format. + + public static native String saveCurrentEditorStateToIniString(); /* + return env->NewStringUTF(imnodes::SaveCurrentEditorStateToIniString(NULL)); + */ + + public static String saveEditorStateToIniString(final ImNodesContext context) { + return nSaveEditorStateToIniString(context.ptr); + } + + private static native String nSaveEditorStateToIniString(long context); /* + return env->NewStringUTF(imnodes::SaveEditorStateToIniString((imnodes::EditorContext*)context, NULL)); + */ + + public static native void loadCurrentEditorStateFromIniString(String data, int dataSize); /* + imnodes::LoadCurrentEditorStateFromIniString(data, dataSize); + */ + + public static void loadEditorStateFromIniString(final ImNodesContext context, final String data, final int dataSize) { + nLoadEditorStateFromIniString(context.ptr, data, dataSize); + } + + private static native void nLoadEditorStateFromIniString(long context, String data, int dataSize); /* + imnodes::LoadEditorStateFromIniString((imnodes::EditorContext*)context, data, dataSize); + */ + + public static native void saveCurrentEditorStateToIniFile(String fileName); /* + imnodes::SaveCurrentEditorStateToIniFile(fileName); + */ + + public static void saveEditorStateToIniFile(final ImNodesContext context, final String fileName) { + nSaveEditorStateToIniFile(context.ptr, fileName); + } + + private static native void nSaveEditorStateToIniFile(long context, String fileName); /* + imnodes::SaveEditorStateToIniFile((imnodes::EditorContext*)context, fileName); + */ + + public static native void loadCurrentEditorStateFromIniFile(String fileName); /* + imnodes::LoadCurrentEditorStateFromIniFile(fileName); + */ + + public static void loadEditorStateFromIniFile(final ImNodesContext context, final String fileName) { + nLoadEditorStateFromIniFile(context.ptr, fileName); + } + + private static native void nLoadEditorStateFromIniFile(long context, String fileName); /* + imnodes::LoadEditorStateFromIniFile((imnodes::EditorContext*)context, fileName); + */ + +} diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesAttributeFlags.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesAttributeFlags.java new file mode 100644 index 0000000..bb6d01b --- /dev/null +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesAttributeFlags.java @@ -0,0 +1,28 @@ +package imgui.imnodes; + +/** + * This enum controls the way the attribute pins behave. + */ +public final class ImNodesAttributeFlags { + + private ImNodesAttributeFlags() { + } + + public static final int None = 0; + + /** + * Allow detaching a link by left-clicking and dragging the link at a pin it is connected to. + * NOTE: the user has to actually delete the link for this to work. A deleted link can be + * detected by calling IsLinkDestroyed() after EndNodeEditor(). + */ + public static final int EnableLinkDetachWithDragClick = 1 << 0; + + /** + * Visual snapping of an in progress link will trigger IsLink Created/Destroyed events. Allows + * for previewing the creation of a link while dragging it across attributes. See here for demo: + * https://github.com/Nelarius/imnodes/issues/41#issuecomment-647132113 NOTE: the user has to + * actually delete the link for this to work. A deleted link can be detected by calling + * IsLinkDestroyed() after EndNodeEditor(). + */ + public static final int EnableLinkCreationOnSnap = 1 << 1; +} diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesColorStyle.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesColorStyle.java new file mode 100644 index 0000000..56612fa --- /dev/null +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesColorStyle.java @@ -0,0 +1,25 @@ +package imgui.imnodes; + +public final class ImNodesColorStyle { + + private ImNodesColorStyle() { + } + + public static final int NodeBackground = 0; + public static final int NodeBackgroundHovered = 1; + public static final int NodeBackgroundSelected = 2; + public static final int NodeOutline = 3; + public static final int TitleBar = 4; + public static final int TitleBarHovered = 5; + public static final int TitleBarSelected = 6; + public static final int Link = 7; + public static final int LinkHovered = 8; + public static final int LinkSelected = 9; + public static final int Pin = 10; + public static final int PinHovered = 11; + public static final int BoxSelector = 12; + public static final int BoxSelectorOutline = 13; + public static final int GridBackground = 14; + public static final int GridLine = 15; + +} diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesContext.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesContext.java new file mode 100644 index 0000000..e4616c7 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesContext.java @@ -0,0 +1,43 @@ +package imgui.imnodes; + +import imgui.binding.ImGuiStructDestroyable; + +public final class ImNodesContext extends ImGuiStructDestroyable { + + /*JNI + #include + #include + #include + #include "jni_common.h" + #include "jni_binding_struct.h" + + #define IMNODES_CONTEXT ((imnodes::EditorContext*)STRUCT_PTR) + */ + + public ImNodesContext() { + super(); + } + + public ImNodesContext(final long ptr) { + super(ptr); + } + + @Override + protected long create() { + return nCreate(); + } + + @Override + public void destroy() { + nDestroy(); + } + + private native long nCreate(); /* + return (jlong)imnodes::EditorContextCreate(); + */ + + private native void nDestroy(); /* + imnodes::EditorContextFree(IMNODES_CONTEXT); + */ + +} diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesPinShape.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesPinShape.java new file mode 100644 index 0000000..1f08e41 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesPinShape.java @@ -0,0 +1,17 @@ +package imgui.imnodes; + +/** + * This enum controls the way attribute pins look. + */ +public final class ImNodesPinShape { + + private ImNodesPinShape() { + } + + public static final int Circle = 0; + public static final int CircleFilled = 1; + public static final int Triangle = 2; + public static final int TriangleFilled = 3; + public static final int Quad = 4; + public static final int QuadFilled = 5; +} diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleVar.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleVar.java new file mode 100644 index 0000000..c454270 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleVar.java @@ -0,0 +1,22 @@ +package imgui.imnodes; + +public final class ImNodesStyleVar { + + private ImNodesStyleVar() { + } + + public static final int GridSpacing = 0; + public static final int NodeCornerRounding = 1; + public static final int NodePaddingHorizontal = 2; + public static final int NodePaddingVertical = 3; + public static final int NodeBorderThickness = 4; + public static final int LinkThickness = 5; + public static final int LinkLineSegmentsPerLength = 6; + public static final int LinkHoverDistance = 7; + public static final int PinCircleRadius = 8; + public static final int PinQuadSideLength = 9; + public static final int PinTriangleSideLength = 10; + public static final int PinLineThickness = 11; + public static final int PinHoverRadius = 12; + public static final int PinOffset = 13; +} diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditor.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditor.java new file mode 100644 index 0000000..b7835be --- /dev/null +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditor.java @@ -0,0 +1,548 @@ +package imgui.nodeditor; + +import imgui.ImDrawList; +import imgui.ImVec2; +import imgui.type.ImLong; + +/** + * Bindings for Imgui Node Editor (https://github.com/thedmd/imgui-node-editor) + * Original library author - Michał Cichoń (https://github.com/thedmd) + * + * An implementation of node editor with ImGui-like API. + * Project purpose is to serve as a basis for more complex solutions like blueprint editors. + * + * Refer to the library's Github page for examples and support + * + * Before you can start drawing editor you have to create ImNodeEditorContext + * (either by invoking constructor directly or using ImNodeEditor.createEditor()) and switch + * current editor via ImNodeEditor.setCurrentEditor(NodeEditorContext) + * + * Binding notice: instead of special types for ids of nodes, links and pins which used in native library + * we use longs to reduce boilerplate and garbage production + */ +public final class ImNodeEditor { + + private static final ImDrawList HINT_FOREGROUND_DRAW_LIST; + private static final ImDrawList HINT_BACKGROUND_DRAW_LIST; + private static final ImDrawList NODE_BACKGROUND_DRAW_LIST; + + static { + HINT_FOREGROUND_DRAW_LIST = new ImDrawList(0); + HINT_BACKGROUND_DRAW_LIST = new ImDrawList(0); + NODE_BACKGROUND_DRAW_LIST = new ImDrawList(0); + } + + private ImNodeEditor() { } + + /*JNI + #pragma warning (disable:4244) + + #include + #include + #include + #include "jni_common.h" + #include "jni_binding_struct.h" + + namespace ed = ax::NodeEditor; + */ + + + /** + * This method exists for api consistency and you can just call NodeEditorContext manually + */ + public static ImNodeEditorContext createEditor() { + return new ImNodeEditorContext(); + } + + /** + * This method exists for api consistency and you can just call NodeEditorContext.destroy() manually + */ + public static void destroyEditor(final ImNodeEditorContext editorContext) { + editorContext.destroy(); + } + + public static void setCurrentEditor(final ImNodeEditorContext editorContext) { + nSetCurrentEditor(editorContext.ptr); + } + + private static native void nSetCurrentEditor(long editor); /* + ed::SetCurrentEditor((ed::EditorContext*)editor); + */ + + public static native void begin(String title); /* + ed::Begin(title); + */ + + public static native void beginNode(long id); /* + ed::BeginNode(id); + */ + + public static native void group(float w, float h); /* + ed::Group(ImVec2(w, h)); + */ + + public static native boolean beginGroupHint(long id); /* + return ed::BeginGroupHint(id); + */ + + + public static native void beginPin(long pin, int imNodeEditorPinKind); /* + ed::BeginPin(pin, (ed::PinKind)imNodeEditorPinKind); + */ + + public static native void endGroupHint(); /* + ed::EndGroupHint(); + */ + + public static native void endPin(); /* + ed::EndPin(); + */ + + public static native void endNode(); /* + ed::EndNode(); + */ + + public static native void end(); /* + ed::End(); + */ + + public static native float getScreenSizeX(); /* + return ed::GetScreenSize().x; + */ + + public static native float getScreenSizeY(); /* + return ed::GetScreenSize().y; + */ + + public static native float toCanvasX(float screenSpacePosX); /* + return ed::ScreenToCanvas(ImVec2(screenSpacePosX, 0.0f)).x; + */ + + public static native float toCanvasY(float screenSpacePosY); /* + return ed::ScreenToCanvas(ImVec2(0.0f, screenSpacePosY)).y; + */ + + public static native float toScreenX(float canvasSpacePosX); /* + return ed::CanvasToScreen(ImVec2(canvasSpacePosX, 0.0f)).x; + */ + + public static native float toScreenY(float canvasSpacePosY); /* + return ed::CanvasToScreen(ImVec2(0.0f, canvasSpacePosY)).y; + */ + + public static native String getStyleColorName(int imNodeEditorStyleColor); /* + return env->NewStringUTF(ed::GetStyleColorName((ed::StyleColor)imNodeEditorStyleColor)); + */ + + public static native void pushStyleColor(int imNodeEditorStyleColor, float r, float g, float b, float a); /* + ed::PushStyleColor((ed::StyleColor)imNodeEditorStyleColor, ImVec4(r, g, b, a)); + */ + + public static native void popStyleColor(int count); /* + ed::PopStyleColor(count); + */ + + public static native void pushStyleVar(int imNodeEditorStyleVar, float v); /* + ed::PushStyleVar((ed::StyleVar)imNodeEditorStyleVar, v); + */ + + public static native void pushStyleVar(int imNodeEditorStyleVar, float x, float y); /* + ed::PushStyleVar((ed::StyleVar)imNodeEditorStyleVar, ImVec2(x, y)); + */ + + public static native void pushStyleVar(int imNodeEditorStyleVar, float r, float g, float b, float a); /* + ed::PushStyleVar((ed::StyleVar)imNodeEditorStyleVar, ImVec4(r, g, b, a)); + */ + + public static native void popStyleVar(int count); /* + ed::PopStyleVar(count); + */ + + + public static native float getGroupMinX(); /* + return ed::GetGroupMin().x; + */ + + public static native float getGroupMinY(); /* + return ed::GetGroupMin().y; + */ + + public static native float getGroupMaxX(); /* + return ed::GetGroupMax().x; + */ + + public static native float getGroupMaxY(); /* + return ed::GetGroupMax().y; + */ + + /** + * Binding notice: both getHintForegroundDrawList(), getHintBackgroundDrawList() and getNodeBackgroundDrawList(long) + * return singleton objects which shouldn't be used outside of the scope of current hint/node + */ + + public static ImDrawList getHintForegroundDrawList() { + HINT_FOREGROUND_DRAW_LIST.ptr = nGetHintForegroundDrawList(); + return HINT_FOREGROUND_DRAW_LIST; + } + + public static ImDrawList getHintBackgroundDrawList() { + HINT_BACKGROUND_DRAW_LIST.ptr = nGetHintBackgroundDrawList(); + return HINT_BACKGROUND_DRAW_LIST; + } + + public static ImDrawList getNodeBackgroundDrawList(final long nodeId) { + final long ptr = nGetNodeBackgroundDrawList(nodeId); + if (ptr == 0L) { + return null; + } else { + NODE_BACKGROUND_DRAW_LIST.ptr = ptr; + return NODE_BACKGROUND_DRAW_LIST; + } + } + + private static native long nGetHintForegroundDrawList(); /* + return (jlong)(intptr_t)ed::GetHintForegroundDrawList(); + */ + + private static native long nGetHintBackgroundDrawList(); /* + return (jlong)(intptr_t)ed::GetHintBackgroundDrawList(); + */ + + private static native long nGetNodeBackgroundDrawList(long nodeId); /* + return (jlong)(intptr_t)ed::GetNodeBackgroundDrawList(nodeId); + */ + + public static native long getDoubleClickedNode(); /* + return (jlong)(uintptr_t)ed::GetDoubleClickedNode(); + */ + + public static native long getDoubleClickedPin(); /* + return (jlong)(uintptr_t)ed::GetDoubleClickedPin(); + */ + + public static native long getDoubleClickedLink(); /* + return (jlong)(uintptr_t)ed::GetDoubleClickedLink(); + */ + + public static native boolean isBackgroundClicked(); /* + return ed::IsBackgroundClicked(); + */ + + public static native boolean isBackgroundDoubleClicked(); /* + return ed::IsBackgroundDoubleClicked(); + */ + + public static native boolean pinHadAnyLinks(long pinId); /* + return ed::PinHadAnyLinks(pinId); + */ + + public static native float getCurrentZoom(); /* + return ed::GetCurrentZoom(); + */ + + public static native void pinRect(float x, float y, float w, float h); /* + ed::PinRect(ImVec2(x, y), ImVec2(w, h)); + */ + + public static native void pinPivotRect(float x, float y, float w, float h); /* + ed::PinPivotRect(ImVec2(x, y), ImVec2(w, h)); + */ + + public static native void pinPivotSize(float w, float h); /* + ed::PinPivotSize(ImVec2(w, h)); + */ + + public static native void pinPivotScale(float w, float h); /* + ed::PinPivotScale(ImVec2(w, h)); + */ + + public static native void pinPivotAlignment(float x, float y); /* + ed::PinPivotAlignment(ImVec2(x, y)); + */ + + public static boolean showNodeContextMenu(final ImLong nodeId) { + return nShowNodeContextMenu(nodeId.getData()); + } + + public static boolean showPinContextMenu(final ImLong pinId) { + return nShowPinContextMenu(pinId.getData()); + } + + public static boolean showLinkContextMenu(final ImLong linkId) { + return nShowLinkContextMenu(linkId.getData()); + } + + /** + * Binding notice: getNodeWithContextMenu(), getPinWithContextMenu() and getLinkWithContextMenu() + * return id of the object for which context menu should be shown. If there is no such object -1 will be returned. + * + * These methods implemented as convenient alternative to showNodeContextMenu(ImLong), showPinContextMenu(ImLong) and + * showLinkContextMenu(ImLong) + */ + + public static native long getNodeWithContextMenu(); /* + ed::NodeId id; + return ed::ShowNodeContextMenu(&id) ? (jlong)(uintptr_t)id : -1; + */ + + public static native long getPinWithContextMenu(); /* + ed::PinId id; + return ed::ShowPinContextMenu(&id) ? (jlong)(uintptr_t)id : -1; + */ + + public static native long getLinkWithContextMenu(); /* + ed::LinkId id; + return ed::ShowLinkContextMenu(&id) ? (jlong)(uintptr_t)id : -1; + */ + + private static native boolean nShowNodeContextMenu(long[] nodeId); /* + return ed::ShowNodeContextMenu((ed::NodeId*)&nodeId[0]); + */ + + private static native boolean nShowPinContextMenu(long[] pinId); /* + return ed::ShowPinContextMenu((ed::PinId*)&pinId[0]); + */ + + private static native boolean nShowLinkContextMenu(long[] linkId); /* + return ed::ShowLinkContextMenu((ed::LinkId*)&linkId[0]); + */ + + public static native boolean showBackgroundContextMenu(); /* + return ed::ShowBackgroundContextMenu(); + */ + + public static native void restoreNodeState(long node); /* + ed::RestoreNodeState(node); + */ + + public static native void suspend(); /* + ed::Suspend(); + */ + + public static native void resume(); /* + ed::Resume(); + */ + + public static native boolean isSuspended(); /* + return ed::IsSuspended(); + */ + + public static native boolean isActive(); /* + return ed::IsActive(); + */ + + public static native void setNodePosition(long node, float x, float y); /* + ed::SetNodePosition(node, ImVec2(x, y)); + */ + + public static void link(final long id, final long startPinId, final long endPinId) { + link(id, startPinId, endPinId, 1F, 1F, 1F, 1F, 1F); + } + + public static native void link(long id, long startPinId, long endPinId, float r, float g, float b, float a, + float thickness); /* + ed::Link(id, startPinId, endPinId, ImVec4(r, g, b, a), thickness); + */ + + public static native void flow(long linkId); /* + ed::Flow(linkId); + */ + + public static boolean beginCreate() { + return beginCreate(1F, 1F, 1F, 1F, 1F); + } + + public static native boolean beginCreate(float r, float g, float b, float a, float thickness); /* + return ed::BeginCreate(ImVec4(r, g, b, a), thickness); + */ + + public static boolean queryNewLink(final ImLong startId, final ImLong endId) { + return nQueryNewLink(startId.getData(), endId.getData(), 1F, 1F, 1F, 1F, 1F); + } + + public static boolean queryNewLink(final ImLong startId, final ImLong endId, final float r, final float g, final float b, final float a, final float thickness) { + return nQueryNewLink(startId.getData(), endId.getData(), r, g, b, a, thickness); + } + + private static native boolean nQueryNewLink(long[] startId, long[] endId, float r, float g, float b, float a, float thickness); /* + return ed::QueryNewLink((ed::PinId*)&startId[0], (ed::PinId*)&endId[0], ImVec4(r, g, b, a), thickness); + */ + + public static boolean acceptNewItem() { + return acceptNewItem(1F, 1F, 1F, 1F, 1F); + } + + public static native boolean acceptNewItem(float r, float g, float b, float a, float thickness); /* + return ed::AcceptNewItem(ImVec4(r, g, b, a), thickness); + */ + + public static void rejectNewItem() { + rejectNewItem(1F, 1F, 1F, 1F, 1F); + } + + public static native void rejectNewItem(float r, float g, float b, float a, float thickness); /* + ed::RejectNewItem(ImVec4(r, g, b, a), thickness); + */ + + public static native void endCreate(); /* + ed::EndCreate(); + */ + + public static native boolean beginDelete(); /* + return ed::BeginDelete(); + */ + + public static boolean queryDeletedLink(final ImLong linkId, final ImLong startId, final ImLong endId) { + return nQueryDeletedLink(linkId.getData(), startId.getData(), endId.getData()); + } + + private static native boolean nQueryDeletedLink(long[] linkId, long[] startId, long[] endId); /* + return ed::QueryDeletedLink((ed::LinkId*)&linkId[0], (ed::PinId*)&startId[0], (ed::PinId*)&endId[0]); + */ + + public static boolean queryDeletedNode(final ImLong nodeId) { + return nQueryDeletedNode(nodeId.getData()); + } + + private static native boolean nQueryDeletedNode(long[] nodeId); /* + return ed::QueryDeletedNode((ed::NodeId*)&nodeId[0]); + */ + + public static native boolean acceptDeletedItem(); /* + return ed::AcceptDeletedItem(); + */ + + public static native void rejectDeletedItem(); /* + ed::RejectDeletedItem(); + */ + + public static native void endDelete(); /* + ed::EndDelete(); + */ + + public static native void navigateToContent(float duration); /* + ed::NavigateToContent(duration); + */ + + public static native void navigateToSelection(boolean zoomIn, float duration); /* + ed::NavigateToSelection(zoomIn, duration); + */ + + public static native void getNodePosition(long node, ImVec2 dst); /* + ImVec2 result = ed::GetNodePosition(node); + Jni::ImVec2Cpy(env, &result, dst); + */ + + public static native float getNodePositionX(long node); /* + return ed::GetNodePosition(node).x; + */ + + public static native float getNodePositionY(long node); /* + return ed::GetNodePosition(node).y; + */ + + public static native float getNodeSizeX(long node); /* + return ed::GetNodeSize(node).x; + */ + + public static native float getNodeSizeY(long node); /* + return ed::GetNodeSize(node).y; + */ + + public static native void centerNodeOnScreen(long node); /* + ed::CenterNodeOnScreen(node); + */ + + public static native boolean hasSelectionChanged(); /* + return ed::HasSelectionChanged(); + */ + + public static native int getSelectedObjectCount(); /* + return ed::GetSelectedObjectCount(); + */ + + public static native int getSelectedNodes(long[] nodes, int size); /* + return ed::GetSelectedNodes((ed::NodeId*)&nodes[0], size); + */ + + public static native int getSelectedLinks(long[] links, int size); /* + return ed::GetSelectedLinks((ed::LinkId*)&links[0], size); + */ + + public static native void clearSelection(); /* + return ed::ClearSelection(); + */ + + public static native void selectNode(long id, boolean append); /* + ed::SelectNode(id, append); + */ + + public static native void selectLink(long id, boolean append); /* + ed::SelectLink(id, append); + */ + + public static native void deselectNode(long id); /* + ed::DeselectNode(id); + */ + + public static native void deselectLink(long id); /* + ed::DeselectLink(id); + */ + + public static native boolean deleteNode(long nodeId); /* + return ed::DeleteNode(nodeId); + */ + + public static native boolean deleteLink(long linkId); /* + return ed::DeleteLink(linkId); + */ + + public static native void enableShortcuts(boolean enable); /* + ed::EnableShortcuts(enable); + */ + + public static native boolean areShortcutsEnabled(); /* + return ed::AreShortcutsEnabled(); + */ + + public static native boolean beginShortcut(); /* + return ed::BeginShortcut(); + */ + + public static native boolean acceptCut(); /* + return ed::AcceptCut(); + */ + + public static native boolean acceptCopy(); /* + return ed::AcceptCopy(); + */ + + public static native boolean acceptPaste(); /* + return ed::AcceptPaste(); + */ + + public static native boolean acceptDuplicate(); /* + return ed::AcceptDuplicate(); + */ + + public static native boolean acceptCreateNode(); /* + return ed::AcceptCreateNode(); + */ + + public static native int getActionContextSize(); /* + return ed::GetActionContextSize(); + */ + + public static native int getActionContextNodes(long[] nodes, int size); /* + return ed::GetActionContextNodes((ed::NodeId*)&nodes[0], size); + */ + + public static native int getActionContextLinks(long[] links, int size); /* + return ed::GetActionContextLinks((ed::LinkId*)&links[0], size); + */ + + public static native void endShortcut(); /* + ed::EndShortcut(); + */ + +} diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorContext.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorContext.java new file mode 100644 index 0000000..4a3b362 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorContext.java @@ -0,0 +1,42 @@ +package imgui.nodeditor; + +import imgui.binding.ImGuiStructDestroyable; + +public final class ImNodeEditorContext extends ImGuiStructDestroyable { + + /*JNI + #include + #include + #include "jni_common.h" + #include "jni_binding_struct.h" + namespace ed = ax::NodeEditor; + + #define IM_NODE_EDITOR_CONTEXT ((ed::EditorContext*)STRUCT_PTR) + */ + + public ImNodeEditorContext() { + super(); + } + + public ImNodeEditorContext(final long ptr) { + super(ptr); + } + + @Override + protected long create() { + return nCreate(); + } + + @Override + public void destroy() { + nDestroyEditorContext(); + } + + private native long nCreate(); /* + return (jlong)ed::CreateEditor(); + */ + + private native void nDestroyEditorContext(); /* + ed::DestroyEditor(IM_NODE_EDITOR_CONTEXT); + */ +} diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorPinKind.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorPinKind.java new file mode 100644 index 0000000..15d9b34 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorPinKind.java @@ -0,0 +1,11 @@ +package imgui.nodeditor; + +public final class ImNodeEditorPinKind { + + private ImNodeEditorPinKind() { + } + + public static final int Input = 0; + public static final int Output = 1; + +} diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleColor.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleColor.java new file mode 100644 index 0000000..6d99ef6 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleColor.java @@ -0,0 +1,27 @@ +package imgui.nodeditor; + +public final class ImNodeEditorStyleColor { + + private ImNodeEditorStyleColor() { + } + + public static final int Bg = 0; + public static final int Grid = 1; + public static final int NodeBg = 2; + public static final int NodeBorder = 3; + public static final int HovNodeBorder = 4; + public static final int SelNodeBorder = 5; + public static final int NodeSelRect = 6; + public static final int NodeSelRectBorder = 7; + public static final int HovLinkBorder = 8; + public static final int SelLinkBorder = 9; + public static final int LinkSelRect = 10; + public static final int LinkSelRectBorder = 11; + public static final int PinRect = 12; + public static final int PinRectBorder = 13; + public static final int Flow = 14; + public static final int FlowMarker = 15; + public static final int GroupBg = 16; + public static final int GroupBorder = 17; + +} diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleVar.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleVar.java new file mode 100644 index 0000000..97a0672 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleVar.java @@ -0,0 +1,32 @@ +package imgui.nodeditor; + +public final class ImNodeEditorStyleVar { + + private ImNodeEditorStyleVar() { + } + + public static final int NodePadding = 0; + public static final int NodeRounding = 1; + public static final int NodeBorderWidth = 2; + public static final int HoveredNodeBorderWidth = 3; + public static final int SelectedNodeBorderWidth = 4; + public static final int PinRounding = 5; + public static final int PinBorderWidth = 6; + public static final int LinkStrength = 7; + public static final int SourceDirection = 8; + public static final int TargetDirection = 9; + public static final int ScrollDuration = 10; + public static final int FlowMarkerDistance = 11; + public static final int FlowSpeed = 12; + public static final int FlowDuration = 13; + public static final int PivotAlignment = 14; + public static final int PivotSize = 15; + public static final int PivotScale = 16; + public static final int PinCorners = 17; + public static final int PinRadius = 18; + public static final int PinArrowSize = 19; + public static final int PinArrowWidth = 20; + public static final int GroupRounding = 21; + public static final int GroupBorderWidth = 22; + +} diff --git a/imgui-lwjgl3/src/test/java/ExampleUi.java b/imgui-lwjgl3/src/test/java/ExampleUi.java index 727ac53..486b9d8 100644 --- a/imgui-lwjgl3/src/test/java/ExampleUi.java +++ b/imgui-lwjgl3/src/test/java/ExampleUi.java @@ -5,10 +5,18 @@ import imgui.flag.ImGuiDir; import imgui.flag.ImGuiInputTextFlags; import imgui.flag.ImGuiStyleVar; import imgui.flag.ImGuiWindowFlags; +import imgui.imnodes.ImNodes; +import imgui.imnodes.ImNodesContext; +import imgui.imnodes.ImNodesPinShape; +import imgui.nodeditor.ImNodeEditor; import imgui.internal.ImGui; import imgui.internal.flag.ImGuiDockNodeFlags; +import imgui.nodeditor.ImNodeEditorContext; +import imgui.nodeditor.ImNodeEditorPinKind; import imgui.type.ImBoolean; import imgui.ImColor; +import imgui.type.ImInt; +import imgui.type.ImLong; import imgui.type.ImString; import org.lwjgl.BufferUtils; @@ -17,8 +25,23 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; -import static org.lwjgl.opengl.GL32.*; +import static org.lwjgl.opengl.GL32.GL_CLAMP_TO_EDGE; +import static org.lwjgl.opengl.GL32.GL_LINEAR; +import static org.lwjgl.opengl.GL32.GL_RGBA; +import static org.lwjgl.opengl.GL32.GL_RGBA8; +import static org.lwjgl.opengl.GL32.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL32.GL_TEXTURE_MAG_FILTER; +import static org.lwjgl.opengl.GL32.GL_TEXTURE_MIN_FILTER; +import static org.lwjgl.opengl.GL32.GL_TEXTURE_WRAP_S; +import static org.lwjgl.opengl.GL32.GL_TEXTURE_WRAP_T; +import static org.lwjgl.opengl.GL32.GL_UNSIGNED_BYTE; +import static org.lwjgl.opengl.GL32.glBindTexture; +import static org.lwjgl.opengl.GL32.glGenTextures; +import static org.lwjgl.opengl.GL32.glTexImage2D; +import static org.lwjgl.opengl.GL32.glTexParameteri; @SuppressWarnings({"MagicNumber", "VisibilityModifier"}) final class ExampleUi { @@ -37,6 +60,8 @@ final class ExampleUi { // Toggles private final ImBoolean showBottomDockedWindow = new ImBoolean(true); private final ImBoolean showDemoWindow = new ImBoolean(); + private final ImBoolean showImNodesWindow = new ImBoolean(false); + private final ImBoolean showImNodeEditorWindow = new ImBoolean(false); // Attach image example private int dukeTexture = 0; @@ -46,7 +71,23 @@ final class ExampleUi { // To modify background color dynamically final float[] backgroundColor = new float[]{0.5f, 0, 0}; + // Context for imnodes example + private ImNodesContext imNodesContext; + + // Context for imgui-node-editor example + private ImNodeEditorContext imNodeEditorContext; + + // Graph used both for imnodes and imgui-node-editor demo + private final Graph graph = new Graph(); + void render() throws Exception { + if (imNodesContext == null) { + imNodesContext = new ImNodesContext(); + } + if (imNodeEditorContext == null) { + imNodeEditorContext = new ImNodeEditorContext(); + } + final int dockspaceId = ImGui.getID("MyDockSpace"); showDockSpace(dockspaceId); setupBottomDockedWindow(dockspaceId); @@ -57,7 +98,6 @@ final class ExampleUi { ImGui.setNextWindowPos(mainViewport.getWorkPosX() + 10, mainViewport.getWorkPosY() + 10, ImGuiCond.Once); ImGui.begin("Custom window"); // Start Custom window - showWindowImage(); showToggles(); @@ -80,6 +120,14 @@ final class ExampleUi { if (showDemoWindow.get()) { ImGui.showDemoWindow(showDemoWindow); } + + if (showImNodesWindow.get()) { + showImNodesWindow(); + } + + if (showImNodeEditorWindow.get()) { + showImNodeEditorWindow(); + } } private void showDockSpace(final int dockspaceId) { @@ -138,6 +186,8 @@ final class ExampleUi { private void showToggles() { ImGui.checkbox("Show Demo Window", showDemoWindow); ImGui.checkbox("Show Bottom Docked Window", showBottomDockedWindow); + ImGui.checkbox("Show demo for imnodes", showImNodesWindow); + ImGui.checkbox("Show demo for imgui-node-editor", showImNodeEditorWindow); if (ImGui.button("Reset Bottom Dock Window")) { isBottomDockedWindowInit = false; } @@ -190,6 +240,178 @@ final class ExampleUi { } } + private void showImNodesWindow() { + ImGui.setNextWindowSize(400F, 400F, ImGuiCond.Appearing); + ImGui.begin("Demo imnodes", showImNodesWindow); + + ImGui.text("This a demo graph editor for ImNodes"); + + + ImNodes.editorContextSet(imNodesContext); + ImNodes.beginNodeEditor(); + + for (Graph.GraphNode node : graph.nodes.values()) { + ImNodes.beginNode(node.nodeId); + + ImNodes.beginNodeTitleBar(); + ImGui.text(node.getName()); + ImNodes.endNodeTitleBar(); + + + ImNodes.beginInputAttribute(node.getInputPinId(), ImNodesPinShape.CircleFilled); + ImGui.text("In"); + ImNodes.endInputAttribute(); + + ImGui.sameLine(); + + ImNodes.beginOutputAttribute(node.getOutputPinId()); + ImGui.text("Out"); + ImNodes.endOutputAttribute(); + + ImNodes.endNode(); + } + + int uniqueLinkId = 1; + for (Graph.GraphNode node : graph.nodes.values()) { + if (graph.nodes.containsKey(node.outputNodeId)) { + ImNodes.link(uniqueLinkId++, node.getOutputPinId(), graph.nodes.get(node.outputNodeId).getInputPinId()); + } + } + + final boolean isEditorHovered = ImNodes.isEditorHovered(); + + ImNodes.endNodeEditor(); + final ImInt a = new ImInt(); + final ImInt b = new ImInt(); + if (ImNodes.isLinkCreated(a, b)) { + final Graph.GraphNode source = graph.findByOutput(a.get()); + final Graph.GraphNode target = graph.findByInput(b.get()); + if (source != null && target != null && source.outputNodeId != target.nodeId) { + source.outputNodeId = target.nodeId; + } + } + + if (ImGui.isMouseClicked(1)) { + final int hoveredNode = ImNodes.getHoveredNode(); + if (hoveredNode != -1) { + ImGui.openPopup("node-context"); + ImGui.getStateStorage().setInt(ImGui.getID("delete-node-id"), hoveredNode); + } else if (isEditorHovered) { + ImGui.openPopup("node-editor-context"); + } + } + + if (ImGui.isPopupOpen("node-context")) { + final int targetNode = ImGui.getStateStorage().getInt(ImGui.getID("delete-node-id")); + if (ImGui.beginPopup("node-context")) { + if (ImGui.button("Delete " + graph.nodes.get(targetNode).getName())) { + graph.nodes.remove(targetNode); + ImGui.closeCurrentPopup(); + } + ImGui.endPopup(); + } + } + + if (ImGui.beginPopup("node-editor-context")) { + if (ImGui.button("Create new node")) { + final Graph.GraphNode node = graph.createGraphNode(); + ImNodes.setNodeScreenSpacePos(node.nodeId, ImGui.getMousePosX(), ImGui.getMousePosY()); + ImGui.closeCurrentPopup(); + } + ImGui.endPopup(); + } + + ImGui.end(); + } + + private void showImNodeEditorWindow() { + ImGui.setNextWindowSize(400F, 400F, ImGuiCond.Appearing); + ImGui.begin("Demo imgui-node-editor", showImNodeEditorWindow); + + ImGui.text("This a demo graph editor for imgui-node-editor"); + + if (ImGui.button("Navigate to content")) { + ImNodeEditor.navigateToContent(1F); + } + + ImNodeEditor.setCurrentEditor(imNodeEditorContext); + ImNodeEditor.begin("Node Editor"); + + for (Graph.GraphNode node : graph.nodes.values()) { + ImNodeEditor.beginNode(node.nodeId); + + ImGui.text(node.getName()); + + ImNodeEditor.beginPin(node.getInputPinId(), ImNodeEditorPinKind.Input); + ImGui.text("-> In"); + ImNodeEditor.endPin(); + + ImGui.sameLine(); + + ImNodeEditor.beginPin(node.getOutputPinId(), ImNodeEditorPinKind.Output); + ImGui.text("Out ->"); + ImNodeEditor.endPin(); + + ImNodeEditor.endNode(); + } + + if (ImNodeEditor.beginCreate()) { + final ImLong a = new ImLong(); + final ImLong b = new ImLong(); + if (ImNodeEditor.queryNewLink(a, b)) { + final Graph.GraphNode source = graph.findByOutput(a.get()); + final Graph.GraphNode target = graph.findByInput(b.get()); + if (source != null && target != null && source.outputNodeId != target.nodeId && ImNodeEditor.acceptNewItem()) { + source.outputNodeId = target.nodeId; + } + } + } + ImNodeEditor.endCreate(); + + int uniqueLinkId = 1; + for (Graph.GraphNode node : graph.nodes.values()) { + if (graph.nodes.containsKey(node.outputNodeId)) { + ImNodeEditor.link(uniqueLinkId++, node.getOutputPinId(), graph.nodes.get(node.outputNodeId).getInputPinId()); + } + } + + ImNodeEditor.suspend(); + final long nodeWithContextMenu = ImNodeEditor.getNodeWithContextMenu(); + if (nodeWithContextMenu != -1) { + ImGui.openPopup("node-context"); + ImGui.getStateStorage().setInt(ImGui.getID("delete-node-id"), (int) nodeWithContextMenu); + } + + if (ImGui.isPopupOpen("node-context")) { + final int targetNode = ImGui.getStateStorage().getInt(ImGui.getID("delete-node-id")); + if (ImGui.beginPopup("node-context")) { + if (ImGui.button("Delete " + graph.nodes.get(targetNode).getName())) { + graph.nodes.remove(targetNode); + ImGui.closeCurrentPopup(); + } + ImGui.endPopup(); + } + } + + if (ImNodeEditor.showBackgroundContextMenu()) { + ImGui.openPopup("node-editor-context"); + } + if (ImGui.beginPopup("node-editor-context")) { + if (ImGui.button("Create new node")) { + final Graph.GraphNode node = graph.createGraphNode(); + final float canvasX = ImNodeEditor.toCanvasX(ImGui.getMousePosX()); + final float canvasY = ImNodeEditor.toCanvasY(ImGui.getMousePosY()); + ImNodeEditor.setNodePosition(node.nodeId, canvasX, canvasY); + ImGui.closeCurrentPopup(); + } + ImGui.endPopup(); + } + ImNodeEditor.resume(); + + ImNodeEditor.end(); + ImGui.end(); + } + private int loadTexture(final BufferedImage image) { final int[] pixels = new int[image.getWidth() * image.getHeight()]; image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); @@ -219,4 +441,72 @@ final class ExampleUi { return textureID; } + + + // Simple graph struct for both of node editors demos + private static final class Graph { + + private int nextNodeId = 1; + private int nextPinId = 100; + + final Map nodes = new HashMap<>(); + + private Graph() { + final GraphNode first = createGraphNode(); + final GraphNode second = createGraphNode(); + first.outputNodeId = second.nodeId; + } + + public GraphNode createGraphNode() { + final GraphNode node = new GraphNode(nextNodeId++, nextPinId++, nextPinId++); + this.nodes.put(node.nodeId, node); + return node; + } + + public GraphNode findByInput(final long inputPinId) { + for (GraphNode node : nodes.values()) { + if (node.getInputPinId() == inputPinId) { + return node; + } + } + return null; + } + + public GraphNode findByOutput(final long outputPinId) { + for (GraphNode node : nodes.values()) { + if (node.getOutputPinId() == outputPinId) { + return node; + } + } + return null; + } + + private static final class GraphNode { + private final int nodeId; + private final int inputPinId; + private final int outputPinId; + + public int outputNodeId = -1; + + private GraphNode(final int nodeId, final int inputPinId, final int outputPintId) { + this.nodeId = nodeId; + this.inputPinId = inputPinId; + this.outputPinId = outputPintId; + } + + public int getInputPinId() { + return inputPinId; + } + + public int getOutputPinId() { + return outputPinId; + } + + public String getName() { + return "Node " + (char) (64 + nodeId); + } + } + } + + } diff --git a/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java b/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java index 8e7bff7..7e6f83f 100644 --- a/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java +++ b/imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java @@ -1,5 +1,30 @@ import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks; -import static org.lwjgl.glfw.GLFW.*; +import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR; +import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR; +import static org.lwjgl.glfw.GLFW.GLFW_FALSE; +import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_CORE_PROFILE; +import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_FORWARD_COMPAT; +import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_PROFILE; +import static org.lwjgl.glfw.GLFW.GLFW_TRUE; +import static org.lwjgl.glfw.GLFW.GLFW_VISIBLE; +import static org.lwjgl.glfw.GLFW.glfwCreateWindow; +import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints; +import static org.lwjgl.glfw.GLFW.glfwDestroyWindow; +import static org.lwjgl.glfw.GLFW.glfwGetCurrentContext; +import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor; +import static org.lwjgl.glfw.GLFW.glfwGetVideoMode; +import static org.lwjgl.glfw.GLFW.glfwGetWindowSize; +import static org.lwjgl.glfw.GLFW.glfwInit; +import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent; +import static org.lwjgl.glfw.GLFW.glfwPollEvents; +import static org.lwjgl.glfw.GLFW.glfwSetErrorCallback; +import static org.lwjgl.glfw.GLFW.glfwSetWindowPos; +import static org.lwjgl.glfw.GLFW.glfwShowWindow; +import static org.lwjgl.glfw.GLFW.glfwSwapBuffers; +import static org.lwjgl.glfw.GLFW.glfwSwapInterval; +import static org.lwjgl.glfw.GLFW.glfwTerminate; +import static org.lwjgl.glfw.GLFW.glfwWindowHint; +import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose; import static org.lwjgl.opengl.GL32.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL32.GL_TRUE; import static org.lwjgl.opengl.GL32.glClear; @@ -22,6 +47,8 @@ import java.io.InputStream; import java.io.UncheckedIOException; import java.nio.IntBuffer; import java.util.Objects; + +import imgui.imnodes.ImNodes; import org.lwjgl.glfw.GLFWErrorCallback; import org.lwjgl.glfw.GLFWVidMode; import org.lwjgl.opengl.GL; @@ -60,6 +87,7 @@ public final class ImGuiGlfwExample { imGuiGl3.dispose(); imGuiGlfw.dispose(); + ImNodes.shutdown(); ImGui.destroyContext(); disposeWindow(); @@ -137,7 +165,7 @@ public final class ImGuiGlfwExample { // IMPORTANT!! // This line is critical for Dear ImGui to work. ImGui.createContext(); - + ImNodes.initialize(); // ------------------------------------------------------------ // Initialize ImGuiIO config final ImGuiIO io = ImGui.getIO(); diff --git a/imgui-node-editor b/imgui-node-editor new file mode 160000 index 0000000..687a72f --- /dev/null +++ b/imgui-node-editor @@ -0,0 +1 @@ +Subproject commit 687a72f940c76cf5064e13fe55fa0408c18fcbe4 diff --git a/imnodes b/imnodes new file mode 160000 index 0000000..5959729 --- /dev/null +++ b/imnodes @@ -0,0 +1 @@ +Subproject commit 595972941054e9fa453f5a6d5590a51c9e1c98a4 From 5beb896b506c91e7571cbc75328d1a647ea0a6eb Mon Sep 17 00:00:00 2001 From: SpaiR Date: Sat, 23 Jan 2021 15:14:49 +0200 Subject: [PATCH 2/3] [Binding] Fix ImNodes minor probs and add Style struct --- .../groovy/imgui/generate/GenerateLibs.groovy | 8 +- .../src/main/java/imgui/imnodes/ImNodes.java | 51 +++-- .../imgui/imnodes/ImNodesAttributeFlags.java | 2 +- .../java/imgui/imnodes/ImNodesColorStyle.java | 2 - .../java/imgui/imnodes/ImNodesContext.java | 18 +- .../java/imgui/imnodes/ImNodesPinShape.java | 1 - .../main/java/imgui/imnodes/ImNodesStyle.java | 175 ++++++++++++++++++ .../java/imgui/imnodes/ImNodesStyleFlags.java | 10 + .../java/imgui/imnodes/ImNodesStyleVar.java | 1 - imgui-lwjgl3/src/test/java/ExampleUi.java | 3 - 10 files changed, 233 insertions(+), 38 deletions(-) create mode 100644 imgui-binding/src/main/java/imgui/imnodes/ImNodesStyle.java create mode 100644 imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleFlags.java diff --git a/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy b/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy index e934916..a01e1c3 100644 --- a/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy +++ b/buildSrc/src/main/groovy/imgui/generate/GenerateLibs.groovy @@ -39,11 +39,9 @@ class GenerateLibs extends DefaultTask { // Copy ImGui h/cpp files project.copy { CopySpec spec -> - spec.from(project.rootProject.file('imgui')) { CopySpec it -> it.include('*.h', '*.cpp') } - - spec.from(project.rootProject.file('imnodes')) { CopySpec it -> it.include('*.h', '*.cpp') } - - spec.from(project.rootProject.file('imgui-node-editor')) { CopySpec it -> it.include('*.h', '*.cpp', '*.inl') } + ['imgui', 'imnodes', 'imgui-node-editor'].each { + spec.from(project.rootProject.file(it)) { CopySpec s -> s.include('*.h', '*.cpp', '*.inl') } + } if (withFreeType) { spec.from(project.rootProject.file('imgui/misc/freetype')) { CopySpec it -> it.include('*.h', '*.cpp') } diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodes.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodes.java index c4762e6..7fa1a6d 100644 --- a/imgui-binding/src/main/java/imgui/imnodes/ImNodes.java +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodes.java @@ -7,19 +7,20 @@ import imgui.type.ImInt; /** * Bindings for Imnodes (https://github.com/Nelarius/imnodes/) * Original library author - Johann Muszynski (https://github.com/Nelarius) - * + *

* Refer to the library's Github page for examples and support */ public final class ImNodes { + private static ImNodesStyle style; - private ImNodes() { } + private ImNodes() { + } /*JNI #include #include #include #include "jni_common.h" - #include "jni_binding_struct.h" */ // An editor context corresponds to a set of nodes in a single workspace (created with a single @@ -55,14 +56,30 @@ public final class ImNodes { imnodes::Shutdown(); */ + /** + * Returns the global style struct. See the struct declaration for default values. + */ + public static ImNodesStyle getStyle() { + if (style == null) { + style = new ImNodesStyle(nGetStyle()); + } + return style; + } + + private static native long nGetStyle(); /* + return (intptr_t)&imnodes::GetStyle(); + */ + // Style presets matching the dear imgui styles of the same name. public static native void styleColorsDark(); /* imnodes::StyleColorsDark(); */ + public static native void styleColorsClassic(); /* imnodes::StyleColorsClassic(); */ + public static native void styleColorsLight(); /* imnodes::StyleColorsLight(); */ @@ -137,7 +154,6 @@ public final class ImNodes { // // Each attribute id must be unique. - /** * Create a static attribute block. A static attribute has no pin, and therefore can't be linked to * anything. However, you can still use IsAttributeActive() and IsAnyAttributeActive() to check for @@ -196,25 +212,32 @@ public final class ImNodes { return imnodes::IsEditorHovered(); */ - /** - * Binding notice: getHoveredNode(), getHoveredLink() and getHoveredPin() - * return id of the hovered object. If there is no such object -1 will be returned. - * Use these functions after endNodeEditor() has been called. - * - * These methods implemented instead of the original bool imnodes::IsNodeHovered(int* node_id), - * bool imnodes::IsLinkHovered(int* link_id) and bool imnodes::IsPinHovered(int* attribute_id) for convenience. - */ + // Binding notice: getHoveredNode(), getHoveredLink() and getHoveredPin() + // return id of the hovered object. If there is no such object -1 will be returned. + // Use these functions after endNodeEditor() has been called. + // + // These methods implemented instead of the original bool imnodes::IsNodeHovered(int* node_id), + // bool imnodes::IsLinkHovered(int* link_id) and bool imnodes::IsPinHovered(int* attribute_id) for convenience. + /** + * @return id of the hovered node or -1 if there is no such object + */ public static native int getHoveredNode(); /* int i; return imnodes::IsNodeHovered(&i) ? i : -1; */ + /** + * @return id of the hovered link or -1 if there is no such object + */ public static native int getHoveredLink(); /* int i; return imnodes::IsLinkHovered(&i) ? i : -1; */ + /** + * @return id of the hovered pin or -1 if there is no such object + */ public static native int getHoveredPin(); /* int i; return imnodes::IsPinHovered(&i) ? i : -1; @@ -222,7 +245,7 @@ public final class ImNodes { /** * Binding notice: getActiveAttribute() returns id the active attribute. If there is no active attribute -1 will be returned. - * + *

* This method implemented instead of the original bool imnodes::IsAnyAttributeActive(int* attribute_id) for convenience. */ public static native int getActiveAttribute(); /* @@ -337,7 +360,6 @@ public final class ImNodes { imnodes::ClearLinkSelection(); */ - /** * Enable or disable the ability to click and drag a specific node. */ @@ -476,5 +498,4 @@ public final class ImNodes { private static native void nLoadEditorStateFromIniFile(long context, String fileName); /* imnodes::LoadEditorStateFromIniFile((imnodes::EditorContext*)context, fileName); */ - } diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesAttributeFlags.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesAttributeFlags.java index bb6d01b..16a464a 100644 --- a/imgui-binding/src/main/java/imgui/imnodes/ImNodesAttributeFlags.java +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesAttributeFlags.java @@ -15,7 +15,7 @@ public final class ImNodesAttributeFlags { * NOTE: the user has to actually delete the link for this to work. A deleted link can be * detected by calling IsLinkDestroyed() after EndNodeEditor(). */ - public static final int EnableLinkDetachWithDragClick = 1 << 0; + public static final int EnableLinkDetachWithDragClick = 1; /** * Visual snapping of an in progress link will trigger IsLink Created/Destroyed events. Allows diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesColorStyle.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesColorStyle.java index 56612fa..dc05874 100644 --- a/imgui-binding/src/main/java/imgui/imnodes/ImNodesColorStyle.java +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesColorStyle.java @@ -1,7 +1,6 @@ package imgui.imnodes; public final class ImNodesColorStyle { - private ImNodesColorStyle() { } @@ -21,5 +20,4 @@ public final class ImNodesColorStyle { public static final int BoxSelectorOutline = 13; public static final int GridBackground = 14; public static final int GridLine = 15; - } diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesContext.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesContext.java index e4616c7..cc7dece 100644 --- a/imgui-binding/src/main/java/imgui/imnodes/ImNodesContext.java +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesContext.java @@ -4,6 +4,13 @@ import imgui.binding.ImGuiStructDestroyable; public final class ImNodesContext extends ImGuiStructDestroyable { + public ImNodesContext() { + } + + public ImNodesContext(final long ptr) { + super(ptr); + } + /*JNI #include #include @@ -14,14 +21,6 @@ public final class ImNodesContext extends ImGuiStructDestroyable { #define IMNODES_CONTEXT ((imnodes::EditorContext*)STRUCT_PTR) */ - public ImNodesContext() { - super(); - } - - public ImNodesContext(final long ptr) { - super(ptr); - } - @Override protected long create() { return nCreate(); @@ -33,11 +32,10 @@ public final class ImNodesContext extends ImGuiStructDestroyable { } private native long nCreate(); /* - return (jlong)imnodes::EditorContextCreate(); + return (intptr_t)imnodes::EditorContextCreate(); */ private native void nDestroy(); /* imnodes::EditorContextFree(IMNODES_CONTEXT); */ - } diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesPinShape.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesPinShape.java index 1f08e41..38def36 100644 --- a/imgui-binding/src/main/java/imgui/imnodes/ImNodesPinShape.java +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesPinShape.java @@ -4,7 +4,6 @@ package imgui.imnodes; * This enum controls the way attribute pins look. */ public final class ImNodesPinShape { - private ImNodesPinShape() { } diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyle.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyle.java new file mode 100644 index 0000000..b5e94ef --- /dev/null +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyle.java @@ -0,0 +1,175 @@ +package imgui.imnodes; + +import imgui.binding.ImGuiStruct; + +public final class ImNodesStyle extends ImGuiStruct { + public ImNodesStyle(final long ptr) { + super(ptr); + } + + /*JNI + #include + #include + #include + #include "jni_common.h" + #include "jni_binding_struct.h" + + #define IMNODES_STYLE ((imnodes::Style*)STRUCT_PTR) + */ + + public native float getGridSpacing(); /* + return IMNODES_STYLE->grid_spacing; + */ + + public native void setGridSpacing(float gridSpacing); /* + IMNODES_STYLE->grid_spacing = gridSpacing; + */ + + public native float getNodeCornerRounding(); /* + return IMNODES_STYLE->node_corner_rounding; + */ + + public native void setNodeCornerRounding(float nodeCornerRounding); /* + IMNODES_STYLE->node_corner_rounding = nodeCornerRounding; + */ + + public native float getNodePaddingHorizontal(); /* + return IMNODES_STYLE->node_padding_horizontal; + */ + + public native void setNodePaddingHorizontal(float nodePaddingHorizontal); /* + IMNODES_STYLE->node_padding_horizontal = nodePaddingHorizontal; + */ + + public native float getNodePaddingVertical(); /* + return IMNODES_STYLE->node_padding_vertical; + */ + + public native void setNodePaddingVertical(float nodePaddingVertical); /* + IMNODES_STYLE->node_padding_vertical = nodePaddingVertical; + */ + + public native float getNodeBorderThickness(); /* + return IMNODES_STYLE->node_border_thickness; + */ + + public native void setNodeBorderThickness(float nodeBorderThickness); /* + IMNODES_STYLE->node_border_thickness = nodeBorderThickness; + */ + + public native float getLinkThickness(); /* + return IMNODES_STYLE->link_thickness; + */ + + public native void setLinkThickness(float linkThickness); /* + IMNODES_STYLE->link_thickness = linkThickness; + */ + + public native float getLinkLineSegmentsPerLength(); /* + return IMNODES_STYLE->link_line_segments_per_length; + */ + + public native void setLinkLineSegmentsPerLength(float linkLineSegmentsPerLength); /* + IMNODES_STYLE->link_line_segments_per_length = linkLineSegmentsPerLength; + */ + + public native float getLinkHoverDistance(); /* + return IMNODES_STYLE->link_hover_distance; + */ + + public native void setLinkHoverDistance(float linkHoverDistance); /* + IMNODES_STYLE->link_hover_distance = linkHoverDistance; + */ + + /** + * The circle radius used when the pin shape is either PinShape_Circle or PinShape_CircleFilled. + */ + public native float getPinCircleRadius(); /* + return IMNODES_STYLE->pin_circle_radius; + */ + + /** + * The circle radius used when the pin shape is either PinShape_Circle or PinShape_CircleFilled. + */ + public native void setPinCircleRadius(float pinCircleRadius); /* + IMNODES_STYLE->pin_circle_radius = pinCircleRadius; + */ + + /** + * The quad side length used when the shape is either PinShape_Quad or PinShape_QuadFilled. + */ + public native float getPinQuadSideLength(); /* + return IMNODES_STYLE->pin_quad_side_length; + */ + + /** + * The quad side length used when the shape is either PinShape_Quad or PinShape_QuadFilled. + */ + public native void setPinQuadSideLength(float pinQuadSideLength); /* + IMNODES_STYLE->pin_quad_side_length = pinQuadSideLength; + */ + + /** + * The equilateral triangle side length used when the pin shape is either PinShape_Triangle or PinShape_TriangleFilled. + */ + public native float getPinTriangleSideLength(); /* + return IMNODES_STYLE->pin_triangle_side_length; + */ + + /** + * The equilateral triangle side length used when the pin shape is either PinShape_Triangle or PinShape_TriangleFilled. + */ + public native void setPinTriangleSideLength(float pinTriangleSideLength); /* + IMNODES_STYLE->pin_triangle_side_length = pinTriangleSideLength; + */ + + /** + * The thickness of the line used when the pin shape is not filled. + */ + public native float getPinLineThickness(); /* + return IMNODES_STYLE->pin_line_thickness; + */ + + /** + * The thickness of the line used when the pin shape is not filled. + */ + public native void setPinLineThickness(float pinLineThickness); /* + IMNODES_STYLE->pin_line_thickness = pinLineThickness; + */ + + /** + * The radius from the pin's center position inside of which it is detected as being hovered over. + */ + public native float getPinHoverRadius(); /* + return IMNODES_STYLE->pin_hover_radius; + */ + + /** + * The radius from the pin's center position inside of which it is detected as being hovered over. + */ + public native void setPinHoverRadius(float pinHoverRadius); /* + IMNODES_STYLE->pin_hover_radius = pinHoverRadius; + */ + + /** + * Offsets the pins' positions from the edge of the node to the outside of the node. + */ + public native float getPinOffset(); /* + return IMNODES_STYLE->pin_offset; + */ + + /** + * Offsets the pins' positions from the edge of the node to the outside of the node. + */ + public native void setPinOffset(float pinOffset); /* + IMNODES_STYLE->pin_offset = pinOffset; + */ + + public native int getFlags(); /* + return IMNODES_STYLE->flags; + */ + + public native void setFlags(int imNodesStyleFlags); /* + IMNODES_STYLE->flags = (imnodes::StyleFlags)imNodesStyleFlags; + */ +} diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleFlags.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleFlags.java new file mode 100644 index 0000000..e3a9809 --- /dev/null +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleFlags.java @@ -0,0 +1,10 @@ +package imgui.imnodes; + +public final class ImNodesStyleFlags { + private ImNodesStyleFlags() { + } + + public static final int None = 0; + public static final int NodeOutline = 1; + public static final int GridLines = 1 << 2; +} diff --git a/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleVar.java b/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleVar.java index c454270..19bfbac 100644 --- a/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleVar.java +++ b/imgui-binding/src/main/java/imgui/imnodes/ImNodesStyleVar.java @@ -1,7 +1,6 @@ package imgui.imnodes; public final class ImNodesStyleVar { - private ImNodesStyleVar() { } diff --git a/imgui-lwjgl3/src/test/java/ExampleUi.java b/imgui-lwjgl3/src/test/java/ExampleUi.java index 486b9d8..d3580d0 100644 --- a/imgui-lwjgl3/src/test/java/ExampleUi.java +++ b/imgui-lwjgl3/src/test/java/ExampleUi.java @@ -246,7 +246,6 @@ final class ExampleUi { ImGui.text("This a demo graph editor for ImNodes"); - ImNodes.editorContextSet(imNodesContext); ImNodes.beginNodeEditor(); @@ -507,6 +506,4 @@ final class ExampleUi { } } } - - } From bb472b9fe9e308002629680ea0d7e4419b1f9aa7 Mon Sep 17 00:00:00 2001 From: SpaiR Date: Sat, 23 Jan 2021 16:04:49 +0200 Subject: [PATCH 3/3] [Binding] Fix ImNodeEditor minor probs and add Style and Config struct --- .../java/imgui/nodeditor/ImNodeEditor.java | 90 +++--- .../imgui/nodeditor/ImNodeEditorConfig.java | 41 +++ .../imgui/nodeditor/ImNodeEditorContext.java | 32 +- .../imgui/nodeditor/ImNodeEditorPinKind.java | 2 - .../imgui/nodeditor/ImNodeEditorStyle.java | 291 ++++++++++++++++++ .../nodeditor/ImNodeEditorStyleColor.java | 2 - .../imgui/nodeditor/ImNodeEditorStyleVar.java | 2 - imgui-lwjgl3/src/test/java/ExampleUi.java | 5 +- 8 files changed, 403 insertions(+), 62 deletions(-) create mode 100644 imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorConfig.java create mode 100644 imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyle.java diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditor.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditor.java index b7835be..4c802a9 100644 --- a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditor.java +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditor.java @@ -21,22 +21,16 @@ import imgui.type.ImLong; * we use longs to reduce boilerplate and garbage production */ public final class ImNodeEditor { + private static final ImDrawList HINT_FOREGROUND_DRAW_LIST = new ImDrawList(0); + private static final ImDrawList HINT_BACKGROUND_DRAW_LIST = new ImDrawList(0); + private static final ImDrawList NODE_BACKGROUND_DRAW_LIST = new ImDrawList(0); - private static final ImDrawList HINT_FOREGROUND_DRAW_LIST; - private static final ImDrawList HINT_BACKGROUND_DRAW_LIST; - private static final ImDrawList NODE_BACKGROUND_DRAW_LIST; + private static ImNodeEditorStyle style; - static { - HINT_FOREGROUND_DRAW_LIST = new ImDrawList(0); - HINT_BACKGROUND_DRAW_LIST = new ImDrawList(0); - NODE_BACKGROUND_DRAW_LIST = new ImDrawList(0); + private ImNodeEditor() { } - private ImNodeEditor() { } - /*JNI - #pragma warning (disable:4244) - #include #include #include @@ -46,7 +40,6 @@ public final class ImNodeEditor { namespace ed = ax::NodeEditor; */ - /** * This method exists for api consistency and you can just call NodeEditorContext manually */ @@ -54,6 +47,10 @@ public final class ImNodeEditor { return new ImNodeEditorContext(); } + public static ImNodeEditorContext createEditor(final ImNodeEditorConfig config) { + return new ImNodeEditorContext(config); + } + /** * This method exists for api consistency and you can just call NodeEditorContext.destroy() manually */ @@ -130,6 +127,17 @@ public final class ImNodeEditor { return ed::CanvasToScreen(ImVec2(0.0f, canvasSpacePosY)).y; */ + public static ImNodeEditorStyle getStyle() { + if (style == null) { + style = new ImNodeEditorStyle(nGetStyle()); + } + return style; + } + + private static native long nGetStyle(); /* + return (intptr_t)&ed::GetStyle(); + */ + public static native String getStyleColorName(int imNodeEditorStyleColor); /* return env->NewStringUTF(ed::GetStyleColorName((ed::StyleColor)imNodeEditorStyleColor)); */ @@ -158,7 +166,6 @@ public final class ImNodeEditor { ed::PopStyleVar(count); */ - public static native float getGroupMinX(); /* return ed::GetGroupMin().x; */ @@ -192,7 +199,7 @@ public final class ImNodeEditor { public static ImDrawList getNodeBackgroundDrawList(final long nodeId) { final long ptr = nGetNodeBackgroundDrawList(nodeId); - if (ptr == 0L) { + if (ptr == 0) { return null; } else { NODE_BACKGROUND_DRAW_LIST.ptr = ptr; @@ -201,27 +208,27 @@ public final class ImNodeEditor { } private static native long nGetHintForegroundDrawList(); /* - return (jlong)(intptr_t)ed::GetHintForegroundDrawList(); + return (intptr_t)(uintptr_t)ed::GetHintForegroundDrawList(); */ private static native long nGetHintBackgroundDrawList(); /* - return (jlong)(intptr_t)ed::GetHintBackgroundDrawList(); + return (intptr_t)(uintptr_t)ed::GetHintBackgroundDrawList(); */ private static native long nGetNodeBackgroundDrawList(long nodeId); /* - return (jlong)(intptr_t)ed::GetNodeBackgroundDrawList(nodeId); + return (intptr_t)(uintptr_t)ed::GetNodeBackgroundDrawList(nodeId); */ public static native long getDoubleClickedNode(); /* - return (jlong)(uintptr_t)ed::GetDoubleClickedNode(); + return (intptr_t)(uintptr_t)ed::GetDoubleClickedNode(); */ public static native long getDoubleClickedPin(); /* - return (jlong)(uintptr_t)ed::GetDoubleClickedPin(); + return (intptr_t)(uintptr_t)ed::GetDoubleClickedPin(); */ public static native long getDoubleClickedLink(); /* - return (jlong)(uintptr_t)ed::GetDoubleClickedLink(); + return (intptr_t)(uintptr_t)ed::GetDoubleClickedLink(); */ public static native boolean isBackgroundClicked(); /* @@ -264,47 +271,47 @@ public final class ImNodeEditor { return nShowNodeContextMenu(nodeId.getData()); } + private static native boolean nShowNodeContextMenu(long[] nodeId); /* + return ed::ShowNodeContextMenu((ed::NodeId*)&nodeId[0]); + */ + public static boolean showPinContextMenu(final ImLong pinId) { return nShowPinContextMenu(pinId.getData()); } + private static native boolean nShowPinContextMenu(long[] pinId); /* + return ed::ShowPinContextMenu((ed::PinId*)&pinId[0]); + */ + public static boolean showLinkContextMenu(final ImLong linkId) { return nShowLinkContextMenu(linkId.getData()); } + private static native boolean nShowLinkContextMenu(long[] linkId); /* + return ed::ShowLinkContextMenu((ed::LinkId*)&linkId[0]); + */ + /** * Binding notice: getNodeWithContextMenu(), getPinWithContextMenu() and getLinkWithContextMenu() * return id of the object for which context menu should be shown. If there is no such object -1 will be returned. - * + *

* These methods implemented as convenient alternative to showNodeContextMenu(ImLong), showPinContextMenu(ImLong) and * showLinkContextMenu(ImLong) */ public static native long getNodeWithContextMenu(); /* ed::NodeId id; - return ed::ShowNodeContextMenu(&id) ? (jlong)(uintptr_t)id : -1; + return ed::ShowNodeContextMenu(&id) ? (intptr_t)(uintptr_t)id : -1; */ public static native long getPinWithContextMenu(); /* ed::PinId id; - return ed::ShowPinContextMenu(&id) ? (jlong)(uintptr_t)id : -1; + return ed::ShowPinContextMenu(&id) ? (intptr_t)(uintptr_t)id : -1; */ public static native long getLinkWithContextMenu(); /* ed::LinkId id; - return ed::ShowLinkContextMenu(&id) ? (jlong)(uintptr_t)id : -1; - */ - - private static native boolean nShowNodeContextMenu(long[] nodeId); /* - return ed::ShowNodeContextMenu((ed::NodeId*)&nodeId[0]); - */ - - private static native boolean nShowPinContextMenu(long[] pinId); /* - return ed::ShowPinContextMenu((ed::PinId*)&pinId[0]); - */ - - private static native boolean nShowLinkContextMenu(long[] linkId); /* - return ed::ShowLinkContextMenu((ed::LinkId*)&linkId[0]); + return ed::ShowLinkContextMenu(&id) ? (intptr_t)(uintptr_t)id : -1; */ public static native boolean showBackgroundContextMenu(); /* @@ -336,7 +343,7 @@ public final class ImNodeEditor { */ public static void link(final long id, final long startPinId, final long endPinId) { - link(id, startPinId, endPinId, 1F, 1F, 1F, 1F, 1F); + link(id, startPinId, endPinId, 1, 1, 1, 1, 1); } public static native void link(long id, long startPinId, long endPinId, float r, float g, float b, float a, @@ -349,7 +356,7 @@ public final class ImNodeEditor { */ public static boolean beginCreate() { - return beginCreate(1F, 1F, 1F, 1F, 1F); + return beginCreate(1, 1, 1, 1, 1); } public static native boolean beginCreate(float r, float g, float b, float a, float thickness); /* @@ -357,7 +364,7 @@ public final class ImNodeEditor { */ public static boolean queryNewLink(final ImLong startId, final ImLong endId) { - return nQueryNewLink(startId.getData(), endId.getData(), 1F, 1F, 1F, 1F, 1F); + return nQueryNewLink(startId.getData(), endId.getData(), 1, 1, 1, 1, 1); } public static boolean queryNewLink(final ImLong startId, final ImLong endId, final float r, final float g, final float b, final float a, final float thickness) { @@ -369,7 +376,7 @@ public final class ImNodeEditor { */ public static boolean acceptNewItem() { - return acceptNewItem(1F, 1F, 1F, 1F, 1F); + return acceptNewItem(1, 1, 1, 1, 1); } public static native boolean acceptNewItem(float r, float g, float b, float a, float thickness); /* @@ -377,7 +384,7 @@ public final class ImNodeEditor { */ public static void rejectNewItem() { - rejectNewItem(1F, 1F, 1F, 1F, 1F); + rejectNewItem(1, 1, 1, 1, 1); } public static native void rejectNewItem(float r, float g, float b, float a, float thickness); /* @@ -544,5 +551,4 @@ public final class ImNodeEditor { public static native void endShortcut(); /* ed::EndShortcut(); */ - } diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorConfig.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorConfig.java new file mode 100644 index 0000000..5302f2a --- /dev/null +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorConfig.java @@ -0,0 +1,41 @@ +package imgui.nodeditor; + +import imgui.binding.ImGuiStructDestroyable; + +public final class ImNodeEditorConfig extends ImGuiStructDestroyable { + public ImNodeEditorConfig() { + } + + public ImNodeEditorConfig(final long ptr) { + super(ptr); + } + + /*JNI + #include + #include + #include + #include + #include "jni_binding_struct.h" + + namespace ed = ax::NodeEditor; + + #define IM_NODE_EDITOR_CONFIG ((ed::Config*)STRUCT_PTR) + */ + + @Override + protected long create() { + return nCreate(); + } + + private native long nCreate(); /* + return (intptr_t)(new ed::Config()); + */ + + public native String getSettingsFile(); /* + return env->NewStringUTF(IM_NODE_EDITOR_CONFIG->SettingsFile); + */ + + public native void setSettingsFile(String settingsFile); /*MANUAL + IM_NODE_EDITOR_CONFIG->SettingsFile = obj_settingsFile == NULL ? NULL : (char*)env->GetStringUTFChars(obj_settingsFile, JNI_FALSE); + */ +} diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorContext.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorContext.java index 4a3b362..c4ded88 100644 --- a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorContext.java +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorContext.java @@ -3,25 +3,27 @@ package imgui.nodeditor; import imgui.binding.ImGuiStructDestroyable; public final class ImNodeEditorContext extends ImGuiStructDestroyable { - - /*JNI - #include - #include - #include "jni_common.h" - #include "jni_binding_struct.h" - namespace ed = ax::NodeEditor; - - #define IM_NODE_EDITOR_CONTEXT ((ed::EditorContext*)STRUCT_PTR) - */ - public ImNodeEditorContext() { - super(); + } + + public ImNodeEditorContext(final ImNodeEditorConfig config) { + this(nCreate(config.ptr)); } public ImNodeEditorContext(final long ptr) { super(ptr); } + /*JNI + #include + #include + #include "jni_binding_struct.h" + + namespace ed = ax::NodeEditor; + + #define IM_NODE_EDITOR_CONTEXT ((ed::EditorContext*)STRUCT_PTR) + */ + @Override protected long create() { return nCreate(); @@ -33,7 +35,11 @@ public final class ImNodeEditorContext extends ImGuiStructDestroyable { } private native long nCreate(); /* - return (jlong)ed::CreateEditor(); + return (intptr_t)ed::CreateEditor(); + */ + + private static native long nCreate(long cfgPtr); /* + return (intptr_t)ed::CreateEditor((ed::Config*)cfgPtr); */ private native void nDestroyEditorContext(); /* diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorPinKind.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorPinKind.java index 15d9b34..d0df2fc 100644 --- a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorPinKind.java +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorPinKind.java @@ -1,11 +1,9 @@ package imgui.nodeditor; public final class ImNodeEditorPinKind { - private ImNodeEditorPinKind() { } public static final int Input = 0; public static final int Output = 1; - } diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyle.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyle.java new file mode 100644 index 0000000..fb2cedb --- /dev/null +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyle.java @@ -0,0 +1,291 @@ +package imgui.nodeditor; + +import imgui.ImVec2; +import imgui.ImVec4; +import imgui.binding.ImGuiStruct; + +public final class ImNodeEditorStyle extends ImGuiStruct { + public ImNodeEditorStyle(final long ptr) { + super(ptr); + } + + /*JNI + #include + #include + #include + #include + #include "jni_common.h" + #include "jni_binding_struct.h" + + namespace ed = ax::NodeEditor; + + #define IM_NODE_EDITOR_STYLE ((ed::Style*)STRUCT_PTR) + */ + + public native void getNodePadding(ImVec4 dstImVec4); /* + Jni::ImVec4Cpy(env, IM_NODE_EDITOR_STYLE->NodePadding, dstImVec4); + */ + + public native void setNodePadding(float x, float y, float z, float w); /* + IM_NODE_EDITOR_STYLE->NodePadding.x = x; + IM_NODE_EDITOR_STYLE->NodePadding.y = y; + IM_NODE_EDITOR_STYLE->NodePadding.z = z; + IM_NODE_EDITOR_STYLE->NodePadding.w = w; + */ + + public native float getNodeRounding(); /* + return IM_NODE_EDITOR_STYLE->NodeRounding; + */ + + public native void setNodeRounding(float nodeRounding); /* + IM_NODE_EDITOR_STYLE->NodeRounding = nodeRounding; + */ + + public native float getNodeBorderWidth(); /* + return IM_NODE_EDITOR_STYLE->NodeBorderWidth; + */ + + public native void setNodeBorderWidth(float nodeBorderWidth); /* + IM_NODE_EDITOR_STYLE->NodeBorderWidth = nodeBorderWidth; + */ + + public native float getHoveredNodeBorderWidth(); /* + return IM_NODE_EDITOR_STYLE->HoveredNodeBorderWidth; + */ + + public native void setHoveredNodeBorderWidth(float hoveredNodeBorderWidth); /* + IM_NODE_EDITOR_STYLE->HoveredNodeBorderWidth = hoveredNodeBorderWidth; + */ + + public native float getSelectedNodeBorderWidth(); /* + return IM_NODE_EDITOR_STYLE->SelectedNodeBorderWidth; + */ + + public native void setSelectedNodeBorderWidth(float selectedNodeBorderWidth); /* + IM_NODE_EDITOR_STYLE->SelectedNodeBorderWidth = selectedNodeBorderWidth; + */ + + public native float getPinRounding(); /* + return IM_NODE_EDITOR_STYLE->PinRounding; + */ + + public native void setPinRounding(float pinRounding); /* + IM_NODE_EDITOR_STYLE->PinRounding = pinRounding; + */ + + public native float getPinBorderWidth(); /* + return IM_NODE_EDITOR_STYLE->PinBorderWidth; + */ + + public native void setPinBorderWidth(float pinBorderWidth); /* + IM_NODE_EDITOR_STYLE->PinBorderWidth = pinBorderWidth; + */ + + public native float getLinkStrength(); /* + return IM_NODE_EDITOR_STYLE->LinkStrength; + */ + + public native void setLinkStrength(float linkStrength); /* + IM_NODE_EDITOR_STYLE->LinkStrength = linkStrength; + */ + + public native void getSourceDirection(ImVec2 dstImVec2); /* + Jni::ImVec2Cpy(env, &IM_NODE_EDITOR_STYLE->SourceDirection, dstImVec2); + */ + + public native float getSourceDirectionX(); /* + return IM_NODE_EDITOR_STYLE->SourceDirection.x; + */ + + public native float getSourceDirectionY(); /* + return IM_NODE_EDITOR_STYLE->SourceDirection.y; + */ + + public native void setSourceDirection(float x, float y); /* + IM_NODE_EDITOR_STYLE->SourceDirection.x = x; + IM_NODE_EDITOR_STYLE->SourceDirection.y = y; + */ + + public native void getTargetDirection(ImVec2 dstImVec2); /* + Jni::ImVec2Cpy(env, &IM_NODE_EDITOR_STYLE->TargetDirection, dstImVec2); + */ + + + public native float getTargetDirectionX(); /* + return IM_NODE_EDITOR_STYLE->TargetDirection.x; + */ + + public native float getTargetDirectionY(); /* + return IM_NODE_EDITOR_STYLE->TargetDirection.y; + */ + + public native void setTargetDirection(float x, float y); /* + IM_NODE_EDITOR_STYLE->TargetDirection.x = x; + IM_NODE_EDITOR_STYLE->TargetDirection.y = y; + */ + + public native float getScrollDuration(); /* + return IM_NODE_EDITOR_STYLE->ScrollDuration; + */ + + public native void setScrollDuration(float scrollDuration); /* + IM_NODE_EDITOR_STYLE->ScrollDuration = scrollDuration; + */ + + public native float getFlowMarkerDistance(); /* + return IM_NODE_EDITOR_STYLE->FlowMarkerDistance; + */ + + public native void setFlowMarkerDistance(float flowMarkerDistance); /* + IM_NODE_EDITOR_STYLE->FlowMarkerDistance = flowMarkerDistance; + */ + + public native float getFlowSpeed(); /* + return IM_NODE_EDITOR_STYLE->FlowSpeed; + */ + + public native void setFlowSpeed(float flowSpeed); /* + IM_NODE_EDITOR_STYLE->FlowSpeed = flowSpeed; + */ + + public native float getFlowDuration(); /* + return IM_NODE_EDITOR_STYLE->FlowDuration; + */ + + public native void setFlowDuration(float flowDuration); /* + IM_NODE_EDITOR_STYLE->FlowDuration = flowDuration; + */ + + public native void getPivotAlignment(ImVec2 dstImVec2); /* + Jni::ImVec2Cpy(env, &IM_NODE_EDITOR_STYLE->PivotAlignment, dstImVec2); + */ + + public native float getPivotAlignmentX(); /* + return IM_NODE_EDITOR_STYLE->PivotAlignment.x; + */ + + public native float getPivotAlignmentY(); /* + return IM_NODE_EDITOR_STYLE->PivotAlignment.y; + */ + + public native void setPivotAlignment(float x, float y); /* + IM_NODE_EDITOR_STYLE->PivotAlignment.x = x; + IM_NODE_EDITOR_STYLE->PivotAlignment.y = y; + */ + + public native void getPivotSize(ImVec2 dstImVec2); /* + Jni::ImVec2Cpy(env, &IM_NODE_EDITOR_STYLE->PivotSize, dstImVec2); + */ + + public native float getPivotSizeX(); /* + return IM_NODE_EDITOR_STYLE->PivotSize.x; + */ + + public native float getPivotSizeY(); /* + return IM_NODE_EDITOR_STYLE->PivotSize.y; + */ + + public native void setPivotSize(float x, float y); /* + IM_NODE_EDITOR_STYLE->PivotSize.x = x; + IM_NODE_EDITOR_STYLE->PivotSize.y = y; + */ + + public native void getPivotScale(ImVec2 dstImVec2); /* + Jni::ImVec2Cpy(env, &IM_NODE_EDITOR_STYLE->PivotScale, dstImVec2); + */ + + public native float getPivotScaleX(); /* + return IM_NODE_EDITOR_STYLE->PivotScale.x; + */ + + public native float getPivotScaleY(); /* + return IM_NODE_EDITOR_STYLE->PivotScale.y; + */ + + public native void setPivotScale(float x, float y); /* + IM_NODE_EDITOR_STYLE->PivotScale.x = x; + IM_NODE_EDITOR_STYLE->PivotScale.y = y; + */ + + public native float getPinCorners(); /* + return IM_NODE_EDITOR_STYLE->PinCorners; + */ + + public native void setPinCorners(float pinCorners); /* + IM_NODE_EDITOR_STYLE->PinCorners = pinCorners; + */ + + public native float getPinRadius(); /* + return IM_NODE_EDITOR_STYLE->PinRadius; + */ + + public native void setPinRadius(float pinRadius); /* + IM_NODE_EDITOR_STYLE->PinRadius = pinRadius; + */ + + public native float getPinArrowSize(); /* + return IM_NODE_EDITOR_STYLE->PinArrowSize; + */ + + public native void setPinArrowSize(float pinArrowSize); /* + IM_NODE_EDITOR_STYLE->PinArrowSize = pinArrowSize; + */ + + public native float getPinArrowWidth(); /* + return IM_NODE_EDITOR_STYLE->PinArrowWidth; + */ + + public native void setPinArrowWidth(float pinArrowWidth); /* + IM_NODE_EDITOR_STYLE->PinArrowWidth = pinArrowWidth; + */ + + public native float getGroupRounding(); /* + return IM_NODE_EDITOR_STYLE->GroupRounding; + */ + + public native void setGroupRounding(float groupRounding); /* + IM_NODE_EDITOR_STYLE->GroupRounding = groupRounding; + */ + + public native float getGroupBorderWidth(); /* + return IM_NODE_EDITOR_STYLE->GroupBorderWidth; + */ + + public native void setGroupBorderWidth(float groupBorderWidth); /* + IM_NODE_EDITOR_STYLE->GroupBorderWidth = groupBorderWidth; + */ + + /** + * BINDING NOTICE: colors is a 2d array with sizes: [StyleColor_Count][4] + */ + public native void setColors(float[][] colors); /* + for (int i = 0; i < ed::StyleColor_Count; i++) { + jfloatArray jColors = (jfloatArray)env->GetObjectArrayElement(colors, i); + jfloat* jColor = env->GetFloatArrayElements(jColors, 0); + + IM_NODE_EDITOR_STYLE->Colors[i].x = jColor[0]; + IM_NODE_EDITOR_STYLE->Colors[i].y = jColor[1]; + IM_NODE_EDITOR_STYLE->Colors[i].z = jColor[2]; + IM_NODE_EDITOR_STYLE->Colors[i].w = jColor[3]; + + env->ReleaseFloatArrayElements(jColors, jColor, 0); + env->DeleteLocalRef(jColors); + } + */ + + public native void getColor(int styleColor, ImVec4 dstImVec4); /* + Jni::ImVec4Cpy(env, IM_NODE_EDITOR_STYLE->Colors[styleColor], dstImVec4); + */ + + public native void setColor(int styleColor, float r, float g, float b, float a); /* + IM_NODE_EDITOR_STYLE->Colors[styleColor] = ImColor((float)r, (float)g, (float)b, (float)a); + */ + + public native void setColor(int styleColor, int r, int g, int b, int a); /* + IM_NODE_EDITOR_STYLE->Colors[styleColor] = ImColor((int)r, (int)g, (int)b, (int)a); + */ + + public native void setColor(int styleColor, int col); /* + IM_NODE_EDITOR_STYLE->Colors[styleColor] = ImColor(col); + */ +} diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleColor.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleColor.java index 6d99ef6..f08846d 100644 --- a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleColor.java +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleColor.java @@ -1,7 +1,6 @@ package imgui.nodeditor; public final class ImNodeEditorStyleColor { - private ImNodeEditorStyleColor() { } @@ -23,5 +22,4 @@ public final class ImNodeEditorStyleColor { public static final int FlowMarker = 15; public static final int GroupBg = 16; public static final int GroupBorder = 17; - } diff --git a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleVar.java b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleVar.java index 97a0672..65c4060 100644 --- a/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleVar.java +++ b/imgui-binding/src/main/java/imgui/nodeditor/ImNodeEditorStyleVar.java @@ -1,7 +1,6 @@ package imgui.nodeditor; public final class ImNodeEditorStyleVar { - private ImNodeEditorStyleVar() { } @@ -28,5 +27,4 @@ public final class ImNodeEditorStyleVar { public static final int PinArrowWidth = 20; public static final int GroupRounding = 21; public static final int GroupBorderWidth = 22; - } diff --git a/imgui-lwjgl3/src/test/java/ExampleUi.java b/imgui-lwjgl3/src/test/java/ExampleUi.java index d3580d0..e92d761 100644 --- a/imgui-lwjgl3/src/test/java/ExampleUi.java +++ b/imgui-lwjgl3/src/test/java/ExampleUi.java @@ -11,6 +11,7 @@ import imgui.imnodes.ImNodesPinShape; import imgui.nodeditor.ImNodeEditor; import imgui.internal.ImGui; import imgui.internal.flag.ImGuiDockNodeFlags; +import imgui.nodeditor.ImNodeEditorConfig; import imgui.nodeditor.ImNodeEditorContext; import imgui.nodeditor.ImNodeEditorPinKind; import imgui.type.ImBoolean; @@ -85,7 +86,9 @@ final class ExampleUi { imNodesContext = new ImNodesContext(); } if (imNodeEditorContext == null) { - imNodeEditorContext = new ImNodeEditorContext(); + final ImNodeEditorConfig config = new ImNodeEditorConfig(); + config.setSettingsFile(null); + imNodeEditorContext = new ImNodeEditorContext(config); } final int dockspaceId = ImGui.getID("MyDockSpace");