Skip to content

Commit f5d5c18

Browse files
committed
Tweak ImGuiImplGlfw
1 parent 0b478fd commit f5d5c18

File tree

2 files changed

+65
-62
lines changed

2 files changed

+65
-62
lines changed

imgui-lwjgl3/src/main/java/imgui/glfw/ImGuiImplGlfw.java

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
package imgui.glfw;
22

3+
import imgui.ImGui;
4+
import imgui.ImGuiIO;
5+
import imgui.ImVec2;
6+
import imgui.callback.ImStrConsumer;
7+
import imgui.callback.ImStrSupplier;
8+
import imgui.flag.ImGuiBackendFlags;
9+
import imgui.flag.ImGuiConfigFlags;
10+
import imgui.flag.ImGuiKey;
11+
import imgui.flag.ImGuiMouseButton;
12+
import imgui.flag.ImGuiMouseCursor;
13+
import imgui.flag.ImGuiNavInput;
14+
import org.lwjgl.glfw.GLFWCharCallback;
15+
import org.lwjgl.glfw.GLFWErrorCallback;
16+
import org.lwjgl.glfw.GLFWKeyCallback;
17+
import org.lwjgl.glfw.GLFWMouseButtonCallback;
18+
import org.lwjgl.glfw.GLFWScrollCallback;
19+
20+
import java.nio.ByteBuffer;
21+
import java.nio.FloatBuffer;
22+
323
import static org.lwjgl.glfw.GLFW.GLFW_ARROW_CURSOR;
424
import static org.lwjgl.glfw.GLFW.GLFW_CURSOR;
525
import static org.lwjgl.glfw.GLFW.GLFW_CURSOR_DISABLED;
@@ -65,37 +85,17 @@
6585
import static org.lwjgl.glfw.GLFW.glfwSetMouseButtonCallback;
6686
import static org.lwjgl.glfw.GLFW.glfwSetScrollCallback;
6787

