Add example for GLFW
This commit is contained in:
1 parent
dc59810566
commit
3e7c50296c
13 files changed
+2606
-2561
No files matched your search
@@ -41,6 +41,10 @@ public class ImGui {
|
|||||||
Native.CreateContext();
|
Native.CreateContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void destroy() {
|
||||||
|
Native.DestroyContext();
|
||||||
|
}
|
||||||
|
|
||||||
public static ImGuiIO GetIO() {
|
public static ImGuiIO GetIO() {
|
||||||
return imguiIO;
|
return imguiIO;
|
||||||
}
|
}
|
||||||
@@ -69,10 +73,24 @@ public class ImGui {
|
|||||||
Native.ShowMetricsWindow(open);
|
Native.ShowMetricsWindow(open);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateDisplayAndInputAndFrame(float deltaTime, float w, float h, float backBufferWidth, float backBufferHeight,
|
public static void UpdateDisplaySize(float width, float height, float frameBufferWidth, float frameBufferHeight) {
|
||||||
int mouseX, int mouseY, boolean mouseDown0, boolean mouseDown1, boolean mouseDown2) {
|
Native.UpdateDisplaySize(width, height, frameBufferWidth, frameBufferHeight);
|
||||||
Native.UpdateDisplayAndInputAndFrame(imguiIO, imguiStyle, deltaTime, w, h, backBufferWidth, backBufferHeight,
|
}
|
||||||
mouseX, mouseY, mouseDown0, mouseDown1, mouseDown2, false, false, false);
|
|
||||||
|
public static void UpdateMousePos(float mouseX, float mouseY) {
|
||||||
|
Native.UpdateMousePos(mouseX, mouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateMouseState(boolean mouseDown0, boolean mouseDown1, boolean mouseDown2, boolean mouseDown3, boolean mouseDown4, boolean mouseDown5) {
|
||||||
|
Native.UpdateMouseState(mouseDown0, mouseDown1, mouseDown2, mouseDown3, mouseDown4, mouseDown5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateImGui() {
|
||||||
|
Native.UpdateImGui(imguiIO, imguiStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateDeltaTime(float deltaTime) {
|
||||||
|
Native.UpdateDeltaTime(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initKeyMap(int[] keys) {
|
public static void initKeyMap(int[] keys) {
|
||||||
@@ -80,15 +98,23 @@ public class ImGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateKey(int key, boolean pressed, boolean released, boolean ctrlKey, boolean shiftKey, boolean altKey, boolean superKey) {
|
public static void UpdateKey(int key, boolean pressed, boolean released, boolean ctrlKey, boolean shiftKey, boolean altKey, boolean superKey) {
|
||||||
Native.updateKey(key, pressed, released, ctrlKey, shiftKey, altKey, superKey);
|
Native.UpdateKey(key, pressed, released, ctrlKey, shiftKey, altKey, superKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateScroll(float amountX, float amountY) {
|
public static void UpdateScroll(float amountX, float amountY) {
|
||||||
Native.updateScroll(amountX, amountY);
|
Native.UpdateScroll(amountX, amountY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateKeyTyped(int c) {
|
public static void UpdateKeyTyped(int c) {
|
||||||
Native.updateKeyTyped(c);
|
Native.UpdateKeyTyped(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void NewFrame() {
|
||||||
|
Native.NewFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EndFrame() {
|
||||||
|
Native.EndFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Render() {
|
public static void Render() {
|
||||||
@@ -248,6 +274,10 @@ public class ImGui {
|
|||||||
Native.SetNextWindowPos(x, y);
|
Native.SetNextWindowPos(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetNextWindowPos(float x, float y, ImGuiCond cond) {
|
||||||
|
Native.SetNextWindowPos(x, y, cond.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
public static void SetNextWindowPos(float x, float y, ImGuiCond cond, float pivotX, float pivotY) {
|
public static void SetNextWindowPos(float x, float y, ImGuiCond cond, float pivotX, float pivotY) {
|
||||||
Native.SetNextWindowPos(x, y, cond.getValue(), pivotX, pivotY);
|
Native.SetNextWindowPos(x, y, cond.getValue(), pivotX, pivotY);
|
||||||
}
|
}
|
||||||
@@ -287,10 +317,11 @@ public class ImGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void SetWindowFocus(String name) {
|
public static void SetWindowFocus(String name) {
|
||||||
if (name == null)
|
if (name == null) {
|
||||||
Native.RemoveWindowFocus();
|
Native.RemoveWindowFocus();
|
||||||
else
|
} else {
|
||||||
Native.SetWindowFocus(name);
|
Native.SetWindowFocus(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Content region
|
// Content region
|
||||||
@@ -841,9 +872,9 @@ public class ImGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO impl
|
//TODO impl
|
||||||
// public static boolean DragScalar(String label, ImGuiDataType_ data_type, ImGuiInt v, ImGuiInt v_current_max, float v_speed, float v_min, float v_max, String format, String format_max) {
|
// public static boolean DragScalar(String label, ImGuiDataType_ data_type, ImGuiInt v, ImGuiInt v_current_max, float v_speed, float v_min, float v_max, String format, String format_max) {
|
||||||
// return ImGuiNative.DragScalar(label, data_type.getValue(), v.data, v_current_max.data, v_speed, v_min, v_max, format, format_max);
|
// return ImGuiNative.DragScalar(label, data_type.getValue(), v.data, v_current_max.data, v_speed, v_min, v_max, format, format_max);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
// Widgets: Sliders
|
// Widgets: Sliders
|
||||||
|
|||||||
@@ -15,7 +15,12 @@ public class ImGuiString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ImGuiString(String text) {
|
public ImGuiString(String text) {
|
||||||
this(100);
|
this(text.length());
|
||||||
|
setValue(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImGuiString(String text, int size) {
|
||||||
|
this(size);
|
||||||
setValue(text);
|
setValue(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -3,166 +3,166 @@ package imgui;
|
|||||||
import imgui.enums.ImDrawCornerFlags;
|
import imgui.enums.ImDrawCornerFlags;
|
||||||
|
|
||||||
class NativeCustomWidget {
|
class NativeCustomWidget {
|
||||||
public static ImGuiCollapseLayoutOptions defaultOptions = new ImGuiCollapseLayoutOptions();
|
public static ImGuiCollapseLayoutOptions defaultOptions = new ImGuiCollapseLayoutOptions();
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
|
|
||||||
/*JNI
|
/*JNI
|
||||||
#include <imgui_layout_widget.h>
|
#include <imgui_layout_widget.h>
|
||||||
|
|
||||||
jfieldID paddingLeftID;
|
jfieldID paddingLeftID;
|
||||||
jfieldID paddingRightID;
|
jfieldID paddingRightID;
|
||||||
jfieldID paddingTopID;
|
jfieldID paddingTopID;
|
||||||
jfieldID paddingBottomID;
|
jfieldID paddingBottomID;
|
||||||
jfieldID arrowColorID;
|
jfieldID arrowColorID;
|
||||||
jfieldID arrowBackgroundHoveredColorID;
|
jfieldID arrowBackgroundHoveredColorID;
|
||||||
jfieldID arrowBackgroundClickedColorID;
|
jfieldID arrowBackgroundClickedColorID;
|
||||||
jfieldID frameColorID;
|
jfieldID frameColorID;
|
||||||
jfieldID borderColorID;
|
jfieldID borderColorID;
|
||||||
jfieldID borderRoundID;
|
jfieldID borderRoundID;
|
||||||
jfieldID roundingCornersID;
|
jfieldID roundingCornersID;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void init() /*-{ }-*/; /*
|
static native void init() /*-{ }-*/; /*
|
||||||
jclass jLayoutOptionsClass = env->FindClass("imgui/NativeCustomWidget");
|
jclass jLayoutOptionsClass = env->FindClass("imgui/NativeCustomWidget");
|
||||||
paddingLeftID = env->GetFieldID(jLayoutOptionsClass, "paddingLeft", "F");
|
paddingLeftID = env->GetFieldID(jLayoutOptionsClass, "paddingLeft", "F");
|
||||||
paddingRightID = env->GetFieldID(jLayoutOptionsClass, "paddingRight", "F");
|
paddingRightID = env->GetFieldID(jLayoutOptionsClass, "paddingRight", "F");
|
||||||
paddingTopID = env->GetFieldID(jLayoutOptionsClass, "paddingTop", "F");
|
paddingTopID = env->GetFieldID(jLayoutOptionsClass, "paddingTop", "F");
|
||||||
paddingBottomID = env->GetFieldID(jLayoutOptionsClass, "paddingBottom", "F");
|
paddingBottomID = env->GetFieldID(jLayoutOptionsClass, "paddingBottom", "F");
|
||||||
arrowColorID = env->GetFieldID(jLayoutOptionsClass, "arrowColor", "I");
|
arrowColorID = env->GetFieldID(jLayoutOptionsClass, "arrowColor", "I");
|
||||||
arrowBackgroundHoveredColorID = env->GetFieldID(jLayoutOptionsClass, "arrowBackgroundHoveredColor", "I");
|
arrowBackgroundHoveredColorID = env->GetFieldID(jLayoutOptionsClass, "arrowBackgroundHoveredColor", "I");
|
||||||
arrowBackgroundClickedColorID = env->GetFieldID(jLayoutOptionsClass, "arrowBackgroundClickedColor", "I");
|
arrowBackgroundClickedColorID = env->GetFieldID(jLayoutOptionsClass, "arrowBackgroundClickedColor", "I");
|
||||||
frameColorID = env->GetFieldID(jLayoutOptionsClass, "frameColor", "I");
|
frameColorID = env->GetFieldID(jLayoutOptionsClass, "frameColor", "I");
|
||||||
borderColorID = env->GetFieldID(jLayoutOptionsClass, "borderColor", "I");
|
borderColorID = env->GetFieldID(jLayoutOptionsClass, "borderColor", "I");
|
||||||
borderRoundID = env->GetFieldID(jLayoutOptionsClass, "borderRound", "I");
|
borderRoundID = env->GetFieldID(jLayoutOptionsClass, "borderRound", "I");
|
||||||
roundingCornersID = env->GetFieldID(jLayoutOptionsClass, "roundingCorners", "I");
|
roundingCornersID = env->GetFieldID(jLayoutOptionsClass, "roundingCorners", "I");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static {
|
static {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static native void ShowLayoutDebug() /*-{ }-*/; /*
|
static native void ShowLayoutDebug() /*-{ }-*/; /*
|
||||||
ImGuiEx::ShowLayoutDebug();
|
ImGuiEx::ShowLayoutDebug();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void BeginLayout(String id, float sizeX, float sizeY); /*-{ }-*/; /*
|
static native void BeginLayout(String id, float sizeX, float sizeY); /*-{ }-*/; /*
|
||||||
ImGuiEx::BeginLayout(id, sizeX, sizeY);
|
ImGuiEx::BeginLayout(id, sizeX, sizeY);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void BeginLayout(String id, float sizeX, float sizeY, float paddingLeft, float paddingRight, float paddingTop, float paddingBottom); /*-{ }-*/; /*
|
static native void BeginLayout(String id, float sizeX, float sizeY, float paddingLeft, float paddingRight, float paddingTop, float paddingBottom); /*-{ }-*/; /*
|
||||||
ImGuiEx::BeginLayout(id, sizeX, sizeY, paddingLeft, paddingRight, paddingTop, paddingBottom);
|
ImGuiEx::BeginLayout(id, sizeX, sizeY, paddingLeft, paddingRight, paddingTop, paddingBottom);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void EndLayout(); /*-{ }-*/; /*
|
static native void EndLayout(); /*-{ }-*/; /*
|
||||||
ImGuiEx::EndLayout();
|
ImGuiEx::EndLayout();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native boolean BeginCollapseLayoutEx2(String title, float sizeX, float sizeY, ImGuiCollapseLayoutOptions jOptions); /*-{ }-*/; /*
|
static native boolean BeginCollapseLayoutEx2(String title, float sizeX, float sizeY, ImGuiCollapseLayoutOptions jOptions); /*-{ }-*/; /*
|
||||||
ImGuiCollapseLayoutOptions options;
|
ImGuiCollapseLayoutOptions options;
|
||||||
options.paddingLeft = env->GetFloatField (jOptions, paddingLeftID);
|
options.paddingLeft = env->GetFloatField (jOptions, paddingLeftID);
|
||||||
options.paddingRight = env->GetFloatField (jOptions, paddingRightID);
|
options.paddingRight = env->GetFloatField (jOptions, paddingRightID);
|
||||||
options.paddingTop = env->GetFloatField (jOptions, paddingTopID);
|
options.paddingTop = env->GetFloatField (jOptions, paddingTopID);
|
||||||
options.paddingBottom = env->GetFloatField (jOptions, paddingBottomID);
|
options.paddingBottom = env->GetFloatField (jOptions, paddingBottomID);
|
||||||
options.arrowColor = env->GetIntField (jOptions, arrowColorID);
|
options.arrowColor = env->GetIntField (jOptions, arrowColorID);
|
||||||
options.arrowBackgroundHoveredColor = env->GetIntField (jOptions, arrowBackgroundHoveredColorID);
|
options.arrowBackgroundHoveredColor = env->GetIntField (jOptions, arrowBackgroundHoveredColorID);
|
||||||
options.arrowBackgroundClickedColor = env->GetIntField (jOptions, arrowBackgroundClickedColorID);
|
options.arrowBackgroundClickedColor = env->GetIntField (jOptions, arrowBackgroundClickedColorID);
|
||||||
options.frameColor = env->GetIntField (jOptions, frameColorID);
|
options.frameColor = env->GetIntField (jOptions, frameColorID);
|
||||||
options.borderColor = env->GetIntField (jOptions, borderColorID);
|
options.borderColor = env->GetIntField (jOptions, borderColorID);
|
||||||
options.borderRound = env->GetIntField (jOptions, borderRoundID);
|
options.borderRound = env->GetIntField (jOptions, borderRoundID);
|
||||||
options.roundingCorners = env->GetIntField (jOptions, roundingCornersID);
|
options.roundingCorners = env->GetIntField (jOptions, roundingCornersID);
|
||||||
return ImGuiEx::BeginCollapseLayoutEx(title, sizeX, sizeY, options);
|
return ImGuiEx::BeginCollapseLayoutEx(title, sizeX, sizeY, options);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void BeginCollapseLayoutEx(boolean [] isOpen, String title, float sizeX, float sizeY, ImGuiCollapseLayoutOptions jOptions); /*-{ }-*/; /*
|
static native void BeginCollapseLayoutEx(boolean [] isOpen, String title, float sizeX, float sizeY, ImGuiCollapseLayoutOptions jOptions); /*-{ }-*/; /*
|
||||||
ImGuiCollapseLayoutOptions options;
|
ImGuiCollapseLayoutOptions options;
|
||||||
options.paddingLeft = env->GetFloatField (jOptions, paddingLeftID);
|
options.paddingLeft = env->GetFloatField (jOptions, paddingLeftID);
|
||||||
options.paddingRight = env->GetFloatField (jOptions, paddingRightID);
|
options.paddingRight = env->GetFloatField (jOptions, paddingRightID);
|
||||||
options.paddingTop = env->GetFloatField (jOptions, paddingTopID);
|
options.paddingTop = env->GetFloatField (jOptions, paddingTopID);
|
||||||
options.paddingBottom = env->GetFloatField (jOptions, paddingBottomID);
|
options.paddingBottom = env->GetFloatField (jOptions, paddingBottomID);
|
||||||
options.arrowColor = env->GetIntField (jOptions, arrowColorID);
|
options.arrowColor = env->GetIntField (jOptions, arrowColorID);
|
||||||
options.arrowBackgroundHoveredColor = env->GetIntField (jOptions, arrowBackgroundHoveredColorID);
|
options.arrowBackgroundHoveredColor = env->GetIntField (jOptions, arrowBackgroundHoveredColorID);
|
||||||
options.arrowBackgroundClickedColor = env->GetIntField (jOptions, arrowBackgroundClickedColorID);
|
options.arrowBackgroundClickedColor = env->GetIntField (jOptions, arrowBackgroundClickedColorID);
|
||||||
options.frameColor = env->GetIntField (jOptions, frameColorID);
|
options.frameColor = env->GetIntField (jOptions, frameColorID);
|
||||||
options.borderColor = env->GetIntField (jOptions, borderColorID);
|
options.borderColor = env->GetIntField (jOptions, borderColorID);
|
||||||
options.borderRound = env->GetIntField (jOptions, borderRoundID);
|
options.borderRound = env->GetIntField (jOptions, borderRoundID);
|
||||||
options.roundingCorners = env->GetIntField (jOptions, roundingCornersID);
|
options.roundingCorners = env->GetIntField (jOptions, roundingCornersID);
|
||||||
ImGuiEx::BeginCollapseLayoutEx(&isOpen[0], title, sizeX, sizeY, options);
|
ImGuiEx::BeginCollapseLayoutEx(&isOpen[0], title, sizeX, sizeY, options);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native boolean BeginCollapseLayout2(String title, float sizeX, float sizeY, ImGuiCollapseLayoutOptions jOptions); /*-{ }-*/; /*
|
static native boolean BeginCollapseLayout2(String title, float sizeX, float sizeY, ImGuiCollapseLayoutOptions jOptions); /*-{ }-*/; /*
|
||||||
ImGuiCollapseLayoutOptions options;
|
ImGuiCollapseLayoutOptions options;
|
||||||
options.paddingLeft = env->GetFloatField (jOptions, paddingLeftID);
|
options.paddingLeft = env->GetFloatField (jOptions, paddingLeftID);
|
||||||
options.paddingRight = env->GetFloatField (jOptions, paddingRightID);
|
options.paddingRight = env->GetFloatField (jOptions, paddingRightID);
|
||||||
options.paddingTop = env->GetFloatField (jOptions, paddingTopID);
|
options.paddingTop = env->GetFloatField (jOptions, paddingTopID);
|
||||||
options.paddingBottom = env->GetFloatField (jOptions, paddingBottomID);
|
options.paddingBottom = env->GetFloatField (jOptions, paddingBottomID);
|
||||||
options.arrowColor = env->GetIntField (jOptions, arrowColorID);
|
options.arrowColor = env->GetIntField (jOptions, arrowColorID);
|
||||||
options.arrowBackgroundHoveredColor = env->GetIntField (jOptions, arrowBackgroundHoveredColorID);
|
options.arrowBackgroundHoveredColor = env->GetIntField (jOptions, arrowBackgroundHoveredColorID);
|
||||||
options.arrowBackgroundClickedColor = env->GetIntField (jOptions, arrowBackgroundClickedColorID);
|
options.arrowBackgroundClickedColor = env->GetIntField (jOptions, arrowBackgroundClickedColorID);
|
||||||
options.frameColor = env->GetIntField (jOptions, frameColorID);
|
options.frameColor = env->GetIntField (jOptions, frameColorID);
|
||||||
options.borderColor = env->GetIntField (jOptions, borderColorID);
|
options.borderColor = env->GetIntField (jOptions, borderColorID);
|
||||||
options.borderRound = env->GetIntField (jOptions, borderRoundID);
|
options.borderRound = env->GetIntField (jOptions, borderRoundID);
|
||||||
options.roundingCorners = env->GetIntField (jOptions, roundingCornersID);
|
options.roundingCorners = env->GetIntField (jOptions, roundingCornersID);
|
||||||
return ImGuiEx::BeginCollapseLayout(title, sizeX, sizeY, options);
|
return ImGuiEx::BeginCollapseLayout(title, sizeX, sizeY, options);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void BeginCollapseLayout(boolean [] isOpen, String title, float sizeX, float sizeY, ImGuiCollapseLayoutOptions jOptions); /*-{ }-*/; /*
|
static native void BeginCollapseLayout(boolean [] isOpen, String title, float sizeX, float sizeY, ImGuiCollapseLayoutOptions jOptions); /*-{ }-*/; /*
|
||||||
ImGuiCollapseLayoutOptions options;
|
ImGuiCollapseLayoutOptions options;
|
||||||
options.paddingLeft = env->GetFloatField (jOptions, paddingLeftID);
|
options.paddingLeft = env->GetFloatField (jOptions, paddingLeftID);
|
||||||
options.paddingRight = env->GetFloatField (jOptions, paddingRightID);
|
options.paddingRight = env->GetFloatField (jOptions, paddingRightID);
|
||||||
options.paddingTop = env->GetFloatField (jOptions, paddingTopID);
|
options.paddingTop = env->GetFloatField (jOptions, paddingTopID);
|
||||||
options.paddingBottom = env->GetFloatField (jOptions, paddingBottomID);
|
options.paddingBottom = env->GetFloatField (jOptions, paddingBottomID);
|
||||||
options.arrowColor = env->GetIntField (jOptions, arrowColorID);
|
options.arrowColor = env->GetIntField (jOptions, arrowColorID);
|
||||||
options.arrowBackgroundHoveredColor = env->GetIntField (jOptions, arrowBackgroundHoveredColorID);
|
options.arrowBackgroundHoveredColor = env->GetIntField (jOptions, arrowBackgroundHoveredColorID);
|
||||||
options.arrowBackgroundClickedColor = env->GetIntField (jOptions, arrowBackgroundClickedColorID);
|
options.arrowBackgroundClickedColor = env->GetIntField (jOptions, arrowBackgroundClickedColorID);
|
||||||
options.frameColor = env->GetIntField (jOptions, frameColorID);
|
options.frameColor = env->GetIntField (jOptions, frameColorID);
|
||||||
options.borderColor = env->GetIntField (jOptions, borderColorID);
|
options.borderColor = env->GetIntField (jOptions, borderColorID);
|
||||||
options.borderRound = env->GetIntField (jOptions, borderRoundID);
|
options.borderRound = env->GetIntField (jOptions, borderRoundID);
|
||||||
options.roundingCorners = env->GetIntField (jOptions, roundingCornersID);
|
options.roundingCorners = env->GetIntField (jOptions, roundingCornersID);
|
||||||
ImGuiEx::BeginCollapseLayout(&isOpen[0], title, sizeX, sizeY, options);
|
ImGuiEx::BeginCollapseLayout(&isOpen[0], title, sizeX, sizeY, options);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void EndCollapseFrameLayout(); /*-{ }-*/; /*
|
static native void EndCollapseFrameLayout(); /*-{ }-*/; /*
|
||||||
ImGuiEx::EndCollapseFrameLayout();
|
ImGuiEx::EndCollapseFrameLayout();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void EndCollapseLayout(); /*-{ }-*/; /*
|
static native void EndCollapseLayout(); /*-{ }-*/; /*
|
||||||
ImGuiEx::EndCollapseLayout();
|
ImGuiEx::EndCollapseLayout();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void BeginAlign(String id, float sizeX, float sizeY, float alignX, float alignY) /*-{ }-*/; /*
|
static native void BeginAlign(String id, float sizeX, float sizeY, float alignX, float alignY) /*-{ }-*/; /*
|
||||||
ImGuiEx::BeginAlign(id, sizeX, sizeY, alignX, alignY);
|
ImGuiEx::BeginAlign(id, sizeX, sizeY, alignX, alignY);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void BeginAlign(String id, float sizeX, float sizeY, float alignX, float alignY, float offsetX, float offsetY) /*-{ }-*/; /*
|
static native void BeginAlign(String id, float sizeX, float sizeY, float alignX, float alignY, float offsetX, float offsetY) /*-{ }-*/; /*
|
||||||
ImGuiEx::BeginAlign(id, sizeX, sizeY, alignX, alignY, offsetX, offsetY);
|
ImGuiEx::BeginAlign(id, sizeX, sizeY, alignX, alignY, offsetX, offsetY);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void EndAlign() /*-{ }-*/; /*
|
static native void EndAlign() /*-{ }-*/; /*
|
||||||
ImGuiEx::EndAlign();
|
ImGuiEx::EndAlign();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void AlignLayout(float alignX, float alignY) /*-{ }-*/; /*
|
static native void AlignLayout(float alignX, float alignY) /*-{ }-*/; /*
|
||||||
ImGuiEx::AlignLayout(alignX, alignY);
|
ImGuiEx::AlignLayout(alignX, alignY);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static native void AlignLayout(float alignX, float alignY, float offsetX, float offsetY) /*-{ }-*/; /*
|
static native void AlignLayout(float alignX, float alignY, float offsetX, float offsetY) /*-{ }-*/; /*
|
||||||
ImGuiEx::AlignLayout(alignX, alignY, offsetX, offsetY);
|
ImGuiEx::AlignLayout(alignX, alignY, offsetX, offsetY);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public static class ImGuiCollapseLayoutOptions {
|
public static class ImGuiCollapseLayoutOptions {
|
||||||
public float paddingLeft = 2;
|
public float paddingLeft = 2;
|
||||||
public float paddingRight = 2;
|
public float paddingRight = 2;
|
||||||
public float paddingTop = 2;
|
public float paddingTop = 2;
|
||||||
public float paddingBottom = 2;
|
public float paddingBottom = 2;
|
||||||
public int arrowColor = ImGuiEx.colorToIntBits(0xFF, 0xFF, 0xFF, 0xFF);
|
public int arrowColor = ImGuiEx.colorToIntBits(0xFF, 0xFF, 0xFF, 0xFF);
|
||||||
public int arrowBackgroundHoveredColor = ImGuiEx.colorToIntBits(0x77, 0x77, 0x77, 0xFF);
|
public int arrowBackgroundHoveredColor = ImGuiEx.colorToIntBits(0x77, 0x77, 0x77, 0xFF);
|
||||||
public int arrowBackgroundClickedColor = ImGuiEx.colorToIntBits(0x55, 0x55, 0x55, 0xFF);
|
public int arrowBackgroundClickedColor = ImGuiEx.colorToIntBits(0x55, 0x55, 0x55, 0xFF);
|
||||||
public int frameColor = ImGuiEx.colorToIntBits(0x24, 0x24, 0x24, 0xFF);
|
public int frameColor = ImGuiEx.colorToIntBits(0x24, 0x24, 0x24, 0xFF);
|
||||||
public int borderColor = ImGuiEx.colorToIntBits(0x40, 0x40, 0x49, 0xFF);
|
public int borderColor = ImGuiEx.colorToIntBits(0x40, 0x40, 0x49, 0xFF);
|
||||||
public int borderRound = 4;
|
public int borderRound = 4;
|
||||||
public int roundingCorners = ImDrawCornerFlags.TopLeft.or(ImDrawCornerFlags.TopRight).getValue();
|
public int roundingCorners = ImDrawCornerFlags.TopLeft.or(ImDrawCornerFlags.TopRight).getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,23 +6,23 @@ package imgui;
|
|||||||
class NativeInternal {
|
class NativeInternal {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
|
|
||||||
/*JNI
|
/*JNI
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <imgui_internal.h>
|
#include <imgui_internal.h>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static native void PushMultiItemsWidths(int components, float w_full) /*-{ }-*/; /*
|
public static native void PushMultiItemsWidths(int components, float w_full) /*-{ }-*/; /*
|
||||||
ImGui::PushMultiItemsWidths(components, w_full);
|
ImGui::PushMultiItemsWidths(components, w_full);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static native boolean ItemAdd(float x1, float y1, float x2, float y2, String id) /*-{ }-*/; /*
|
public static native boolean ItemAdd(float x1, float y1, float x2, float y2, String id) /*-{ }-*/; /*
|
||||||
ImGuiID imGuiID = ImGui::GetID(id);
|
ImGuiID imGuiID = ImGui::GetID(id);
|
||||||
return ImGui::ItemAdd(ImRect(x1, y1, x2, y2), imGuiID);
|
return ImGui::ItemAdd(ImRect(x1, y1, x2, y2), imGuiID);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static native void ItemSize(float x1, float y1, float x2, float y2, float text_offset_y) /*-{ }-*/; /*
|
public static native void ItemSize(float x1, float y1, float x2, float y2, float text_offset_y) /*-{ }-*/; /*
|
||||||
ImGui::ItemSize(ImRect(x1, y1, x2, y2), text_offset_y);
|
ImGui::ItemSize(ImRect(x1, y1, x2, y2), text_offset_y);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ public class ImGuiHoveredFlags {
|
|||||||
public static ImGuiHoveredFlags RootWindow = new ImGuiHoveredFlags(1 << 1);
|
public static ImGuiHoveredFlags RootWindow = new ImGuiHoveredFlags(1 << 1);
|
||||||
public static ImGuiHoveredFlags AnyWindow = new ImGuiHoveredFlags(1 << 2);
|
public static ImGuiHoveredFlags AnyWindow = new ImGuiHoveredFlags(1 << 2);
|
||||||
public static ImGuiHoveredFlags AllowWhenBlockedByPopup = new ImGuiHoveredFlags(1 << 3);
|
public static ImGuiHoveredFlags AllowWhenBlockedByPopup = new ImGuiHoveredFlags(1 << 3);
|
||||||
// public static ImGuiHoveredFlags AllowWhenBlockedByModal = new ImGuiHoveredFlags(1 << 4);
|
// public static ImGuiHoveredFlags AllowWhenBlockedByModal = new ImGuiHoveredFlags(1 << 4);
|
||||||
public static ImGuiHoveredFlags AllowWhenBlockedByActiveItem = new ImGuiHoveredFlags(1 << 5);
|
public static ImGuiHoveredFlags AllowWhenBlockedByActiveItem = new ImGuiHoveredFlags(1 << 5);
|
||||||
public static ImGuiHoveredFlags AllowWhenOverlapped = new ImGuiHoveredFlags(1 << 6);
|
public static ImGuiHoveredFlags AllowWhenOverlapped = new ImGuiHoveredFlags(1 << 6);
|
||||||
public static ImGuiHoveredFlags AllowWhenDisabled = new ImGuiHoveredFlags(1 << 7);
|
public static ImGuiHoveredFlags AllowWhenDisabled = new ImGuiHoveredFlags(1 << 7);
|
||||||
|
|||||||
@@ -4,36 +4,29 @@ package imgui.enums;
|
|||||||
* User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
|
* User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
|
||||||
*/
|
*/
|
||||||
public enum ImGuiKey {
|
public enum ImGuiKey {
|
||||||
Tab(0),
|
Tab,
|
||||||
LeftArrow(1),
|
LeftArrow,
|
||||||
RightArrow(2),
|
RightArrow,
|
||||||
UpArrow(3),
|
UpArrow,
|
||||||
DownArrow(4),
|
DownArrow,
|
||||||
PageUp(5),
|
PageUp,
|
||||||
PageDown(6),
|
PageDown,
|
||||||
Home(7),
|
Home,
|
||||||
End(8),
|
End,
|
||||||
Insert(9),
|
Insert,
|
||||||
Delete(10),
|
Delete,
|
||||||
Backspace(11),
|
Backspace,
|
||||||
Space(12),
|
Space,
|
||||||
Enter(13),
|
Enter,
|
||||||
Escape(14),
|
Escape,
|
||||||
A(15),
|
KeyPadEnter,
|
||||||
C(16),
|
A,
|
||||||
V(17),
|
C,
|
||||||
X(18),
|
V,
|
||||||
Y(19),
|
X,
|
||||||
Z(20),
|
Y,
|
||||||
COUNT(21);
|
Z,
|
||||||
|
COUNT;
|
||||||
|
|
||||||
private final int code;
|
public final int code = ordinal();
|
||||||
|
|
||||||
ImGuiKey(int code) {
|
|
||||||
this.code = code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getValue() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -16,8 +16,8 @@ public class ImGuiTreeNodeFlags {
|
|||||||
public static ImGuiTreeNodeFlags Leaf = new ImGuiTreeNodeFlags(1 << 8);
|
public static ImGuiTreeNodeFlags Leaf = new ImGuiTreeNodeFlags(1 << 8);
|
||||||
public static ImGuiTreeNodeFlags Bullet = new ImGuiTreeNodeFlags(1 << 9);
|
public static ImGuiTreeNodeFlags Bullet = new ImGuiTreeNodeFlags(1 << 9);
|
||||||
public static ImGuiTreeNodeFlags FramePadding = new ImGuiTreeNodeFlags(1 << 10);
|
public static ImGuiTreeNodeFlags FramePadding = new ImGuiTreeNodeFlags(1 << 10);
|
||||||
// public static ImGuiTreeNodeFlags SpanAllAvailWidth = new ImGuiTreeNodeFlags(1 << 11);
|
// public static ImGuiTreeNodeFlags SpanAllAvailWidth = new ImGuiTreeNodeFlags(1 << 11);
|
||||||
// public static ImGuiTreeNodeFlags NoScrollOnOpen = new ImGuiTreeNodeFlags(1 << 12);
|
// public static ImGuiTreeNodeFlags NoScrollOnOpen = new ImGuiTreeNodeFlags(1 << 12);
|
||||||
public static ImGuiTreeNodeFlags NavLeftJumpsBackHere = new ImGuiTreeNodeFlags(1 << 13);
|
public static ImGuiTreeNodeFlags NavLeftJumpsBackHere = new ImGuiTreeNodeFlags(1 << 13);
|
||||||
public static ImGuiTreeNodeFlags CollapsingHeader = new ImGuiTreeNodeFlags(Framed.getValue() | NoTreePushOnOpen.getValue() | NoAutoOpenOnLog.getValue());
|
public static ImGuiTreeNodeFlags CollapsingHeader = new ImGuiTreeNodeFlags(Framed.getValue() | NoTreePushOnOpen.getValue() | NoAutoOpenOnLog.getValue());
|
||||||
private static ImGuiTreeNodeFlags Custom = new ImGuiTreeNodeFlags(0);
|
private static ImGuiTreeNodeFlags Custom = new ImGuiTreeNodeFlags(0);
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
import org.lwjgl.glfw.GLFWKeyCallback;
|
|
||||||
import org.lwjgl.glfw.GLFWMouseButtonCallback;
|
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.*;
|
|
||||||
|
|
||||||
public class InputHandler {
|
|
||||||
private static long window;
|
|
||||||
private static final int KEYBOARD_SIZE = 512;
|
|
||||||
private static final int MOUSE_SIZE = 16;
|
|
||||||
|
|
||||||
private static int[] keyStates = new int[KEYBOARD_SIZE];
|
|
||||||
private static boolean[] activeKeys = new boolean[KEYBOARD_SIZE];
|
|
||||||
|
|
||||||
private static int[] mouseButtonStates = new int[MOUSE_SIZE];
|
|
||||||
private static boolean[] activeMouseButtons = new boolean[MOUSE_SIZE];
|
|
||||||
private static long lastMouseNS = 0;
|
|
||||||
private static long mouseDoubleClickPeriodNS = 1000000000 / 5; //5th of a second for double click.
|
|
||||||
|
|
||||||
private static int NO_STATE = -1;
|
|
||||||
|
|
||||||
protected static GLFWKeyCallback keyboard = new GLFWKeyCallback()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void invoke(long window, int key, int scancode, int action, int mods)
|
|
||||||
{
|
|
||||||
activeKeys[key] = action != GLFW_RELEASE;
|
|
||||||
keyStates[key] = action;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
protected static GLFWMouseButtonCallback mouse = new GLFWMouseButtonCallback()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void invoke(long window, int button, int action, int mods)
|
|
||||||
{
|
|
||||||
activeMouseButtons[button] = action != GLFW_RELEASE;
|
|
||||||
mouseButtonStates[button] = action;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
protected static void init(long window)
|
|
||||||
{
|
|
||||||
InputHandler.window = window;
|
|
||||||
resetKeyboard();
|
|
||||||
resetMouse();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void update()
|
|
||||||
{
|
|
||||||
resetKeyboard();
|
|
||||||
resetMouse();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void resetKeyboard()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < keyStates.length; i++)
|
|
||||||
{
|
|
||||||
keyStates[i] = NO_STATE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void resetMouse()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < mouseButtonStates.length; i++)
|
|
||||||
{
|
|
||||||
mouseButtonStates[i] = NO_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
long now = System.nanoTime();
|
|
||||||
|
|
||||||
if (now - lastMouseNS > mouseDoubleClickPeriodNS)
|
|
||||||
lastMouseNS = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean keyDown(int key)
|
|
||||||
{
|
|
||||||
return activeKeys[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean keyPressed(int key)
|
|
||||||
{
|
|
||||||
return keyStates[key] == GLFW_PRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean keyReleased(int key)
|
|
||||||
{
|
|
||||||
return keyStates[key] == GLFW_RELEASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean mouseButtonDown(int button)
|
|
||||||
{
|
|
||||||
return activeMouseButtons[button];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean mouseButtonPressed(int button)
|
|
||||||
{
|
|
||||||
return mouseButtonStates[button] == GLFW_RELEASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean mouseButtonReleased(int button)
|
|
||||||
{
|
|
||||||
boolean flag = mouseButtonStates[button] == GLFW_RELEASE;
|
|
||||||
|
|
||||||
if (flag)
|
|
||||||
lastMouseNS = System.nanoTime();
|
|
||||||
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean mouseButtonDoubleClicked(int button)
|
|
||||||
{
|
|
||||||
long last = lastMouseNS;
|
|
||||||
boolean flag = mouseButtonReleased(button);
|
|
||||||
|
|
||||||
long now = System.nanoTime();
|
|
||||||
|
|
||||||
if (flag && now - last < mouseDoubleClickPeriodNS)
|
|
||||||
{
|
|
||||||
lastMouseNS = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
import imgui.DrawData;
|
|
||||||
import imgui.ImGui;
|
|
||||||
import imgui.gl3.ImGuiImplGl3;
|
|
||||||
import org.lwjgl.BufferUtils;
|
|
||||||
import org.lwjgl.Version;
|
|
||||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
|
||||||
import org.lwjgl.glfw.GLFWVidMode;
|
|
||||||
import org.lwjgl.opengl.GL;
|
|
||||||
import org.lwjgl.system.MemoryStack;
|
|
||||||
|
|
||||||
import java.nio.DoubleBuffer;
|
|
||||||
import java.nio.IntBuffer;
|
|
||||||
|
|
||||||
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
|
|
||||||
import static org.lwjgl.glfw.GLFW.*;
|
|
||||||
import static org.lwjgl.opengl.GL11.*;
|
|
||||||
import static org.lwjgl.system.MemoryStack.stackPush;
|
|
||||||
import static org.lwjgl.system.MemoryUtil.NULL;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
// The window handle
|
|
||||||
private long window;
|
|
||||||
private ImGuiImplGl3 imGuiGl = new ImGuiImplGl3();
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
System.out.println("Hello LWJGL " + Version.getVersion() + "!");
|
|
||||||
|
|
||||||
init();
|
|
||||||
loop();
|
|
||||||
|
|
||||||
// Free the window callbacks and destroy the window
|
|
||||||
glfwFreeCallbacks(window);
|
|
||||||
glfwDestroyWindow(window);
|
|
||||||
|
|
||||||
// Terminate GLFW and free the error callback
|
|
||||||
glfwTerminate();
|
|
||||||
glfwSetErrorCallback(null).free();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
// Setup an error callback. The default implementation
|
|
||||||
// will print the error message in System.err.
|
|
||||||
GLFWErrorCallback.createPrint(System.err).set();
|
|
||||||
|
|
||||||
// Initialize GLFW. Most GLFW functions will not work before doing this.
|
|
||||||
if (!glfwInit())
|
|
||||||
throw new IllegalStateException("Unable to initialize GLFW");
|
|
||||||
|
|
||||||
// Configure GLFW
|
|
||||||
glfwDefaultWindowHints(); // optional, the current window hints are already the default
|
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
|
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
|
|
||||||
|
|
||||||
// Create the window
|
|
||||||
window = glfwCreateWindow(1024, 768, "Hello World!", NULL, NULL);
|
|
||||||
if (window == NULL)
|
|
||||||
throw new RuntimeException("Failed to create the GLFW window");
|
|
||||||
|
|
||||||
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
|
|
||||||
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
|
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
|
|
||||||
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
|
|
||||||
});
|
|
||||||
|
|
||||||
glfwSetMouseButtonCallback(window, InputHandler.mouse);
|
|
||||||
|
|
||||||
// Get the thread stack and push a new frame
|
|
||||||
try (MemoryStack stack = stackPush()) {
|
|
||||||
IntBuffer pWidth = stack.mallocInt(1); // int*
|
|
||||||
IntBuffer pHeight = stack.mallocInt(1); // int*
|
|
||||||
|
|
||||||
// Get the window size passed to glfwCreateWindow
|
|
||||||
glfwGetWindowSize(window, pWidth, pHeight);
|
|
||||||
|
|
||||||
// Get the resolution of the primary monitor
|
|
||||||
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
|
||||||
|
|
||||||
// Center the window
|
|
||||||
glfwSetWindowPos(
|
|
||||||
window,
|
|
||||||
(vidmode.width() - pWidth.get(0)) / 2,
|
|
||||||
(vidmode.height() - pHeight.get(0)) / 2
|
|
||||||
);
|
|
||||||
} // the stack frame is popped automatically
|
|
||||||
|
|
||||||
// Make the OpenGL context current
|
|
||||||
glfwMakeContextCurrent(window);
|
|
||||||
// Enable v-sync
|
|
||||||
glfwSwapInterval(1);
|
|
||||||
InputHandler.init(window);
|
|
||||||
// Make the window visible
|
|
||||||
glfwShowWindow(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
long lastFrame = System.nanoTime();
|
|
||||||
|
|
||||||
public float getDelta() {
|
|
||||||
long time = System.nanoTime();
|
|
||||||
int delta_time = (int) ((time - lastFrame) / 1000000);
|
|
||||||
lastFrame = time;
|
|
||||||
return delta_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loop() {
|
|
||||||
// This line is critical for LWJGL's interoperation with GLFW's
|
|
||||||
// OpenGL context, or any context that is managed externally.
|
|
||||||
// LWJGL detects the context that is current in the current thread,
|
|
||||||
// creates the GLCapabilities instance and makes the OpenGL
|
|
||||||
// bindings available for use.
|
|
||||||
GL.createCapabilities();
|
|
||||||
|
|
||||||
ImGui.init();
|
|
||||||
imGuiGl.init();
|
|
||||||
|
|
||||||
// Set the clear color
|
|
||||||
glClearColor(.5f, 0.0f, 0f, 0.0f);
|
|
||||||
|
|
||||||
int[] win_width = new int[1], win_height = new int[1];
|
|
||||||
int[] width = new int[1], height = new int[1];
|
|
||||||
DoubleBuffer xBuffer = BufferUtils.createDoubleBuffer(1);
|
|
||||||
DoubleBuffer yBuffer = BufferUtils.createDoubleBuffer(1);
|
|
||||||
|
|
||||||
// Run the rendering loop until the user has attempted to close
|
|
||||||
// the window or has pressed the ESCAPE key.
|
|
||||||
while (!glfwWindowShouldClose(window)) {
|
|
||||||
xBuffer.clear();
|
|
||||||
yBuffer.clear();
|
|
||||||
|
|
||||||
InputHandler.update();
|
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
|
|
||||||
|
|
||||||
glfwGetWindowSize(window, win_width, win_height);
|
|
||||||
glfwGetFramebufferSize(window, width, height);
|
|
||||||
glfwGetCursorPos(window, xBuffer, yBuffer);
|
|
||||||
|
|
||||||
int mX = (int) xBuffer.get();
|
|
||||||
int mY = (int) yBuffer.get();
|
|
||||||
|
|
||||||
ImGui.UpdateDisplayAndInputAndFrame(getDelta(), win_width[0], win_height[0], width[0], height[0], mX, mY, InputHandler.mouseButtonDown(0), false, false);
|
|
||||||
ImGui.ShowDemoWindow();
|
|
||||||
ImGui.Render();
|
|
||||||
imGuiGl.render(ImGui.GetDrawData());
|
|
||||||
|
|
||||||
glfwSwapBuffers(window); // swap the color buffers
|
|
||||||
|
|
||||||
// Poll for window events. The key callback above will only be
|
|
||||||
// invoked during this call.
|
|
||||||
glfwPollEvents();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
new Main().run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,10 +10,10 @@ import java.util.Objects;
|
|||||||
import static org.lwjgl.opengl.GL30.*;
|
import static org.lwjgl.opengl.GL30.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class mostly a straightforward port of the https://raw.githubusercontent.com/ocornut/imgui/v1.74/examples/imgui_impl_opengl3.cpp adapted to Java and LWJGL realms.
|
* This class mostly a straightforward port of the https://raw.githubusercontent.com/ocornut/imgui/v1.74/examples/imgui_impl_opengl3.cpp adapted for Java and LWJGL realms.
|
||||||
* <p>
|
* <p>
|
||||||
* It do support a backup of the current GL state before rendering and restoring of its initial state after.
|
* It do support a backup of the current GL state before rendering and restoring of its initial state after.
|
||||||
* But some specific state variables may be missed (all which are hidden under '#ifdef' macros in the original imgui file).
|
* But some specific state variables may be missed (all which are hidden under '#ifdef' macros in the original 'imgui_impl_opengl3.cpp' file).
|
||||||
* <p>
|
* <p>
|
||||||
* By default this implementation uses shaders with 130 version of GLSL (OpenGL 3.0).
|
* By default this implementation uses shaders with 130 version of GLSL (OpenGL 3.0).
|
||||||
* You can provide your own shaders into the {@link ImGuiImplGl3#init(CharSequence, CharSequence)} method.
|
* You can provide your own shaders into the {@link ImGuiImplGl3#init(CharSequence, CharSequence)} method.
|
||||||
@@ -55,7 +55,7 @@ public class ImGuiImplGl3 {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method SHOULD be called before calling of {@link ImGuiImplGl3#render(DrawData)} method.
|
* This method SHOULD be called before calling of {@link ImGuiImplGl3#render(DrawData)} method.
|
||||||
* By using this method shaders with 130 version of GLSL will be used for render.
|
* By using this method shaders with 130 version of GLSL (OpenGL 3.0) will be used for render.
|
||||||
*/
|
*/
|
||||||
public void init() {
|
public void init() {
|
||||||
final CharSequence fragShaderSource = readFromResources("default.frag");
|
final CharSequence fragShaderSource = readFromResources("default.frag");
|
||||||
@@ -86,8 +86,8 @@ public class ImGuiImplGl3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||||
int fbWidth = (int) (drawData.displaySizeX * drawData.framebufferScaleX);
|
final int fbWidth = (int) (drawData.displaySizeX * drawData.framebufferScaleX);
|
||||||
int fbHeight = (int) (drawData.displaySizeY * drawData.framebufferScaleY);
|
final int fbHeight = (int) (drawData.displaySizeY * drawData.framebufferScaleY);
|
||||||
|
|
||||||
if (fbWidth <= 0 || fbHeight <= 0) {
|
if (fbWidth <= 0 || fbHeight <= 0) {
|
||||||
return;
|
return;
|
||||||
@@ -169,7 +169,7 @@ public class ImGuiImplGl3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this method in the end of your app working state to clear used resources.
|
* Call this method in the end of your app working state to dispose resources.
|
||||||
*/
|
*/
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
glDeleteTextures(gFontTexture);
|
glDeleteTextures(gFontTexture);
|
||||||
@@ -196,7 +196,7 @@ public class ImGuiImplGl3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void prepareFont() {
|
private void prepareFont() {
|
||||||
TexDataRGBA32 texData = new TexDataRGBA32();
|
final TexDataRGBA32 texData = new TexDataRGBA32();
|
||||||
ImGui.GetTexDataAsRGBA32(texData, texData.pixelBuffer);
|
ImGui.GetTexDataAsRGBA32(texData, texData.pixelBuffer);
|
||||||
|
|
||||||
gFontTexture = glGenTextures();
|
gFontTexture = glGenTextures();
|
||||||
@@ -314,20 +314,23 @@ public class ImGuiImplGl3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int loadAndCompileShader(final int type, final CharSequence source) {
|
private int loadAndCompileShader(final int type, final CharSequence source) {
|
||||||
int id = glCreateShader(type);
|
final int id = glCreateShader(type);
|
||||||
|
|
||||||
glShaderSource(id, source);
|
glShaderSource(id, source);
|
||||||
glCompileShader(id);
|
glCompileShader(id);
|
||||||
|
|
||||||
if (glGetShaderi(id, GL_COMPILE_STATUS) != GL_TRUE) {
|
if (glGetShaderi(id, GL_COMPILE_STATUS) != GL_TRUE) {
|
||||||
throw new IllegalStateException(glGetShaderInfoLog(id));
|
throw new IllegalStateException(glGetShaderInfoLog(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharSequence readFromResources(final String path) {
|
private CharSequence readFromResources(final String path) {
|
||||||
StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
try (InputStream in = getClass().getClassLoader().getResourceAsStream(path);
|
try (final InputStream in = getClass().getClassLoader().getResourceAsStream(path);
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(in)))) {
|
final BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(in)))) {
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
builder.append(line).append('\n');
|
builder.append(line).append('\n');
|
||||||
|
|||||||
@@ -0,0 +1,268 @@
|
|||||||
|
import imgui.ImGui;
|
||||||
|
import imgui.ImGuiString;
|
||||||
|
import imgui.enums.*;
|
||||||
|
import imgui.gl3.ImGuiImplGl3;
|
||||||
|
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||||
|
import org.lwjgl.glfw.GLFWVidMode;
|
||||||
|
import org.lwjgl.opengl.GL;
|
||||||
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
|
||||||
|
import static org.lwjgl.glfw.GLFW.*;
|
||||||
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
|
import static org.lwjgl.system.MemoryStack.stackPush;
|
||||||
|
import static org.lwjgl.system.MemoryUtil.NULL;
|
||||||
|
|
||||||
|
public class ImGuiGlfwExample {
|
||||||
|
private static final int DEFAULT_WIDTH = 1024;
|
||||||
|
private static final int DEFAULT_HEIGHT = 768;
|
||||||
|
|
||||||
|
private static final ImGuiString IMGUI_DEMO_LINK = new ImGuiString("https://raw.githubusercontent.com/ocornut/imgui/v1.74/imgui_demo.cpp");
|
||||||
|
|
||||||
|
private long window; // current GLFW window ID
|
||||||
|
|
||||||
|
// Those are used to track window size properties
|
||||||
|
private final int[] winWidth = new int[1];
|
||||||
|
private final int[] winHeight = new int[1];
|
||||||
|
private final int[] fbWidth = new int[1];
|
||||||
|
private final int[] fbHeight = new int[1];
|
||||||
|
|
||||||
|
// For mouse tracking
|
||||||
|
private final double[] mousePosX = new double[1];
|
||||||
|
private final double[] mousePosY = new double[1];
|
||||||
|
|
||||||
|
// TODO: move this into ImGuiIO.KeysDown
|
||||||
|
private boolean ctrlKeyDown;
|
||||||
|
private boolean shiftKeyDown;
|
||||||
|
private boolean altKeyDown;
|
||||||
|
private boolean superKeyDown;
|
||||||
|
|
||||||
|
private final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3();
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
initGlfw();
|
||||||
|
initImGui();
|
||||||
|
loop();
|
||||||
|
destroyImGui();
|
||||||
|
destroyGlfw();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method initializes GLFW window. All code is mostly a copy-paste from the official LWJGL3 website.
|
||||||
|
private void initGlfw() {
|
||||||
|
// Setup an error callback. The default implementation
|
||||||
|
// will print the error message in System.err.
|
||||||
|
GLFWErrorCallback.createPrint(System.err).set();
|
||||||
|
|
||||||
|
// Initialize GLFW. Most GLFW functions will not work before doing this.
|
||||||
|
if (!glfwInit()) {
|
||||||
|
throw new IllegalStateException("Unable to initialize GLFW");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure GLFW
|
||||||
|
glfwDefaultWindowHints(); // optional, the current window hints are already the default
|
||||||
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
|
||||||
|
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE); // the window will be maximized
|
||||||
|
|
||||||
|
// Create the window
|
||||||
|
window = glfwCreateWindow(DEFAULT_WIDTH, DEFAULT_HEIGHT, "ImGui+GLFW+LWJGL Example", NULL, NULL);
|
||||||
|
|
||||||
|
if (window == NULL) {
|
||||||
|
throw new RuntimeException("Failed to create the GLFW window");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the thread stack and push a new frame
|
||||||
|
try (final MemoryStack stack = stackPush()) {
|
||||||
|
final IntBuffer pWidth = stack.mallocInt(1); // int*
|
||||||
|
final IntBuffer pHeight = stack.mallocInt(1); // int*
|
||||||
|
|
||||||
|
// Get the window size passed to glfwCreateWindow
|
||||||
|
glfwGetWindowSize(window, pWidth, pHeight);
|
||||||
|
|
||||||
|
// Get the resolution of the primary monitor
|
||||||
|
GLFWVidMode vidmode = Objects.requireNonNull(glfwGetVideoMode(glfwGetPrimaryMonitor()));
|
||||||
|
|
||||||
|
// Center the window
|
||||||
|
glfwSetWindowPos(window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
|
||||||
|
} // the stack frame is popped automatically
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(window); // Make the OpenGL context current
|
||||||
|
glfwSwapInterval(GLFW_TRUE); // Enable v-sync
|
||||||
|
glfwShowWindow(window); // Make the window visible
|
||||||
|
|
||||||
|
// This line is critical for LWJGL's interoperation with GLFW's
|
||||||
|
// OpenGL context, or any context that is managed externally.
|
||||||
|
// LWJGL detects the context that is current in the current thread,
|
||||||
|
// creates the GLCapabilities instance and makes the OpenGL
|
||||||
|
// bindings available for use.
|
||||||
|
GL.createCapabilities();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here we will initialize ImGui stuff.
|
||||||
|
private void initImGui() {
|
||||||
|
// This line is critical for ImGui to work.
|
||||||
|
// It loads native library, creates ImGui context and does other necessary stuff.
|
||||||
|
ImGui.init();
|
||||||
|
|
||||||
|
// ImGui provides three different color schemas for styling. We will use the classic one here.
|
||||||
|
ImGui.StyleColorsClassic();
|
||||||
|
// ImGui.StyleColorsDark(); // This is a default style for ImGui
|
||||||
|
// ImGui.StyleColorsLight();
|
||||||
|
|
||||||
|
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
|
||||||
|
final int[] keys = new int[ImGuiKey.COUNT.code];
|
||||||
|
keys[ImGuiKey.Tab.code] = GLFW_KEY_TAB;
|
||||||
|
keys[ImGuiKey.LeftArrow.code] = GLFW_KEY_LEFT;
|
||||||
|
keys[ImGuiKey.RightArrow.code] = GLFW_KEY_RIGHT;
|
||||||
|
keys[ImGuiKey.UpArrow.code] = GLFW_KEY_UP;
|
||||||
|
keys[ImGuiKey.DownArrow.code] = GLFW_KEY_DOWN;
|
||||||
|
keys[ImGuiKey.PageUp.code] = GLFW_KEY_PAGE_UP;
|
||||||
|
keys[ImGuiKey.PageDown.code] = GLFW_KEY_PAGE_DOWN;
|
||||||
|
keys[ImGuiKey.Home.code] = GLFW_KEY_HOME;
|
||||||
|
keys[ImGuiKey.End.code] = GLFW_KEY_END;
|
||||||
|
keys[ImGuiKey.Insert.code] = GLFW_KEY_INSERT;
|
||||||
|
keys[ImGuiKey.Delete.code] = GLFW_KEY_DELETE;
|
||||||
|
keys[ImGuiKey.Backspace.code] = GLFW_KEY_BACKSPACE;
|
||||||
|
keys[ImGuiKey.Space.code] = GLFW_KEY_SPACE;
|
||||||
|
keys[ImGuiKey.Enter.code] = GLFW_KEY_ENTER;
|
||||||
|
keys[ImGuiKey.Escape.code] = GLFW_KEY_ESCAPE;
|
||||||
|
keys[ImGuiKey.KeyPadEnter.code] = GLFW_KEY_KP_ENTER;
|
||||||
|
keys[ImGuiKey.A.code] = GLFW_KEY_A;
|
||||||
|
keys[ImGuiKey.C.code] = GLFW_KEY_C;
|
||||||
|
keys[ImGuiKey.V.code] = GLFW_KEY_V;
|
||||||
|
keys[ImGuiKey.X.code] = GLFW_KEY_X;
|
||||||
|
keys[ImGuiKey.Y.code] = GLFW_KEY_Y;
|
||||||
|
keys[ImGuiKey.Z.code] = GLFW_KEY_Z;
|
||||||
|
ImGui.initKeyMap(keys);
|
||||||
|
|
||||||
|
// Here goes GLFW callbacks to update user input stuff in ImGui
|
||||||
|
glfwSetKeyCallback(window, (w, key, scancode, action, mods) -> {
|
||||||
|
final boolean isKeyDown = action == GLFW_PRESS;
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_LEFT_CONTROL || key == GLFW_KEY_RIGHT_CONTROL) {
|
||||||
|
ctrlKeyDown = isKeyDown;
|
||||||
|
} else if (key == GLFW_KEY_LEFT_SHIFT || key == GLFW_KEY_RIGHT_SHIFT) {
|
||||||
|
shiftKeyDown = isKeyDown;
|
||||||
|
} else if (key == GLFW_KEY_LEFT_ALT || key == GLFW_KEY_RIGHT_ALT) {
|
||||||
|
altKeyDown = isKeyDown;
|
||||||
|
} else if (key == GLFW_KEY_LEFT_SUPER || key == GLFW_KEY_RIGHT_SUPER) {
|
||||||
|
superKeyDown = isKeyDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.UpdateKey(key, isKeyDown, action == GLFW_RELEASE, ctrlKeyDown, shiftKeyDown, altKeyDown, superKeyDown);
|
||||||
|
});
|
||||||
|
|
||||||
|
glfwSetCharCallback(window, (w, c) -> {
|
||||||
|
if (c != GLFW_KEY_DELETE) {
|
||||||
|
ImGui.UpdateKeyTyped(c);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
glfwSetMouseButtonCallback(window, (w, button, action, mods) -> {
|
||||||
|
final boolean mouseDown0 = button == GLFW_MOUSE_BUTTON_1 && action != GLFW_RELEASE;
|
||||||
|
final boolean mouseDown1 = button == GLFW_MOUSE_BUTTON_2 && action != GLFW_RELEASE;
|
||||||
|
final boolean mouseDown2 = button == GLFW_MOUSE_BUTTON_3 && action != GLFW_RELEASE;
|
||||||
|
final boolean mouseDown3 = button == GLFW_MOUSE_BUTTON_4 && action != GLFW_RELEASE;
|
||||||
|
final boolean mouseDown4 = button == GLFW_MOUSE_BUTTON_5 && action != GLFW_RELEASE;
|
||||||
|
final boolean mouseDown5 = button == GLFW_MOUSE_BUTTON_6 && action != GLFW_RELEASE;
|
||||||
|
ImGui.UpdateMouseState(mouseDown0, mouseDown1, mouseDown2, mouseDown3, mouseDown4, mouseDown5);
|
||||||
|
|
||||||
|
if (!ImGui.GetIO().WantCaptureMouse && mouseDown1) {
|
||||||
|
ImGui.SetWindowFocus(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
glfwSetScrollCallback(window, (w, xOffset, yOffset) -> ImGui.UpdateScroll((float) xOffset, (float) yOffset));
|
||||||
|
|
||||||
|
// Initialize renderer itself
|
||||||
|
imGuiGl3.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loop() {
|
||||||
|
double time = 0; // to track our frame delta value
|
||||||
|
|
||||||
|
// Set the clear color
|
||||||
|
glClearColor(0.5f, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
// Run the rendering loop until the user has attempted to close the window
|
||||||
|
while (!glfwWindowShouldClose(window)) {
|
||||||
|
// Count frame delta value
|
||||||
|
final double currentTime = glfwGetTime();
|
||||||
|
final double deltaTime = (time > 0) ? (currentTime - time) : 1f / 60f;
|
||||||
|
time = currentTime;
|
||||||
|
|
||||||
|
// Get window size properties and mouse position
|
||||||
|
glfwGetWindowSize(window, winWidth, winHeight);
|
||||||
|
glfwGetFramebufferSize(window, fbWidth, fbHeight);
|
||||||
|
glfwGetCursorPos(window, mousePosX, mousePosY);
|
||||||
|
|
||||||
|
// IMPORTANT!!
|
||||||
|
// We SHOULD call those methods to update ImGui state for current frame
|
||||||
|
ImGui.UpdateImGui();
|
||||||
|
ImGui.UpdateDisplaySize(winWidth[0], winHeight[0], fbWidth[0], fbHeight[0]);
|
||||||
|
ImGui.UpdateMousePos((float) mousePosX[0], (float) mousePosY[0]);
|
||||||
|
ImGui.UpdateDeltaTime((float) deltaTime);
|
||||||
|
|
||||||
|
// Render itself starts here
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
|
||||||
|
|
||||||
|
// Any ImGui code SHOULD go between NewFrame()/Render() methods
|
||||||
|
ImGui.NewFrame();
|
||||||
|
|
||||||
|
ImGui.SetNextWindowSize(600, 200, ImGuiCond.Once);
|
||||||
|
ImGui.SetNextWindowPos(10, 10, ImGuiCond.Once);
|
||||||
|
|
||||||
|
ImGui.Begin("Custom window");
|
||||||
|
ImGui.Text("Hello from Java!");
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
ImGui.BeginChild("##custom_window_child", 200, 50);
|
||||||
|
if (ImGui.TreeNode("Simple..")) {
|
||||||
|
ImGui.TreeNodeEx("..tree", ImGuiTreeNodeFlags.Leaf.or(ImGuiTreeNodeFlags.Bullet).or(ImGuiTreeNodeFlags.NoTreePushOnOpen));
|
||||||
|
ImGui.TreePop();
|
||||||
|
}
|
||||||
|
ImGui.EndChild();
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
ImGui.Text("Consider to look the original ImGui demo: ");
|
||||||
|
ImGui.SetNextItemWidth(500);
|
||||||
|
ImGui.InputText("##input_to_copy_link", IMGUI_DEMO_LINK, ImGuiInputTextFlags.ReadOnly);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.Text("(?)");
|
||||||
|
if (ImGui.IsItemHovered()) {
|
||||||
|
ImGui.SetTooltip("You can copy and paste this link");
|
||||||
|
}
|
||||||
|
ImGui.End();
|
||||||
|
|
||||||
|
ImGui.ShowDemoWindow();
|
||||||
|
ImGui.Render();
|
||||||
|
|
||||||
|
imGuiGl3.render(ImGui.GetDrawData()); // render DrawData from ImGui into our OpenGL context
|
||||||
|
|
||||||
|
glfwSwapBuffers(window); // swap the color buffers
|
||||||
|
|
||||||
|
// Poll for window events. The key callback above will only be invoked during this call.
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you want to clean a room after yourself - do it by yourself
|
||||||
|
private void destroyImGui() {
|
||||||
|
imGuiGl3.dispose();
|
||||||
|
ImGui.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void destroyGlfw() {
|
||||||
|
glfwFreeCallbacks(window);
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
glfwTerminate();
|
||||||
|
Objects.requireNonNull(glfwSetErrorCallback(null)).free();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(final String[] args) {
|
||||||
|
new ImGuiGlfwExample().run();
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in new issue
Block a user