summaryrefslogtreecommitdiffstats
path: root/src/glfw_impl.zig
blob: 7ef2f63e41ed05f7107d02e14dcfa037d49e5194 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
const c = @import("c.zig");
const builtin = @import("builtin");
pub const ClientApi = enum {
    Unknown,
    OpenGL,
    Vulkan,
};

// Data
var g_Window: ?*c.GLFWwindow = null;
var g_ClientApi: ClientApi = .Unknown;
var g_Time: f32 = 0.0;
var g_MouseJustPressed = [5]bool;
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;

pub fn Init(window: *c.GLFWwindow, install_callbacks: bool, client_api: ClientApi) void {
  g_Window = window;
  g_Time = 0.0;

  // Setup back-end capabilities flags
  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 (false and 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";

  // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Tab)] = c.GLFW_KEY_TAB;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_LeftArrow)] = c.GLFW_KEY_LEFT;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_RightArrow)] = c.GLFW_KEY_RIGHT;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_UpArrow)] = c.GLFW_KEY_UP;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_DownArrow)] = c.GLFW_KEY_DOWN;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_PageUp)] = c.GLFW_KEY_PAGE_UP;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_PageDown)] = c.GLFW_KEY_PAGE_DOWN;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Home)] = c.GLFW_KEY_HOME;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_End)] = c.GLFW_KEY_END;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Insert)] = c.GLFW_KEY_INSERT;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Delete)] = c.GLFW_KEY_DELETE;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Backspace)] = c.GLFW_KEY_BACKSPACE;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Space)] = c.GLFW_KEY_SPACE;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Enter)] = c.GLFW_KEY_ENTER;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Escape)] = c.GLFW_KEY_ESCAPE;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_KeyPadEnter)] = c.GLFW_KEY_KP_ENTER;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_A)] = c.GLFW_KEY_A;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_C)] = c.GLFW_KEY_C;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_V)] = c.GLFW_KEY_V;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_X)] = c.GLFW_KEY_X;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Y)] = c.GLFW_KEY_Y;
  io.*.KeyMap[@enumToInt(c.ImGuiKey_Z)] = c.GLFW_KEY_Z;

  // io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
  // io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
  // 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);
  g_MouseCursors[@enumToInt(c.ImGuiMouseCursor_ResizeAll)] = c.glfwCreateStandardCursor(c.GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
  g_MouseCursors[@enumToInt(c.ImGuiMouseCursor_ResizeNS)] = c.glfwCreateStandardCursor(c.GLFW_VRESIZE_CURSOR);
  g_MouseCursors[@enumToInt(c.ImGuiMouseCursor_ResizeEW)] = c.glfwCreateStandardCursor(c.GLFW_HRESIZE_CURSOR);
  g_MouseCursors[@enumToInt(c.ImGuiMouseCursor_ResizeNESW)] = c.glfwCreateStandardCursor(c.GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
  g_MouseCursors[@enumToInt(c.ImGuiMouseCursor_ResizeNWSE)] = c.glfwCreateStandardCursor(c.GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
  g_MouseCursors[@enumToInt(c.ImGuiMouseCursor_Hand)] = c.glfwCreateStandardCursor(c.GLFW_HAND_CURSOR);

  // Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
  g_PrevUserCallbackMousebutton = null;
  g_PrevUserCallbackScroll = null;
  g_PrevUserCallbackKey = null;
  g_PrevUserCallbackChar = null;
  if (install_callbacks and false) {
    // g_PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback);
    // g_PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback);
    // g_PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback);
    // g_PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback);
  }

  // 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) {
    main_viewport.*.PlatformHandleRaw = c.glfwGetWin32Window(g_Window);
  }

  // if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable != 0)
  //    ImGui_ImplGlfw_InitPlatformInterface();

  g_ClientApi = client_api;
}

pub fn Shutdown() void {
  // ImGui_ImplGlfw_ShutdownPlatformInterface();
  for (g_MouseCursors) |*cursor| {
    c.glfwDestroyCursor(cursor.*);
    cursor.* = null;
  }
  g_ClientApi = .Unknown;
}