68-
import imgui.ImGui;
69-
import imgui.ImGuiIO;
70-
import imgui.ImVec2;
71-
import imgui.callback.ImStrConsumer;
72-
import imgui.callback.ImStrSupplier;
73-
import imgui.flag.ImGuiBackendFlags;
74-
import imgui.flag.ImGuiConfigFlags;
75-
import imgui.flag.ImGuiKey;
76-
import imgui.flag.ImGuiMouseButton;
77-
import imgui.flag.ImGuiMouseCursor;
78-
import imgui.flag.ImGuiNavInput;
79-
import java.nio.ByteBuffer;
80-
import java.nio.FloatBuffer;
81-
import org.lwjgl.glfw.GLFWCharCallback;
82-
import org.lwjgl.glfw.GLFWErrorCallback;
83-
import org.lwjgl.glfw.GLFWKeyCallback;
84-
import org.lwjgl.glfw.GLFWMouseButtonCallback;
85-
import org.lwjgl.glfw.GLFWScrollCallback;
86-
8788
/**
8889
* This class is a straightforward port of the
8990
* <a href="https://raw.githubusercontent.com/ocornut/imgui/v1.76/examples/imgui_impl_glfw.cpp">imgui_impl_glfw.cpp</a>.
9091
* <p>
9192
* It supports clipboard, gamepad, mouse and keyboard in the same way the original Dear ImGui code does. You can copy-paste this class in your codebase and
9293
* modify the rendering routine in the way you'd like.
93-
* <p>
9494
*/
9595
public class ImGuiImplGlfw {
9696

9797
// Id of the current GLFW window
98-
private long windowId;
98+
private long windowPtr;
9999

100100
// For application window properties
101101
private final int[] winWidth = new int[1];
@@ -106,8 +106,12 @@ public class ImGuiImplGlfw {
106106
// Mouse cursors provided by GLFW
107107
private final long[] mouseCursors = new long[ImGuiMouseCursor.COUNT];
108108

109+
// Empty array to fill ImGuiIO.NavInputs with zeroes
110+
private final float[] emptyNavInputs = new float[ImGuiNavInput.COUNT];
111+
109112
// For mouse tracking
110113
private final boolean[] mouseJustPressed = new boolean[ImGuiMouseButton.COUNT];
114+
private final ImVec2 mousePosBackup = new ImVec2();
111115
private final double[] cursorPosX = new double[1];
112116
private final double[] cursorPosY = new double[1];
113117

@@ -142,8 +146,8 @@ public void scrollCallback(final long windowId, final double xOffset, final doub
142146
}
143147

144148
final ImGuiIO io = ImGui.getIO();
145-
io.setMouseWheelH((float) xOffset);
146-
io.setMouseWheel((float) yOffset);
149+
io.setMouseWheelH(io.getMouseWheelH() + (float) xOffset);
150+
io.setMouseWheel(io.getMouseWheel() + (float) yOffset);
147151
}
148152

149153
/**
@@ -155,10 +159,10 @@ public void keyCallback(final long windowId, final int key, final int scancode,
155159
}
156160

157161
final ImGuiIO io = ImGui.getIO();
162+
158163
if (action == GLFW_PRESS) {
159164
io.setKeysDown(key, true);
160-
}
161-
if (action == GLFW_RELEASE) {
165+
} else if (action == GLFW_RELEASE) {
162166
io.setKeysDown(key, false);
163167
}
164168

@@ -186,8 +190,7 @@ public void charCallback(final long windowId, final int c) {
186190
* Method takes two arguments, which should be a valid GLFW window pointer and a boolean indicating whether or not to install callbacks.
187191
*/
188192
public boolean init(final long windowId, final boolean installCallbacks) {
189-
this.windowId = windowId;
190-
time = 0.0;
193+
this.windowPtr = windowId;
191194

192195
final ImGuiIO io = ImGui.getIO();
193196

@@ -265,10 +268,10 @@ public void accept(final String str) {
265268
*/
266269
public void dispose() {
267270
if (callbacksInstalled) {
268-
glfwSetMouseButtonCallback(windowId, previousMouseButtonCallback);
269-
glfwSetScrollCallback(windowId, previousScrollCallback);
270-
glfwSetKeyCallback(windowId, previousKeyCallback);
271-
glfwSetCharCallback(windowId, previousCharCallback);
271+
glfwSetMouseButtonCallback(windowPtr, previousMouseButtonCallback);
272+
glfwSetScrollCallback(windowPtr, previousScrollCallback);
273+
glfwSetKeyCallback(windowPtr, previousKeyCallback);
274+
glfwSetCharCallback(windowPtr, previousCharCallback);
272275
callbacksInstalled = false;
273276
}
274277

@@ -279,73 +282,74 @@ public void dispose() {
279282

280283
private void updateMousePosAndButtons(final float scaleX, final float scaleY) {
281284
final ImGuiIO io = ImGui.getIO();
285+
282286
for (int i = 0; i < ImGuiMouseButton.COUNT; i++) {
283-
io.setMouseDown(i, mouseJustPressed[i] || glfwGetMouseButton(windowId, i) != 0);
287+
// If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
288+
io.setMouseDown(i, mouseJustPressed[i] || glfwGetMouseButton(windowPtr, i) != 0);
284289
mouseJustPressed[i] = false;
285290
}
286291

287-
final ImVec2 mousePosBackup = new ImVec2();
288292
io.getMousePos(mousePosBackup);
289293
io.setMousePos(-Float.MAX_VALUE, -Float.MAX_VALUE);
290294

291-
final boolean focused = glfwGetWindowAttrib(windowId, GLFW_FOCUSED) != 0;
295+
final boolean focused = glfwGetWindowAttrib(windowPtr, GLFW_FOCUSED) != 0;
292296
if (focused) {
293297
if (io.getWantSetMousePos()) {
294-
glfwSetCursorPos(windowId, mousePosBackup.x, mousePosBackup.y);
298+
glfwSetCursorPos(windowPtr, mousePosBackup.x, mousePosBackup.y);
295299
} else {
296-
glfwGetCursorPos(windowId, cursorPosX, cursorPosY);
300+
glfwGetCursorPos(windowPtr, cursorPosX, cursorPosY);
297301
io.setMousePos((float) cursorPosX[0] * scaleX, (float) cursorPosY[0] * scaleY);
298302
}
299303
}
300304
}
301305

302306
private void updateMouseCursor() {
303307
final ImGuiIO io = ImGui.getIO();
304-
final boolean noCursorChange = (io.getConfigFlags() & ImGuiConfigFlags.NoMouseCursorChange)
305-
== ImGuiConfigFlags.NoMouseCursorChange;
306-
final boolean cursorDisabled = glfwGetInputMode(windowId, GLFW_CURSOR) == GLFW_CURSOR_DISABLED;
308+
309+
final boolean noCursorChange = (io.getConfigFlags() & ImGuiConfigFlags.NoMouseCursorChange) == ImGuiConfigFlags.NoMouseCursorChange;
310+
final boolean cursorDisabled = glfwGetInputMode(windowPtr, GLFW_CURSOR) == GLFW_CURSOR_DISABLED;
311+
307312
if (noCursorChange || cursorDisabled) {
308313
return;
309314
}
310315

311316
final int cursor = ImGui.getMouseCursor();
317+
312318
if (cursor == ImGuiMouseCursor.None || io.getMouseDrawCursor()) {
313-
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
319+
glfwSetInputMode(windowPtr, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
314320
} else {
315-
glfwSetCursor(windowId, mouseCursors[cursor] != 0 ? mouseCursors[cursor]
316-
: mouseCursors[ImGuiMouseCursor.Arrow]);
317-
glfwSetInputMode(windowId, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
321+
glfwSetCursor(windowPtr, mouseCursors[cursor] != 0 ? mouseCursors[cursor] : mouseCursors[ImGuiMouseCursor.Arrow]);
322+
glfwSetInputMode(windowPtr, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
318323
}
319324
}
320325

321326
private void updateGamepads() {
322327
final ImGuiIO io = ImGui.getIO();
323328

324-
final float[] navInputs = new float[ImGuiNavInput.COUNT];
325-
io.setNavInputs(navInputs);
326-
327329
if ((io.getConfigFlags() & ImGuiConfigFlags.NavEnableGamepad) == 0) {
328330
return;
329331
}
330332

333+
io.setNavInputs(emptyNavInputs);
334+
331335
final ByteBuffer buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1);
332336
final int buttonsCount = buttons.limit();
333337

334338
final FloatBuffer axis = glfwGetJoystickAxes(GLFW_JOYSTICK_1);
335339
final int axisCount = axis.limit();
336340

337-
mapButton(ImGuiNavInput.Activate, 0, buttons, buttonsCount, io); // Cross / A
341+
mapButton(ImGuiNavInput.Activate, 0, buttons, buttonsCount, io); // Cross / A
338342
mapButton(ImGuiNavInput.Cancel, 1, buttons, buttonsCount, io); // Circle / B
339-
mapButton(ImGuiNavInput.Menu, 2, buttons, buttonsCount, io); // Square / X
340-
mapButton(ImGuiNavInput.Input, 3, buttons, buttonsCount, io); // Triangle / Y
341-
mapButton(ImGuiNavInput.DpadLeft, 13, buttons, buttonsCount, io); // D-Pad Left
342-
mapButton(ImGuiNavInput.DpadRight, 11, buttons, buttonsCount, io); // D-Pad Right
343+
mapButton(ImGuiNavInput.Menu, 2, buttons, buttonsCount, io); // Square / X
344+
mapButton(ImGuiNavInput.Input, 3, buttons, buttonsCount, io); // Triangle / Y
345+
mapButton(ImGuiNavInput.DpadLeft, 13, buttons, buttonsCount, io); // D-Pad Left
346+
mapButton(ImGuiNavInput.DpadRight, 11, buttons, buttonsCount, io); // D-Pad Right
343347
mapButton(ImGuiNavInput.DpadUp, 10, buttons, buttonsCount, io); // D-Pad Up
344-
mapButton(ImGuiNavInput.DpadDown, 12, buttons, buttonsCount, io); // D-Pad Down
345-
mapButton(ImGuiNavInput.FocusPrev, 4, buttons, buttonsCount, io); // L1 / LB
346-
mapButton(ImGuiNavInput.FocusNext, 5, buttons, buttonsCount, io); // R1 / RB
347-
mapButton(ImGuiNavInput.TweakSlow, 4, buttons, buttonsCount, io); // L1 / LB
348-
mapButton(ImGuiNavInput.TweakFast, 5, buttons, buttonsCount, io); // R1 / RB
348+
mapButton(ImGuiNavInput.DpadDown, 12, buttons, buttonsCount, io); // D-Pad Down
349+
mapButton(ImGuiNavInput.FocusPrev, 4, buttons, buttonsCount, io); // L1 / LB
350+
mapButton(ImGuiNavInput.FocusNext, 5, buttons, buttonsCount, io); // R1 / RB
351+
mapButton(ImGuiNavInput.TweakSlow, 4, buttons, buttonsCount, io); // L1 / LB
352+
mapButton(ImGuiNavInput.TweakFast, 5, buttons, buttonsCount, io); // R1 / RB
349353
mapAnalog(ImGuiNavInput.LStickLeft, 0, -0.3f, -0.9f, axis, axisCount, io);
350354
mapAnalog(ImGuiNavInput.LStickRight, 0, +0.3f, +0.9f, axis, axisCount, io);
351355
mapAnalog(ImGuiNavInput.LStickUp, 1, +0.3f, +0.9f, axis, axisCount, io);
@@ -390,11 +394,12 @@ public void newFrame() {
390394
final ImGuiIO io = ImGui.getIO();
391395
if (!io.getFonts().isBuilt()) {
392396
throw new IllegalStateException(
393-
"Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer init() method? e.g. ImGuiImplGl3.init().");
397+
"Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer init() method? e.g. ImGuiImplGl3.init()"
398+
);
394399
}
395400

396-
glfwGetWindowSize(windowId, winWidth, winHeight);
397-
glfwGetFramebufferSize(windowId, fbWidth, fbHeight);
401+
glfwGetWindowSize(windowPtr, winWidth, winHeight);
402+
glfwGetFramebufferSize(windowPtr, fbWidth, fbHeight);
398403

399404
final float scaleX = (float) fbWidth[0] / winWidth[0];
400405
final float scaleY = (float) fbHeight[0] / winHeight[0];
@@ -406,6 +411,7 @@ public void newFrame() {
406411

407412
final double currentTime = glfwGetTime();
408413
io.setDeltaTime(time > 0.0 ? (float) (currentTime - time) : 1.0f / 60.0f);
414+
time = currentTime;
409415

410416
updateMousePosAndButtons(scaleX, scaleY);
411417
updateMouseCursor();

imgui-lwjgl3/src/test/java/ImGuiGlfwExample.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import imgui.ImGui;
3333
import imgui.ImGuiFreeType;
3434
import imgui.ImGuiIO;
35-
import imgui.flag.ImGuiBackendFlags;
3635
import imgui.flag.ImGuiConfigFlags;
3736
import imgui.flag.ImGuiMouseCursor;
3837
import imgui.gl3.ImGuiImplGl3;
@@ -177,8 +176,6 @@ private void setupImGui() {
177176

178177
io.setIniFilename(null); // We don't want to save .ini file
179178
io.setConfigFlags(ImGuiConfigFlags.NavEnableKeyboard | ImGuiConfigFlags.DockingEnable); // Navigation with keyboard and enabled docking
180-
io.setBackendFlags(ImGuiBackendFlags.HasMouseCursors); // Mouse cursors to display while resizing windows etc.
181-
io.setBackendPlatformName("imgui_java_impl_glfw");
182179

183180
// ------------------------------------------------------------
184181
// Fonts configuration

0 commit comments

Comments
 (0)