Add ImString resize support

This commit is contained in:
SpaiR committed 2020-01-01 13:41:44 +03:00
1 parent 295471930f
commit fbf1c0d1c2
4 files changed
+155 -103

No files matched your search

+69 -75
View File
@@ -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() {
}
}
+52 -15
View File
@@ -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);
}
}