summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2019-10-20 22:32:49 +0000
committers-ol <s-ol@users.noreply.github.com>2019-10-20 22:34:49 +0000
commit407a006acdabd11a1cfd7b370834d7036c99ac96 (patch)
tree1503fee58190fc3a6e3e8b85c6db20d06f4846e9 /src
parentadd openGL3 impl (still failing) (diff)
downloadzig-imgui-407a006acdabd11a1cfd7b370834d7036c99ac96.tar.gz
zig-imgui-407a006acdabd11a1cfd7b370834d7036c99ac96.zip
more glfw
Diffstat (limited to 'src')
-rw-r--r--src/glfw_impl.zig143
-rw-r--r--src/main.zig2
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;
}