Skip to content

Commit

Permalink
[API] Added callback binding for InputText (#156)
Browse files Browse the repository at this point in the history
* Added callback binding for InputText

* Add JavaDoc

* Change

* Add Javadoc

* Fix Import

* Teaks and improvements

- Extended example;
- Added input text callback ImGuiInputTextFlags#CallbackEdit;
- Minor code improvements.

---------

Co-authored-by: SpaiR <klimbetoo@gmail.com>
  • Loading branch information
moheng233 and SpaiR committed Feb 7, 2023
1 parent f3c971c commit 986aa53
Show file tree
Hide file tree
Showing 6 changed files with 296 additions and 6 deletions.
44 changes: 44 additions & 0 deletions example/src/main/java/ExampleInputTextCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import imgui.ImGui;
import imgui.ImGuiInputTextCallbackData;
import imgui.callback.ImGuiInputTextCallback;
import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiInputTextFlags;
import imgui.type.ImBoolean;
import imgui.type.ImString;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class ExampleInputTextCallback {
private static final ImString STR = new ImString();
private static final StringBuilder OUTPUT = new StringBuilder();
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

private static final ImGuiInputTextCallback CALLBACK = new ImGuiInputTextCallback() {
@Override
public void accept(final ImGuiInputTextCallbackData data) {
final char c = (char) data.getEventChar();
if (c == 'h' || c == 'H') {
data.setEventChar('!');
OUTPUT.append(DATE_FORMAT.format(LocalDateTime.now())).append(" :: Replaced!\n");
} else if (c == 'w' || c == 'W') {
data.setEventChar(0);
OUTPUT.append(DATE_FORMAT.format(LocalDateTime.now())).append(" :: Discarded!\n");
} else {
OUTPUT.append(DATE_FORMAT.format(LocalDateTime.now())).append(" :: Typed: ").append(c).append('\n');
}
}
};

public static void show(final ImBoolean showInputTextCallback) {
ImGui.setNextWindowSize(400, 300, ImGuiCond.Once);
if (ImGui.begin("Input Text Callback Demo", showInputTextCallback)) {
ImGui.alignTextToFramePadding();
ImGui.text("Try to input \"Hello World!\":");
ImGui.sameLine();
ImGui.inputText("##input", STR, ImGuiInputTextFlags.CallbackCharFilter, CALLBACK);
ImGui.text(OUTPUT.toString());
}
ImGui.end();
}
}
6 changes: 6 additions & 0 deletions example/src/main/java/Extra.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class Extra {
private static final ImBoolean SHOW_IMGUI_FILE_DIALOG_WINDOW = new ImBoolean(false);
private static final ImBoolean SHOW_IMGUI_MEMORY_EDITOR_WINDOW = new ImBoolean(false);
private static final ImBoolean SHOW_IMGUI_CANVAS_EDITOR_WINDOW = new ImBoolean(false);
private static final ImBoolean SHOW_IMGUI_INPUT_CALLBACK_WINDOW = new ImBoolean(false);

private static final Graph GRAPH = new Graph();

Expand All @@ -28,6 +29,7 @@ public static void show(final Application app) {
ImGui.checkbox("Show ImGuiFileDialog Demo Window", SHOW_IMGUI_FILE_DIALOG_WINDOW);
ImGui.checkbox("Show ImGui MemoryEditor Demo Window", SHOW_IMGUI_MEMORY_EDITOR_WINDOW);
ImGui.checkbox("Show ImGui Canvas Demo Window", SHOW_IMGUI_CANVAS_EDITOR_WINDOW);
ImGui.checkbox("Show Imgui InputText Callback Window", SHOW_IMGUI_INPUT_CALLBACK_WINDOW);

if (SHOW_DEMO_WINDOW.get()) {
ImGui.showDemoWindow(SHOW_DEMO_WINDOW);
Expand Down Expand Up @@ -68,5 +70,9 @@ public static void show(final Application app) {
if (SHOW_IMGUI_CANVAS_EDITOR_WINDOW.get()) {
ExampleCanvasEditor.show(SHOW_IMGUI_CANVAS_EDITOR_WINDOW);
}

if (SHOW_IMGUI_INPUT_CALLBACK_WINDOW.get()) {
ExampleInputTextCallback.show(SHOW_IMGUI_INPUT_CALLBACK_WINDOW);
}
}
}
49 changes: 43 additions & 6 deletions imgui-binding/src/main/java/imgui/ImGui.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package imgui;

import imgui.assertion.ImAssertCallback;
import imgui.callback.ImGuiInputTextCallback;
import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiDragDropFlags;
import imgui.flag.ImGuiInputTextFlags;
Expand Down Expand Up @@ -2988,11 +2989,13 @@ public static boolean vSliderScalar(String label, float sizeX, float sizeY, int

/*JNI
jmethodID jImStringResizeInternalMID;
jmethodID jInputTextCallbackMID;
jfieldID inputDataSizeID;
jfieldID inputDataIsDirtyID;
jfieldID inputDataIsResizedID;
struct InputTextCallbackUserData {
JNIEnv* env;
jobject* imString;
Expand All @@ -3001,6 +3004,7 @@ public static boolean vSliderScalar(String label, float sizeX, float sizeY, int
char* resizedBuf;
jobject* textInputData;
char* allowedChars;
jobject* handler;
};
static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) {
Expand Down Expand Up @@ -3033,6 +3037,11 @@ static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) {
}
}
if (userData->handler != NULL) {
JNIEnv* env = userData->env;
env->CallObjectMethod(*userData->handler, jInputTextCallbackMID, data);
}
return 0;
}
*/
Expand All @@ -3045,41 +3054,68 @@ static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) {
jclass jImString = env->FindClass("imgui/type/ImString");
jImStringResizeInternalMID = env->GetMethodID(jImString, "resizeInternal", "(I)[B");
jclass jCallback = env->FindClass("imgui/callback/ImGuiInputTextCallback");
jInputTextCallbackMID = env->GetMethodID(jCallback, "accept", "(J)V");
*/

public static boolean inputText(String label, ImString text) {
return preInputText(false, label, null, text, 0, 0, ImGuiInputTextFlags.None);
return preInputText(false, label, null, text);
}

public static boolean inputText(String label, ImString text, int imGuiInputTextFlags) {
return preInputText(false, label, null, text, 0, 0, imGuiInputTextFlags);
}

public static boolean inputText(String label, ImString text, int imGuiInputTextFlags, ImGuiInputTextCallback callback) {
return preInputText(false, label, null, text, 0, 0, imGuiInputTextFlags, callback);
}

public static boolean inputTextMultiline(String label, ImString text) {
return preInputText(true, label, null, text, 0, 0, ImGuiInputTextFlags.None);
return preInputText(true, label, null, text);
}

public static boolean inputTextMultiline(String label, ImString text, float width, float height) {
return preInputText(true, label, null, text, width, height, ImGuiInputTextFlags.None);
return preInputText(true, label, null, text, width, height);
}

public static boolean inputTextMultiline(String label, ImString text, int imGuiInputTextFlags) {
return preInputText(true, label, null, text, 0, 0, imGuiInputTextFlags);
}

public static boolean inputTextMultiline(String label, ImString text, int imGuiInputTextFlags, ImGuiInputTextCallback callback) {
return preInputText(true, label, null, text, 0, 0, imGuiInputTextFlags, callback);
}

public static boolean inputTextMultiline(String label, ImString text, float width, float height, int imGuiInputTextFlags) {
return preInputText(true, label, null, text, width, height, imGuiInputTextFlags);
}

public static boolean inputTextMultiline(String label, ImString text, float width, float height, int imGuiInputTextFlags, ImGuiInputTextCallback callback) {
return preInputText(true, label, null, text, width, height, imGuiInputTextFlags, callback);
}

public static boolean inputTextWithHint(String label, String hint, ImString text) {
return preInputText(false, label, hint, text, 0, 0, ImGuiInputTextFlags.None);
return preInputText(false, label, hint, text);
}

public static boolean inputTextWithHint(String label, String hint, ImString text, int imGuiInputTextFlags) {
return preInputText(false, label, hint, text, 0, 0, imGuiInputTextFlags);
}

private static boolean preInputText(boolean multiline, String label, String hint, ImString text) {
return preInputText(multiline, label, hint, text, 0, 0);
}

private static boolean preInputText(boolean multiline, String label, String hint, ImString text, float width, float height) {
return preInputText(multiline, label, hint, text, width, height, ImGuiInputTextFlags.None);
}

private static boolean preInputText(boolean multiline, String label, String hint, ImString text, float width, float height, int flags) {
return preInputText(multiline, label, hint, text, width, height, flags, null);
}

private static boolean preInputText(boolean multiline, String label, String hint, ImString text, float width, float height, int flags, ImGuiInputTextCallback callback) {
final ImString.InputData inputData = text.inputData;

if (inputData.isResizable) {
Expand All @@ -3095,10 +3131,10 @@ private static boolean preInputText(boolean multiline, String label, String hint
hintLabel = "";
}

return nInputText(multiline, hint != null, label, hintLabel, text, text.getData(), text.getData().length, width, height, flags, inputData, inputData.allowedChars);
return nInputText(multiline, hint != null, label, hintLabel, text, text.getData(), text.getData().length, width, height, flags, inputData, inputData.allowedChars, callback);
}

private static native boolean nInputText(boolean multiline, boolean hint, String label, String hintLabel, ImString imString, byte[] buf, int maxSize, float width, float height, int flags, ImString.InputData textInputData, String allowedChars); /*
private static native boolean nInputText(boolean multiline, boolean hint, String label, String hintLabel, ImString imString, byte[] buf, int maxSize, float width, float height, int flags, ImString.InputData textInputData, String allowedChars, ImGuiInputTextCallback callback); /*
InputTextCallbackUserData userData;
userData.imString = &imString;
userData.maxSize = maxSize;
Expand All @@ -3107,6 +3143,7 @@ private static boolean preInputText(boolean multiline, String label, String hint
userData.textInputData = &textInputData;
userData.env = env;
userData.allowedChars = allowedChars;
userData.handler = &callback;
bool valueChanged;
Expand Down
182 changes: 182 additions & 0 deletions imgui-binding/src/main/java/imgui/ImGuiInputTextCallbackData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package imgui;

import imgui.binding.ImGuiStruct;

/**
* Shared state of InputText(), passed as an argument to your callback when a ImGuiInputTextFlags_Callback* flag is used.<p>
* The callback function should return 0 by default.<p>
* Callbacks (follow a flag name and see comments in ImGuiInputTextFlags_ declarations for more details)<p>
* - ImGuiInputTextFlags_CallbackEdit: Callback on buffer edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)<p>
* - ImGuiInputTextFlags_CallbackAlways: Callback on each iteration<p>
* - ImGuiInputTextFlags_CallbackCompletion: Callback on pressing TAB<p>
* - ImGuiInputTextFlags_CallbackHistory: Callback on pressing Up/Down arrows<p>
* - ImGuiInputTextFlags_CallbackCharFilter: Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard.<p>
* - ImGuiInputTextFlags_CallbackResize: Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow.<p>
*/
public class ImGuiInputTextCallbackData extends ImGuiStruct {
public ImGuiInputTextCallbackData(final long ptr) {
super(ptr);
}

/*JNI
#include "_common.h"
#define IMGUI_CALLBACK_DATA ((ImGuiInputTextCallbackData*)STRUCT_PTR)
*/

/**
* One ImGuiInputTextFlags_Callback*
*
* @return ImGuiInputTextFlags
*/
public native int getEventFlag(); /*
return IMGUI_CALLBACK_DATA->EventFlag;
*/

/**
* What user passed to InputText()
*
* @return ImGuiInputTextFlags
*/
public native int getFlags(); /*
return IMGUI_CALLBACK_DATA->Flags;
*/

/**
* [CharFilter] Character input;
*
* @return Character input
*/
public native int getEventChar(); /*
return IMGUI_CALLBACK_DATA->EventChar;
*/

/**
* [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0;
*
* @param c Replaced characters
*/
public void setEventChar(final char c) {
setEventChar((int) c);
}

/**
* [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0;
*
* @param c Replaced characters
*/
public native void setEventChar(int c); /*
IMGUI_CALLBACK_DATA->EventChar = c;
*/

/**
* [Completion,History]
*
* @return Key pressed (Up/Down/TAB)
*/
public native int getEventKey(); /*
return IMGUI_CALLBACK_DATA->EventKey;
*/

/**
* [Resize] Can replace pointer <p>
* [Completion,History,Always] Only write to pointed data, don't replace the actual pointer!
*
* @return Buf
*/
public native String getBuf(); /*
return env->NewStringUTF(IMGUI_CALLBACK_DATA->Buf);
*/

/**
* Set if you modify Buf/BufTextLen!
*
* @return Dirty
*/
public native boolean getBufDirty(); /*
return IMGUI_CALLBACK_DATA->BufDirty;
*/

/**
* Set if you modify Buf/BufTextLen!
*
* @param dirty Dirty
*/
public native void setBufDirty(boolean dirty); /*
IMGUI_CALLBACK_DATA->BufDirty = dirty;
*/

/**
* Current cursor position
*
* @return Current cursor position
*/
public native int getCursorPos(); /*
return IMGUI_CALLBACK_DATA->CursorPos;
*/

/**
* Set the current cursor position
*
* @param pos Set the current cursor position
*/
public native void setCursorPos(int pos); /*
IMGUI_CALLBACK_DATA->CursorPos = pos;
*/

/**
* Selection Start
*
* @return Selection Start
*/
public native int getSelectionStart(); /*
return IMGUI_CALLBACK_DATA->SelectionStart;
*/

/**
* Set Selection Start
*
* @param pos Selection Start
*/
public native void setSelectionStart(int pos); /*
IMGUI_CALLBACK_DATA->SelectionStart = pos;
*/

/**
* Selection End
*
* @return Selection End
*/
public native int getSelectionEnd(); /*
return IMGUI_CALLBACK_DATA->SelectionEnd;
*/

/**
* Set Selection End
*
* @param pos Selection End
*/
public native void setSelectionEnd(int pos); /*
IMGUI_CALLBACK_DATA->SelectionEnd = pos;
*/

/**
* Delete Chars
*
* @param pos Start Delete Pos
* @param bytesCount Delete Char Count
*/
public native void deleteChars(int pos, int bytesCount); /*
IMGUI_CALLBACK_DATA->DeleteChars(pos, bytesCount);
*/

/**
* Insert Chars
*
* @param pos insert Psos
* @param str insert String
*/
public native void insertChars(int pos, String str); /*
IMGUI_CALLBACK_DATA->InsertChars(pos, str);
*/
}
Loading

0 comments on commit 986aa53

Please sign in to comment.