diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2019-10-20 22:32:49 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2019-10-20 22:34:49 +0000 |
| commit | 407a006acdabd11a1cfd7b370834d7036c99ac96 (patch) | |
| tree | 1503fee58190fc3a6e3e8b85c6db20d06f4846e9 /src | |
| parent | add openGL3 impl (still failing) (diff) | |
| download | zig-imgui-407a006acdabd11a1cfd7b370834d7036c99ac96.tar.gz zig-imgui-407a006acdabd11a1cfd7b370834d7036c99ac96.zip | |
more glfw
Diffstat (limited to 'src')
| -rw-r--r-- | src/glfw_impl.zig | 143 | ||||
| -rw-r--r-- | src/main.zig | 2 |
2 files changed, 127 insertions, 18 deletions
diff --git a/src/glfw_impl.zig b/src/glfw_impl.zig index 9b79374..8bfbec2 100644 --- a/src/glfw_impl.zig +++ b/src/glfw_impl.zig @@ -1,5 +1,8 @@ const c = @import("c.zig"); const builtin = @import("builtin"); +const debug = @import("std").debug; +const math = @import("std").math; + pub const ClientApi = enum { Unknown, OpenGL, @@ -9,17 +12,17 @@ pub const ClientApi = enum { // Data var g_Window: ?*c.GLFWwindow = null; var g_ClientApi: ClientApi = .Unknown; -var g_Time: f32 = 0.0; +var g_Time: f64 = 0.0; var g_MouseJustPressed = [_]bool{ false } ** 5; var g_MouseCursors = [_]?*c.GLFWcursor{ null } ** @enumToInt(c.ImGuiMouseCursor_COUNT); var g_WantUpdateMonitors = true; // Chain GLFW callbacks for main viewport: // our callbacks will call the user's previously installed callbacks, if any. -var g_PrevUserCallbackMousebutton: ?c.GLFWmousebuttonfun = null; -var g_PrevUserCallbackScroll: ?c.GLFWscrollfun = null; -var g_PrevUserCallbackKey: ?c.GLFWkeyfun = null; -var g_PrevUserCallbackChar: ?c.GLFWcharfun = null; +var g_PrevUserCallbackMousebutton: c.GLFWmousebuttonfun = null; +var g_PrevUserCallbackScroll: c.GLFWscrollfun = null; +var g_PrevUserCallbackKey: c.GLFWkeyfun = null; +var g_PrevUserCallbackChar: c.GLFWcharfun = null; pub fn Init(window: *c.GLFWwindow, install_callbacks: bool, client_api: ClientApi) void { g_Window = window; @@ -29,8 +32,8 @@ pub fn Init(window: *c.GLFWwindow, install_callbacks: bool, client_api: ClientAp const io = c.igGetIO(); io.*.BackendFlags |= @enumToInt(c.ImGuiBackendFlags_HasMouseCursors); // We can honor GetMouseCursor() values (optional) io.*.BackendFlags |= @enumToInt(c.ImGuiBackendFlags_HasSetMousePos); // We can honor io.WantSetMousePos requests (optional, rarely used) - io.*.BackendFlags |= @enumToInt(c.ImGuiBackendFlags_PlatformHasViewports); // We can create multi-viewports on the Platform side (optional) - if (@hasField(c, "GLFW_HAS_GLFW_HOVERED") and builtin.os == builtin.Os.windows) { + if (false) io.*.BackendFlags |= @enumToInt(c.ImGuiBackendFlags_PlatformHasViewports); // We can create multi-viewports on the Platform side (optional) + if (false and @hasField(c, "GLFW_HAS_GLFW_HOVERED") and builtin.os == builtin.Os.windows) { io.*.BackendFlags |= @enumToInt(ImGuiBackendFlags_HasMouseHoveredViewport); // We can set io.MouseHoveredViewport correctly (optional, not easy) } io.*.BackendPlatformName = c"imgui_impl_glfw.zig"; @@ -62,7 +65,7 @@ pub fn Init(window: *c.GLFWwindow, install_callbacks: bool, client_api: ClientAp // @TODO: Clipboard // io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; // io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; - // io.ClipboardUserData = g_Window; + io.*.ClipboardUserData = g_Window; g_MouseCursors[@enumToInt(c.ImGuiMouseCursor_Arrow)] = c.glfwCreateStandardCursor(c.GLFW_ARROW_CURSOR); g_MouseCursors[@enumToInt(c.ImGuiMouseCursor_TextInput)] = c.glfwCreateStandardCursor(c.GLFW_IBEAM_CURSOR); @@ -88,13 +91,13 @@ pub fn Init(window: *c.GLFWwindow, install_callbacks: bool, client_api: ClientAp // Our mouse update function expect PlatformHandle to be filled for the main viewport const main_viewport = c.igGetMainViewport(); main_viewport.*.PlatformHandle = g_Window; - if (builtin.os == builtin.Os.windows) { + if (builtin.os == builtin.Os.windows) main_viewport.*.PlatformHandleRaw = c.glfwGetWin32Window(g_Window); - } // @TODO: Platform Interface (Viewport) - // if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable != 0) - // ImGui_ImplGlfw_InitPlatformInterface(); + if (io.*.ConfigFlags & @enumToInt(c.ImGuiConfigFlags_ViewportsEnable) != 0) + unreachable; + // ImGui_ImplGlfw_InitPlatformInterface(); g_ClientApi = client_api; } @@ -112,7 +115,7 @@ pub fn Shutdown() void { pub fn NewFrame() void { const io = c.igGetIO(); - // @TODO: assert font atlas + debug.assert(c.ImFontAtlas_IsBuilt(io.*.Fonts)); var w : c_int = undefined; var h : c_int = undefined; @@ -121,11 +124,111 @@ pub fn NewFrame() void { c.glfwGetWindowSize(g_Window, &w, &h); c.glfwGetFramebufferSize(g_Window, &display_w, &display_h); io.*.DisplaySize = c.ImVec2{ .x = @intToFloat(f32, w), .y = @intToFloat(f32, h) }; + + if (w > 0 and h > 0) + io.*.DisplayFramebufferScale = c.ImVec2{ + .x = @intToFloat(f32, display_w) / @intToFloat(f32, w), + .y = @intToFloat(f32, display_h) / @intToFloat(f32, h), + }; + if (g_WantUpdateMonitors) + UpdateMonitors(); + + // Setup time step + const current_time = c.glfwGetTime(); + io.*.DeltaTime = if (g_Time > 0.0) @floatCast(f32, current_time - g_Time) else 1.0 / 60.0; + g_Time = current_time; + + UpdateMousePosAndButtons(); + UpdateMouseCursor(); + + UpdateGamepads(); +} + +fn UpdateMonitors() void { + // @TODO +} + +fn UpdateMousePosAndButtons() void { + // Update buttons + const io = c.igGetIO(); + for (io.*.MouseDown) |*isDown, i| { + // 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. + isDown.* = g_MouseJustPressed[i] or c.glfwGetMouseButton(g_Window, @intCast(c_int, i)) != 0; + g_MouseJustPressed[i] = false; + } + + // Update mouse position + const mouse_pos_backup = io.*.MousePos; + io.*.MousePos = c.ImVec2{ .x = math.f32_min, .y = math.f32_min }; + io.*.MouseHoveredViewport = 0; + const platform_io = c.igGetPlatformIO(); + var n : usize = 0; + while (n < @intCast(usize, platform_io.*.Viewports.Size)) : (n += 1) { + const viewport = platform_io.*.Viewports.Data[n]; + const window = @ptrCast(*c.GLFWwindow, viewport.*.PlatformHandle); + const focused = c.glfwGetWindowAttrib(window, c.GLFW_FOCUSED) != 0; + if (focused) { + if (io.*.WantSetMousePos) { + c.glfwSetCursorPos(window, mouse_pos_backup.x - viewport.*.Pos.x, mouse_pos_backup.y - viewport.*.Pos.y); + } else { + var mouse_x : f64 = undefined; + var mouse_y : f64 = undefined; + c.glfwGetCursorPos(window, &mouse_x, &mouse_y); + if (io.*.ConfigFlags & @enumToInt(c.ImGuiConfigFlags_ViewportsEnable) != 0) { + // Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor) + var window_x : c_int = undefined; + var window_y : c_int = undefined; + c.glfwGetWindowPos(window, &window_x, &window_y); + io.*.MousePos = c.ImVec2{ + .x = @floatCast(f32, mouse_x) + @intToFloat(f32, window_x), + .y = @floatCast(f32, mouse_y) + @intToFloat(f32, window_y), + }; + } else { + // Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window) + io.*.MousePos = c.ImVec2{ .x = @floatCast(f32, mouse_x), .y = @floatCast(f32, mouse_y) }; + } + } + + for (io.*.MouseDown) |*isDown, i| + isDown.* = isDown.* or c.glfwGetMouseButton(window, @intCast(c_int, i)) != 0; + } + } +} + +fn UpdateMouseCursor() void { + const io = c.igGetIO(); + if (io.*.ConfigFlags & @enumToInt(c.ImGuiConfigFlags_NoMouseCursorChange) != 0 + or c.glfwGetInputMode(g_Window, c.GLFW_CURSOR) == c.GLFW_CURSOR_DISABLED) + return; + + const imgui_cursor = c.igGetMouseCursor(); + const platform_io = c.igGetPlatformIO(); + var n : usize = 0; + while (n < @intCast(usize, platform_io.*.Viewports.Size)) : (n += 1) { + const window = @ptrCast(*c.GLFWwindow, platform_io.*.Viewports.Data[n].*.PlatformHandle); + if (imgui_cursor == @enumToInt(c.ImGuiMouseCursor_None) or io.*.MouseDrawCursor) { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + c.glfwSetInputMode(window, c.GLFW_CURSOR, c.GLFW_CURSOR_HIDDEN); + } else { + // Show OS mouse cursor + // FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here. + c.glfwSetCursor(window, + if (g_MouseCursors[@intCast(usize, imgui_cursor)]) |cursor| cursor + else g_MouseCursors[@enumToInt(c.ImGuiMouseCursor_Arrow)]); + c.glfwSetInputMode(window, c.GLFW_CURSOR, c.GLFW_CURSOR_NORMAL); + } + } +} + +fn UpdateGamepads() void { + // @TODO } // GLFW Callbacks extern fn Callback_MouseButton(window: ?*c.GLFWwindow, button: c_int, action: c_int, mods: c_int) void { - // @TODO: delegate up + if (g_PrevUserCallbackMousebutton) |prev| { + prev(window, button, action, mods); + } if (button < 0) return; @@ -136,7 +239,9 @@ extern fn Callback_MouseButton(window: ?*c.GLFWwindow, button: c_int, action: c_ } extern fn Callback_Scroll(window: ?*c.GLFWwindow, dx: f64, dy: f64) void { - // @TODO: delegate up + if (g_PrevUserCallbackScroll) |prev| { + prev(window, dx, dy); + } const io = c.igGetIO(); io.*.MouseWheelH += @floatCast(f32, dx); @@ -144,7 +249,9 @@ extern fn Callback_Scroll(window: ?*c.GLFWwindow, dx: f64, dy: f64) void { } extern fn Callback_Key(window: ?*c.GLFWwindow, key: c_int, scancode: c_int, action: c_int, modifiers: c_int) void { - // @TODO: delegate up + if (g_PrevUserCallbackKey) |prev| { + prev(window, key, scancode, action, modifiers); + } if (key < 0) unreachable; @@ -165,7 +272,9 @@ extern fn Callback_Key(window: ?*c.GLFWwindow, key: c_int, scancode: c_int, acti } extern fn Callback_Char(window: ?*c.GLFWwindow, char: c_uint) void { - // @TODO: delegate up + if (g_PrevUserCallbackChar) |prev| { + prev(window, char); + } const io = c.igGetIO(); c.ImGuiIO_AddInputCharacter(io, char); diff --git a/src/main.zig b/src/main.zig index 59b1804..882faf0 100644 --- a/src/main.zig +++ b/src/main.zig @@ -49,7 +49,7 @@ pub fn main() !void { const style = c.igGetStyle(); c.igStyleColorsDark(style); - if (io.*.ConfigFlags & @enumToInt(c.ImGuiConfigFlags_ViewportsEnable) != 0) { + if (false and io.*.ConfigFlags & @enumToInt(c.ImGuiConfigFlags_ViewportsEnable) != 0) { style.*.WindowRounding = 0.0; style.*.Colors[@enumToInt(c.ImGuiCol_WindowBg)].w = 1.0; } |
