Add ImString resize support
This commit is contained in:
1 parent
295471930f
commit
fbf1c0d1c2
4 files changed
+155
-103
No files matched your search
@@ -1,5 +1,7 @@
|
||||
package imgui;
|
||||
|
||||
import imgui.enums.ImGuiInputTextFlags;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class ImGui {
|
||||
@@ -2382,25 +2384,26 @@ public final class ImGui {
|
||||
/*JNI
|
||||
jfieldID imTextInputDataSizeID;
|
||||
jfieldID imTextInputDataIsDirtyID;
|
||||
jfieldID imTextInputDataIsResizedID;
|
||||
|
||||
struct InputTextCallback_UserData {
|
||||
jobject* textInputData;
|
||||
char* resizedBuf;
|
||||
|
||||
struct InputTextCallbackUserData {
|
||||
JNIEnv* env;
|
||||
int maxChar;
|
||||
char* allowedChar;
|
||||
int allowedCharLength;
|
||||
int maxSize;
|
||||
int curSize;
|
||||
jobject* textInputData;
|
||||
char* buf;
|
||||
char* allowedChars;
|
||||
};
|
||||
|
||||
static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) {
|
||||
InputTextCallback_UserData* userData = (InputTextCallback_UserData*)data->UserData;
|
||||
InputTextCallbackUserData* userData = (InputTextCallbackUserData*)data->UserData;
|
||||
|
||||
if (data->EventFlag == ImGuiInputTextFlags_CallbackCharFilter) {
|
||||
if(userData->allowedCharLength > 0) {
|
||||
int allowedCharLength = strlen(userData->allowedChars);
|
||||
if(allowedCharLength > 0) {
|
||||
bool found = false;
|
||||
for(int i = 0; i < userData->allowedCharLength; i++) {
|
||||
if(userData->allowedChar[i] == data->EventChar) {
|
||||
for(int i = 0; i < allowedCharLength; i++) {
|
||||
if(userData->allowedChars[i] == data->EventChar) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -2417,94 +2420,85 @@ public final class ImGui {
|
||||
jclass jImInputTextDataClass = env->FindClass("imgui/ImGuiInputTextData");
|
||||
imTextInputDataSizeID = env->GetFieldID(jImInputTextDataClass, "size", "I");
|
||||
imTextInputDataIsDirtyID = env->GetFieldID(jImInputTextDataClass, "isDirty", "Z");
|
||||
imTextInputDataIsResizedID = env->GetFieldID(jImInputTextDataClass, "isResized", "Z");
|
||||
*/
|
||||
|
||||
public static boolean InputText(String label, ImString text) {
|
||||
return nInputText(label, text.data, text.data.length, 0, text.inputData, text.inputData.maxChar, text.inputData.allowedChar, text.inputData.allowedChar.length());
|
||||
return preInputText(false, label, text, 0, 0, 0);
|
||||
}
|
||||
|
||||
public static boolean InputText(String label, ImString text, int imGuiInputTextFlags) {
|
||||
return nInputText(label, text.data, text.data.length, imGuiInputTextFlags, text.inputData, text.inputData.maxChar, text.inputData.allowedChar, text.inputData.allowedChar.length());
|
||||
return preInputText(false, label, text, 0, 0, imGuiInputTextFlags);
|
||||
}
|
||||
|
||||
private static native boolean nInputText(String label, byte[] buff, int maxSize, int flags, ImGuiInputTextData textInputData, int maxChar, String allowedChar, int allowedCharLength); /*
|
||||
int size = (int)strlen(buff);
|
||||
|
||||
InputTextCallback_UserData cb_user_data;
|
||||
cb_user_data.textInputData = &textInputData;
|
||||
cb_user_data.env = env;
|
||||
cb_user_data.curSize = size;
|
||||
cb_user_data.maxSize = maxSize;
|
||||
cb_user_data.maxChar = maxChar;
|
||||
cb_user_data.allowedChar = allowedChar;
|
||||
cb_user_data.allowedCharLength = allowedCharLength;
|
||||
|
||||
char tempArray[maxSize];
|
||||
|
||||
memset(tempArray, 0, sizeof(tempArray));
|
||||
memcpy(tempArray, buff, size);
|
||||
|
||||
if(maxChar >= 0 && maxChar < maxSize) {
|
||||
maxSize = maxChar;
|
||||
}
|
||||
|
||||
bool flag = ImGui::InputText(label, tempArray, maxSize, flags | ImGuiInputTextFlags_CallbackCharFilter, &TextEditCallbackStub, &cb_user_data);
|
||||
|
||||
if (flag) {
|
||||
size = (int)strlen(tempArray);
|
||||
env->SetIntField(textInputData, imTextInputDataSizeID, size);
|
||||
env->SetBooleanField(textInputData, imTextInputDataIsDirtyID, true);
|
||||
memset(buff, 0, maxSize);
|
||||
memcpy(buff, tempArray, size);
|
||||
}
|
||||
|
||||
return flag;
|
||||
*/
|
||||
|
||||
public static boolean InputTextMultiline(String label, ImString text) {
|
||||
return nInputTextMultiline(label, text.data, text.data.length, 0, 0, 0, text.inputData, text.inputData.maxChar, text.inputData.allowedChar, text.inputData.allowedChar.length());
|
||||
return preInputText(true, label, text, 0, 0, 0);
|
||||
}
|
||||
|
||||
public static boolean InputTextMultiline(String label, ImString text, float width, float height) {
|
||||
return nInputTextMultiline(label, text.data, text.data.length, width, height, 0, text.inputData, text.inputData.maxChar, text.inputData.allowedChar, text.inputData.allowedChar.length());
|
||||
return preInputText(true, label, text, width, height, 0);
|
||||
}
|
||||
|
||||
public static boolean InputTextMultiline(String label, ImString text, int imGuiInputTextFlags) {
|
||||
return preInputText(true, label, text, 0, 0, imGuiInputTextFlags);
|
||||
}
|
||||
|
||||
public static boolean InputTextMultiline(String label, ImString text, float width, float height, int imGuiInputTextFlags) {
|
||||
return nInputTextMultiline(label, text.data, text.data.length, width, height, imGuiInputTextFlags, text.inputData, text.inputData.maxChar, text.inputData.allowedChar, text.inputData.allowedChar.length());
|
||||
return preInputText(true, label, text, width, height, imGuiInputTextFlags);
|
||||
}
|
||||
|
||||
private static native boolean nInputTextMultiline(String label, byte[] buff, int maxSize, float width, float height, int flags, ImGuiInputTextData textInputData, int maxChar, String allowedChar, int allowedCharLength); /*
|
||||
int size = (int)strlen(buff);
|
||||
private static boolean preInputText(boolean multiline, String label, ImString text, float width, float height, int flags) {
|
||||
ImGuiInputTextData inputData = text.inputData;
|
||||
|
||||
InputTextCallback_UserData cb_user_data;
|
||||
cb_user_data.textInputData = &textInputData;
|
||||
cb_user_data.env = env;
|
||||
cb_user_data.curSize = size;
|
||||
cb_user_data.maxSize = maxSize;
|
||||
cb_user_data.maxChar = maxChar;
|
||||
cb_user_data.allowedChar = allowedChar;
|
||||
cb_user_data.allowedCharLength = allowedCharLength;
|
||||
|
||||
char tempArray[maxSize];
|
||||
|
||||
memset(tempArray, 0, sizeof(tempArray));
|
||||
memcpy(tempArray, buff, size);
|
||||
|
||||
if(maxChar >= 0 && maxChar < maxSize) {
|
||||
maxSize = maxChar;
|
||||
if (inputData.isResizable) {
|
||||
flags |= ImGuiInputTextFlags.CallbackResize;
|
||||
}
|
||||
|
||||
bool flag = ImGui::InputTextMultiline(label, tempArray, maxSize, ImVec2(width, height), flags | ImGuiInputTextFlags_CallbackCharFilter, &TextEditCallbackStub, &cb_user_data);
|
||||
boolean hasInput = nInputText(multiline, label, text.data, text.data.length, width, height, flags, inputData, inputData.allowedChars);
|
||||
|
||||
if (inputData.isResized) {
|
||||
inputData.isResized = false;
|
||||
text.set(nGetResizedStr(), true);
|
||||
}
|
||||
|
||||
return hasInput;
|
||||
}
|
||||
|
||||
private static native boolean nInputText(boolean multiline, String label, byte[] buf, int maxSize, float width, float height, int flags, ImGuiInputTextData textInputData, String allowedChars); /*
|
||||
InputTextCallbackUserData userData;
|
||||
userData.textInputData = &textInputData;
|
||||
userData.env = env;
|
||||
userData.buf = buf;
|
||||
userData.allowedChars = allowedChars;
|
||||
|
||||
if (strlen(allowedChars) > 0)
|
||||
flags |= ImGuiInputTextFlags_CallbackCharFilter;
|
||||
|
||||
bool hasInput;
|
||||
|
||||
if (multiline) {
|
||||
hasInput = ImGui::InputTextMultiline(label, buf, maxSize, ImVec2(width, height), flags, &TextEditCallbackStub, &userData);
|
||||
} else {
|
||||
hasInput = ImGui::InputText(label, buf, maxSize, flags, &TextEditCallbackStub, &userData);
|
||||
}
|
||||
|
||||
if (hasInput) {
|
||||
int size = strlen(buf);
|
||||
|
||||
if (((size + 1) > maxSize) && (flags & ImGuiInputTextFlags_CallbackResize)) {
|
||||
env->SetBooleanField(textInputData, imTextInputDataIsResizedID, true);
|
||||
resizedBuf = buf;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
size = (int)strlen(tempArray);
|
||||
env->SetIntField(textInputData, imTextInputDataSizeID, size);
|
||||
env->SetBooleanField(textInputData, imTextInputDataIsDirtyID, true);
|
||||
memset(buff, 0, maxSize);
|
||||
memcpy(buff, tempArray, size);
|
||||
}
|
||||
|
||||
return flag;
|
||||
return hasInput;
|
||||
*/
|
||||
|
||||
private static native String nGetResizedStr(); /*
|
||||
return env->NewStringUTF(resizedBuf);
|
||||
*/
|
||||
|
||||
public static boolean InputFloat(String label, ImFloat v) {
|
||||
@@ -4522,7 +4516,7 @@ public final class ImGui {
|
||||
*/
|
||||
|
||||
// Clipboard Utilities (also see the LogToClipboard() function to capture or output text data to the clipboard)
|
||||
|
||||
|
||||
public static native String GetClipboardText(); /*
|
||||
return env->NewStringUTF(ImGui::GetClipboardText());
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,25 @@
|
||||
package imgui;
|
||||
|
||||
final class ImGuiInputTextData {
|
||||
public int size;
|
||||
public int maxChar = -1;
|
||||
public String allowedChar = "";
|
||||
/**
|
||||
* Use this class to customize your ImGui input.
|
||||
*/
|
||||
public final class ImGuiInputTextData {
|
||||
/**
|
||||
* If not empty, then other chars which are different from provided will be filtered during the {@link ImGui#InputText(String, ImString)}
|
||||
* and {@link ImGui#InputTextMultiline} methods.
|
||||
*/
|
||||
public String allowedChars = "";
|
||||
|
||||
/**
|
||||
* If true, then string will be resized during the the {@link ImGui#InputText(String, ImString)} and {@link ImGui#InputTextMultiline} methods.
|
||||
* Alternatively you can provide {@link imgui.enums.ImGuiInputTextFlags#CallbackResize} flag to the input text widgets to enable string resizing.
|
||||
*/
|
||||
public boolean isResizable;
|
||||
|
||||
int size;
|
||||
boolean isDirty;
|
||||
boolean isResized = false;
|
||||
|
||||
ImGuiInputTextData() {
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,30 @@
|
||||
package imgui;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Wrapper for {@link String} to use inside of ImGui input widgets.
|
||||
*/
|
||||
public final class ImString {
|
||||
private static final int DEFAULT_SIZE = 100;
|
||||
private static final short DEFAULT_LENGTH = 100;
|
||||
private static final short CARET_LEN = 1;
|
||||
private static final short DEFAULT_RESIZE = 10;
|
||||
|
||||
public final ImGuiInputTextData inputData = new ImGuiInputTextData();
|
||||
/**
|
||||
* String will be resized to the value equal to a new size plus this resize factor.
|
||||
*/
|
||||
public int resizeFactor = DEFAULT_RESIZE;
|
||||
|
||||
ImGuiInputTextData inputData = new ImGuiInputTextData();
|
||||
byte[] data;
|
||||
private String text;
|
||||
private String text = "";
|
||||
|
||||
public ImString() {
|
||||
this(DEFAULT_SIZE);
|
||||
this(DEFAULT_LENGTH);
|
||||
}
|
||||
|
||||
public ImString(int size) {
|
||||
data = new byte[size];
|
||||
public ImString(int length) {
|
||||
data = new byte[length + CARET_LEN];
|
||||
}
|
||||
|
||||
public ImString(String text) {
|
||||
@@ -22,8 +32,8 @@ public final class ImString {
|
||||
set(text);
|
||||
}
|
||||
|
||||
public ImString(String text, int size) {
|
||||
this(size);
|
||||
public ImString(String text, int length) {
|
||||
this(length);
|
||||
set(text);
|
||||
}
|
||||
|
||||
@@ -36,11 +46,38 @@ public final class ImString {
|
||||
}
|
||||
|
||||
public void set(String value) {
|
||||
inputData.size = value.length();
|
||||
text = value;
|
||||
for (int i = 0; i < inputData.size; i++) {
|
||||
data[i] = (byte) value.charAt(i);
|
||||
set(value.getBytes());
|
||||
}
|
||||
|
||||
public void set(String value, boolean resize) {
|
||||
byte[] str = value.getBytes();
|
||||
if (resize && data.length - CARET_LEN < str.length) {
|
||||
data = new byte[str.length + resizeFactor + CARET_LEN];
|
||||
}
|
||||
set(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the text inside of the data buffer.
|
||||
* @return length of the text inside of the data buffer
|
||||
*/
|
||||
public int getLength() {
|
||||
return get().length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the data buffer. Buffer size will always have '+1' to its size, since it's used by the Dear ImGui to draw a caret.
|
||||
* @return size of the data buffer
|
||||
*/
|
||||
public int getBufferSize() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
private void set(byte[] str) {
|
||||
int len = Math.min(str.length, data.length);
|
||||
System.arraycopy(str, 0, data, 0, len);
|
||||
inputData.isDirty = true;
|
||||
inputData.size = len;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,11 +90,11 @@ public final class ImString {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ImString imString = (ImString) o;
|
||||
return Arrays.equals(data, imString.data);
|
||||
return Objects.equals(text, imString.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(data);
|
||||
return text.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -47,11 +47,12 @@ public final class ImGuiGlfwExample {
|
||||
private final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3();
|
||||
|
||||
// Local app variables go here
|
||||
private final ImString imguiDemoLink = new ImString("https://raw.githubusercontent.com/ocornut/imgui/v1.74/imgui_demo.cpp", 100);
|
||||
private float[] backgroundColor = new float[]{0.5f, 0, 0};
|
||||
private int clickCount = 0;
|
||||
private final String imguiDemoLink = "https://raw.githubusercontent.com/ocornut/imgui/v1.74/imgui_demo.cpp";
|
||||
private final byte[] testPayload = "Test Payload".getBytes();
|
||||
private String dropTargetText = "Drop Here";
|
||||
private float[] backgroundColor = new float[]{0.5f, 0, 0};
|
||||
private int clickCount = 0;
|
||||
private final ImString resizableStr = new ImString(5);
|
||||
|
||||
private final ImBool showDemoWindow = new ImBool();
|
||||
|
||||
@@ -273,11 +274,12 @@ public final class ImGuiGlfwExample {
|
||||
}
|
||||
|
||||
private void showUi() {
|
||||
ImGui.SetNextWindowSize(600, 210, ImGuiCond.Once);
|
||||
ImGui.SetNextWindowSize(600, 300, ImGuiCond.Once);
|
||||
ImGui.SetNextWindowPos(10, 10, ImGuiCond.Once);
|
||||
|
||||
ImGui.Begin("Custom window");
|
||||
ImGui.Text("Hello from Java!");
|
||||
|
||||
ImGui.Button("Drag me");
|
||||
if (ImGui.BeginDragDropSource()) {
|
||||
ImGui.SetDragDropPayload("payload_type", testPayload, testPayload.length);
|
||||
@@ -298,6 +300,7 @@ public final class ImGuiGlfwExample {
|
||||
ImGui.Text("Background color:");
|
||||
ImGui.SameLine();
|
||||
ImGui.ColorEdit3("##click_counter_col", backgroundColor, ImGuiColorEditFlags.NoInputs | ImGuiColorEditFlags.NoDragDrop);
|
||||
|
||||
if (ImGui.Button("Click")) {
|
||||
clickCount++;
|
||||
}
|
||||
@@ -309,16 +312,17 @@ public final class ImGuiGlfwExample {
|
||||
ImGui.Checkbox("Show demo window", showDemoWindow);
|
||||
ImGui.NewLine();
|
||||
|
||||
ImGui.InputText("Resizable input", resizableStr, ImGuiInputTextFlags.CallbackResize);
|
||||
ImGui.Text(String.format("text len: %d | buffer size: %d", resizableStr.getLength(), resizableStr.getBufferSize()));
|
||||
ImGui.NewLine();
|
||||
|
||||
ImGui.Separator();
|
||||
ImGui.Text("Consider to look the original ImGui demo: ");
|
||||
ImGui.SetNextItemWidth(500);
|
||||
ImGui.InputText("##input_to_copy_link", imguiDemoLink, ImGuiInputTextFlags.ReadOnly);
|
||||
if (ImGui.IsItemHovered()) {
|
||||
ImGui.SetMouseCursor(ImGuiMouseCursor.TextInput);
|
||||
}
|
||||
ImGui.TextColored(0, .8f, 0, 1, imguiDemoLink);
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Copy")) {
|
||||
ImGui.SetClipboardText(imguiDemoLink.get());
|
||||
ImGui.SetClipboardText(imguiDemoLink);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user