2020-10-12 17:34:22 +02:00
// dear imgui: Platform Backend for GLFW
2021-01-28 12:11:26 +01:00
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
2018-06-08 19:37:33 +02:00
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
2019-01-02 16:04:13 +01:00
// (Requires: GLFW 3.1+)
2018-06-08 19:37:33 +02:00
// Implemented features:
2018-06-11 12:33:51 +02:00
// [X] Platform: Clipboard support.
2018-09-20 10:37:55 +02:00
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
2019-12-05 15:43:05 +01:00
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
2018-06-30 14:33:45 +02:00
// [X] Platform: Keyboard arrays indexed using GLFW_KEY_* codes, e.g. ImGui::IsKeyPressed(GLFW_KEY_SPACE).
2018-06-08 19:37:33 +02:00
2021-06-28 16:52:10 +02:00
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
2021-05-27 13:59:35 +02:00
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
2020-10-14 12:22:53 +02:00
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
2018-06-08 19:37:33 +02:00
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
2021-08-02 20:17:26 +02:00
// 2021-08-17: *BREAKING CHANGE*: Now using glfwSetWindowFocusCallback() to calling io.AddFocusEvent(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() and forward it to the backend via ImGui_ImplGlfw_WindowFocusCallback().
// 2021-07-29: *BREAKING CHANGE*: Now using glfwSetCursorEnterCallback(). MousePos is correctly reported when the host platform window is hovered but not focused. If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetWindowFocusCallback() callback and forward it to the backend via ImGui_ImplGlfw_CursorEnterCallback().
2021-06-28 16:52:10 +02:00
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
2020-01-17 11:36:56 +01:00
// 2020-01-17: Inputs: Disable error callback while assigning mouse cursors because some X11 setup don't have them and it generates errors.
2019-12-05 15:43:05 +01:00
// 2019-12-05: Inputs: Added support for new mouse cursors added in GLFW 3.4+ (resizing cursors, not allowed cursor).
2019-10-18 16:25:18 +02:00
// 2019-10-18: Misc: Previously installed user callbacks are now restored on shutdown.
2019-07-22 03:39:50 +02:00
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
2019-05-11 10:33:56 +02:00
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
2019-03-12 18:27:14 +01:00
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
2018-11-30 18:18:15 +01:00
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
2018-11-08 16:24:41 +01:00
// 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and chain call them.
2018-08-01 11:34:17 +02:00
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
2018-06-29 16:30:41 +02:00
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
2018-06-08 19:37:33 +02:00
// 2018-06-08: Misc: Extracted imgui_impl_glfw.cpp/.h away from the old combined GLFW+OpenGL/Vulkan examples.
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value, passed to glfwSetCursor()).
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
// 2018-01-25: Inputs: Added gamepad support if ImGuiConfigFlags_NavEnableGamepad is set.
// 2018-01-25: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert.
// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1).
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
# include "imgui.h"
# include "imgui_impl_glfw.h"
// GLFW
# include <GLFW/glfw3.h>
# ifdef _WIN32
# undef APIENTRY
# define GLFW_EXPOSE_NATIVE_WIN32
# include <GLFW/glfw3native.h> // for glfwGetWin32Window
# endif
2019-06-06 16:13:30 +02:00
# define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ GLFW_FLOATING
# define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_HOVERED
# define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity
# define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorContentScale
# define GLFW_HAS_VULKAN (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwCreateWindowSurface
2021-08-02 15:48:20 +02:00
# ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
2019-12-05 15:43:05 +01:00
# define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
2019-12-06 15:08:04 +01:00
# else
# define GLFW_HAS_NEW_CURSORS (0)
# endif
2018-06-08 19:37:33 +02:00
2021-06-28 16:52:10 +02:00
// GLFW data
2018-06-08 19:37:33 +02:00
enum GlfwClientApi
{
GlfwClientApi_Unknown ,
GlfwClientApi_OpenGL ,
2021-02-10 17:27:33 +01:00
GlfwClientApi_Vulkan
2018-06-08 19:37:33 +02:00
} ;
2021-06-28 16:52:10 +02:00
struct ImGui_ImplGlfw_Data
{
GLFWwindow * Window ;
GlfwClientApi ClientApi ;
double Time ;
2021-07-29 18:59:45 +02:00
GLFWwindow * MouseWindow ;
2021-06-28 16:52:10 +02:00
bool MouseJustPressed [ ImGuiMouseButton_COUNT ] ;
GLFWcursor * MouseCursors [ ImGuiMouseCursor_COUNT ] ;
bool InstalledCallbacks ;
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
2021-08-02 20:17:26 +02:00
GLFWwindowfocusfun PrevUserCallbackWindowFocus ;
2021-07-29 18:59:45 +02:00
GLFWcursorenterfun PrevUserCallbackCursorEnter ;
2021-06-28 16:52:10 +02:00
GLFWmousebuttonfun PrevUserCallbackMousebutton ;
GLFWscrollfun PrevUserCallbackScroll ;
GLFWkeyfun PrevUserCallbackKey ;
GLFWcharfun PrevUserCallbackChar ;
2021-07-07 14:12:48 +02:00
GLFWmonitorfun PrevUserCallbackMonitor ;
2021-06-28 16:52:10 +02:00
ImGui_ImplGlfw_Data ( ) { memset ( this , 0 , sizeof ( * this ) ) ; }
} ;
2021-06-29 16:42:13 +02:00
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
2021-07-07 14:12:48 +02:00
// - Because glfwPollEvents() process all windows and some events may be called outside of it, you will need to register your own callbacks
// (passing install_callbacks=false in ImGui_ImplGlfw_InitXXX functions), set the current dear imgui context and then call our callbacks.
// - Otherwise we may need to store a GLFWWindow* -> ImGuiContext* map and handle this in the backend, adding a little bit of extra complexity to it.
2021-06-29 16:42:13 +02:00
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
2021-06-30 15:22:15 +02:00
static ImGui_ImplGlfw_Data * ImGui_ImplGlfw_GetBackendData ( )
{
return ImGui : : GetCurrentContext ( ) ? ( ImGui_ImplGlfw_Data * ) ImGui : : GetIO ( ) . BackendPlatformUserData : NULL ;
}
2021-06-28 16:52:10 +02:00
// Functions
2018-06-08 19:37:33 +02:00
static const char * ImGui_ImplGlfw_GetClipboardText ( void * user_data )
{
return glfwGetClipboardString ( ( GLFWwindow * ) user_data ) ;
}
static void ImGui_ImplGlfw_SetClipboardText ( void * user_data , const char * text )
{
glfwSetClipboardString ( ( GLFWwindow * ) user_data , text ) ;
}
2018-11-08 16:24:41 +01:00
void ImGui_ImplGlfw_MouseButtonCallback ( GLFWwindow * window , int button , int action , int mods )
2018-06-08 19:37:33 +02:00
{
2021-06-28 16:52:10 +02:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2021-08-02 15:48:20 +02:00
if ( bd - > PrevUserCallbackMousebutton ! = NULL & & window = = bd - > Window )
2021-06-28 16:52:10 +02:00
bd - > PrevUserCallbackMousebutton ( window , button , action , mods ) ;
2018-11-08 16:24:41 +01:00
2021-06-28 16:52:10 +02:00
if ( action = = GLFW_PRESS & & button > = 0 & & button < IM_ARRAYSIZE ( bd - > MouseJustPressed ) )
bd - > MouseJustPressed [ button ] = true ;
2018-06-08 19:37:33 +02:00
}
2018-11-08 16:24:41 +01:00
void ImGui_ImplGlfw_ScrollCallback ( GLFWwindow * window , double xoffset , double yoffset )
2018-06-08 19:37:33 +02:00
{
2021-06-28 16:52:10 +02:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2021-08-02 15:48:20 +02:00
if ( bd - > PrevUserCallbackScroll ! = NULL & & window = = bd - > Window )
2021-06-28 16:52:10 +02:00
bd - > PrevUserCallbackScroll ( window , xoffset , yoffset ) ;
2018-11-08 16:24:41 +01:00
2018-06-08 19:37:33 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
io . MouseWheelH + = ( float ) xoffset ;
io . MouseWheel + = ( float ) yoffset ;
}
2018-11-08 16:24:41 +01:00
void ImGui_ImplGlfw_KeyCallback ( GLFWwindow * window , int key , int scancode , int action , int mods )
2018-06-08 19:37:33 +02:00
{
2021-06-28 16:52:10 +02:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2021-08-02 15:48:20 +02:00
if ( bd - > PrevUserCallbackKey ! = NULL & & window = = bd - > Window )
2021-06-28 16:52:10 +02:00
bd - > PrevUserCallbackKey ( window , key , scancode , action , mods ) ;
2018-11-08 16:24:41 +01:00
2018-06-08 19:37:33 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-05-19 19:03:15 +02:00
if ( key > = 0 & & key < IM_ARRAYSIZE ( io . KeysDown ) )
{
if ( action = = GLFW_PRESS )
io . KeysDown [ key ] = true ;
if ( action = = GLFW_RELEASE )
io . KeysDown [ key ] = false ;
}
2018-06-08 19:37:33 +02:00
2018-11-08 16:24:41 +01:00
// Modifiers are not reliable across systems
2018-06-08 19:37:33 +02:00
io . KeyCtrl = io . KeysDown [ GLFW_KEY_LEFT_CONTROL ] | | io . KeysDown [ GLFW_KEY_RIGHT_CONTROL ] ;
io . KeyShift = io . KeysDown [ GLFW_KEY_LEFT_SHIFT ] | | io . KeysDown [ GLFW_KEY_RIGHT_SHIFT ] ;
io . KeyAlt = io . KeysDown [ GLFW_KEY_LEFT_ALT ] | | io . KeysDown [ GLFW_KEY_RIGHT_ALT ] ;
2020-01-17 15:18:33 +01:00
# ifdef _WIN32
io . KeySuper = false ;
# else
2018-06-08 19:37:33 +02:00
io . KeySuper = io . KeysDown [ GLFW_KEY_LEFT_SUPER ] | | io . KeysDown [ GLFW_KEY_RIGHT_SUPER ] ;
2020-01-17 15:18:33 +01:00
# endif
2018-06-08 19:37:33 +02:00
}
2021-08-02 20:17:26 +02:00
void ImGui_ImplGlfw_WindowFocusCallback ( GLFWwindow * window , int focused )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
if ( bd - > PrevUserCallbackWindowFocus ! = NULL & & window = = bd - > Window )
bd - > PrevUserCallbackWindowFocus ( window , focused ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
io . AddFocusEvent ( focused ! = 0 ) ;
}
2021-07-29 18:59:45 +02:00
void ImGui_ImplGlfw_CursorEnterCallback ( GLFWwindow * window , int entered )
{
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2021-08-02 20:17:26 +02:00
if ( bd - > PrevUserCallbackCursorEnter ! = NULL & & window = = bd - > Window )
2021-07-29 18:59:45 +02:00
bd - > PrevUserCallbackCursorEnter ( window , entered ) ;
2021-08-02 20:17:26 +02:00
2021-07-29 18:59:45 +02:00
if ( entered )
bd - > MouseWindow = window ;
if ( ! entered & & bd - > MouseWindow = = window )
bd - > MouseWindow = NULL ;
}
2018-11-08 16:24:41 +01:00
void ImGui_ImplGlfw_CharCallback ( GLFWwindow * window , unsigned int c )
2018-06-08 19:37:33 +02:00
{
2021-06-28 16:52:10 +02:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2021-08-02 15:48:20 +02:00
if ( bd - > PrevUserCallbackChar ! = NULL & & window = = bd - > Window )
2021-06-28 16:52:10 +02:00
bd - > PrevUserCallbackChar ( window , c ) ;
2018-11-08 16:24:41 +01:00
2018-06-08 19:37:33 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2019-05-11 10:33:56 +02:00
io . AddInputCharacter ( c ) ;
2018-06-08 19:37:33 +02:00
}
2021-07-07 14:12:48 +02:00
void ImGui_ImplGlfw_MonitorCallback ( GLFWmonitor * , int )
{
// Unused in 'master' branch but 'docking' branch will use this, so we declare it ahead of it so if you have to install callbacks you can install this one too.
}
2018-06-08 19:37:33 +02:00
static bool ImGui_ImplGlfw_Init ( GLFWwindow * window , bool install_callbacks , GlfwClientApi client_api )
{
2021-06-28 16:52:10 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
IM_ASSERT ( io . BackendPlatformUserData = = NULL & & " Already initialized a platform backend! " ) ;
2020-10-12 17:34:22 +02:00
// Setup backend capabilities flags
2021-06-30 15:22:15 +02:00
ImGui_ImplGlfw_Data * bd = IM_NEW ( ImGui_ImplGlfw_Data ) ( ) ;
2021-06-28 16:52:10 +02:00
io . BackendPlatformUserData = ( void * ) bd ;
io . BackendPlatformName = " imgui_impl_glfw " ;
2018-06-08 19:37:33 +02:00
io . BackendFlags | = ImGuiBackendFlags_HasMouseCursors ; // We can honor GetMouseCursor() values (optional)
io . BackendFlags | = ImGuiBackendFlags_HasSetMousePos ; // We can honor io.WantSetMousePos requests (optional, rarely used)
2021-06-30 15:22:15 +02:00
bd - > Window = window ;
bd - > Time = 0.0 ;
2021-03-04 11:03:40 +01:00
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array.
2018-06-08 19:37:33 +02:00
io . KeyMap [ ImGuiKey_Tab ] = GLFW_KEY_TAB ;
io . KeyMap [ ImGuiKey_LeftArrow ] = GLFW_KEY_LEFT ;
io . KeyMap [ ImGuiKey_RightArrow ] = GLFW_KEY_RIGHT ;
io . KeyMap [ ImGuiKey_UpArrow ] = GLFW_KEY_UP ;
io . KeyMap [ ImGuiKey_DownArrow ] = GLFW_KEY_DOWN ;
io . KeyMap [ ImGuiKey_PageUp ] = GLFW_KEY_PAGE_UP ;
io . KeyMap [ ImGuiKey_PageDown ] = GLFW_KEY_PAGE_DOWN ;
io . KeyMap [ ImGuiKey_Home ] = GLFW_KEY_HOME ;
io . KeyMap [ ImGuiKey_End ] = GLFW_KEY_END ;
io . KeyMap [ ImGuiKey_Insert ] = GLFW_KEY_INSERT ;
io . KeyMap [ ImGuiKey_Delete ] = GLFW_KEY_DELETE ;
io . KeyMap [ ImGuiKey_Backspace ] = GLFW_KEY_BACKSPACE ;
io . KeyMap [ ImGuiKey_Space ] = GLFW_KEY_SPACE ;
io . KeyMap [ ImGuiKey_Enter ] = GLFW_KEY_ENTER ;
io . KeyMap [ ImGuiKey_Escape ] = GLFW_KEY_ESCAPE ;
2019-07-22 03:39:50 +02:00
io . KeyMap [ ImGuiKey_KeyPadEnter ] = GLFW_KEY_KP_ENTER ;
2018-06-08 19:37:33 +02:00
io . KeyMap [ ImGuiKey_A ] = GLFW_KEY_A ;
io . KeyMap [ ImGuiKey_C ] = GLFW_KEY_C ;
io . KeyMap [ ImGuiKey_V ] = GLFW_KEY_V ;
io . KeyMap [ ImGuiKey_X ] = GLFW_KEY_X ;
io . KeyMap [ ImGuiKey_Y ] = GLFW_KEY_Y ;
io . KeyMap [ ImGuiKey_Z ] = GLFW_KEY_Z ;
io . SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText ;
io . GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText ;
2021-06-28 16:52:10 +02:00
io . ClipboardUserData = bd - > Window ;
2018-06-08 19:37:33 +02:00
# if defined(_WIN32)
2021-06-28 16:52:10 +02:00
io . ImeWindowHandle = ( void * ) glfwGetWin32Window ( bd - > Window ) ;
2018-06-08 19:37:33 +02:00
# endif
2020-01-17 11:36:56 +01:00
// Create mouse cursors
// (By design, on X11 cursors are user configurable and some cursors may be missing. When a cursor doesn't exist,
// GLFW will emit an error which will often be printed by the app, so we temporarily disable error reporting.
// Missing cursors will return NULL and our _UpdateMouseCursor() function will use the Arrow cursor instead.)
GLFWerrorfun prev_error_callback = glfwSetErrorCallback ( NULL ) ;
2021-06-28 16:52:10 +02:00
bd - > MouseCursors [ ImGuiMouseCursor_Arrow ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_TextInput ] = glfwCreateStandardCursor ( GLFW_IBEAM_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNS ] = glfwCreateStandardCursor ( GLFW_VRESIZE_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeEW ] = glfwCreateStandardCursor ( GLFW_HRESIZE_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_Hand ] = glfwCreateStandardCursor ( GLFW_HAND_CURSOR ) ;
2019-12-02 09:36:59 +01:00
# if GLFW_HAS_NEW_CURSORS
2021-06-28 16:52:10 +02:00
bd - > MouseCursors [ ImGuiMouseCursor_ResizeAll ] = glfwCreateStandardCursor ( GLFW_RESIZE_ALL_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNESW ] = glfwCreateStandardCursor ( GLFW_RESIZE_NESW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNWSE ] = glfwCreateStandardCursor ( GLFW_RESIZE_NWSE_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_NotAllowed ] = glfwCreateStandardCursor ( GLFW_NOT_ALLOWED_CURSOR ) ;
2019-12-02 09:36:59 +01:00
# else
2021-06-28 16:52:10 +02:00
bd - > MouseCursors [ ImGuiMouseCursor_ResizeAll ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNESW ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_ResizeNWSE ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
bd - > MouseCursors [ ImGuiMouseCursor_NotAllowed ] = glfwCreateStandardCursor ( GLFW_ARROW_CURSOR ) ;
2019-12-02 09:36:59 +01:00
# endif
2020-01-17 11:36:56 +01:00
glfwSetErrorCallback ( prev_error_callback ) ;
2019-01-20 17:56:17 +01:00
2018-11-08 16:24:41 +01:00
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
2021-08-02 20:17:26 +02:00
bd - > PrevUserCallbackWindowFocus = NULL ;
2021-06-28 16:52:10 +02:00
bd - > PrevUserCallbackMousebutton = NULL ;
bd - > PrevUserCallbackScroll = NULL ;
bd - > PrevUserCallbackKey = NULL ;
bd - > PrevUserCallbackChar = NULL ;
2021-07-07 14:12:48 +02:00
bd - > PrevUserCallbackMonitor = NULL ;
2018-06-08 19:37:33 +02:00
if ( install_callbacks )
2018-11-08 16:06:22 +01:00
{
2021-06-28 16:52:10 +02:00
bd - > InstalledCallbacks = true ;
2021-08-02 20:17:26 +02:00
bd - > PrevUserCallbackWindowFocus = glfwSetWindowFocusCallback ( window , ImGui_ImplGlfw_WindowFocusCallback ) ;
2021-07-29 18:59:45 +02:00
bd - > PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback ( window , ImGui_ImplGlfw_CursorEnterCallback ) ;
2021-06-28 16:52:10 +02:00
bd - > PrevUserCallbackMousebutton = glfwSetMouseButtonCallback ( window , ImGui_ImplGlfw_MouseButtonCallback ) ;
bd - > PrevUserCallbackScroll = glfwSetScrollCallback ( window , ImGui_ImplGlfw_ScrollCallback ) ;
bd - > PrevUserCallbackKey = glfwSetKeyCallback ( window , ImGui_ImplGlfw_KeyCallback ) ;
bd - > PrevUserCallbackChar = glfwSetCharCallback ( window , ImGui_ImplGlfw_CharCallback ) ;
2021-07-07 14:12:48 +02:00
bd - > PrevUserCallbackMonitor = glfwSetMonitorCallback ( ImGui_ImplGlfw_MonitorCallback ) ;
2018-11-08 16:06:22 +01:00
}
2018-06-08 19:37:33 +02:00
2021-06-28 16:52:10 +02:00
bd - > ClientApi = client_api ;
2018-06-08 19:37:33 +02:00
return true ;
}
bool ImGui_ImplGlfw_InitForOpenGL ( GLFWwindow * window , bool install_callbacks )
{
return ImGui_ImplGlfw_Init ( window , install_callbacks , GlfwClientApi_OpenGL ) ;
}
bool ImGui_ImplGlfw_InitForVulkan ( GLFWwindow * window , bool install_callbacks )
{
return ImGui_ImplGlfw_Init ( window , install_callbacks , GlfwClientApi_Vulkan ) ;
}
2021-02-10 17:27:33 +01:00
bool ImGui_ImplGlfw_InitForOther ( GLFWwindow * window , bool install_callbacks )
2021-01-28 12:11:26 +01:00
{
2021-02-10 17:27:33 +01:00
return ImGui_ImplGlfw_Init ( window , install_callbacks , GlfwClientApi_Unknown ) ;
2021-01-28 12:11:26 +01:00
}
2018-06-08 19:37:33 +02:00
void ImGui_ImplGlfw_Shutdown ( )
{
2021-06-28 16:52:10 +02:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2021-09-20 18:43:05 +02:00
IM_ASSERT ( bd ! = NULL & & " No platform backend to shutdown, or already shutdown? " ) ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-06-28 16:52:10 +02:00
if ( bd - > InstalledCallbacks )
2019-10-18 16:25:18 +02:00
{
2021-08-02 20:17:26 +02:00
glfwSetWindowFocusCallback ( bd - > Window , bd - > PrevUserCallbackWindowFocus ) ;
2021-08-02 15:48:20 +02:00
glfwSetCursorEnterCallback ( bd - > Window , bd - > PrevUserCallbackCursorEnter ) ;
2021-06-28 16:52:10 +02:00
glfwSetMouseButtonCallback ( bd - > Window , bd - > PrevUserCallbackMousebutton ) ;
glfwSetScrollCallback ( bd - > Window , bd - > PrevUserCallbackScroll ) ;
glfwSetKeyCallback ( bd - > Window , bd - > PrevUserCallbackKey ) ;
glfwSetCharCallback ( bd - > Window , bd - > PrevUserCallbackChar ) ;
2021-07-07 14:12:48 +02:00
glfwSetMonitorCallback ( bd - > PrevUserCallbackMonitor ) ;
2019-10-18 16:25:18 +02:00
}
2018-06-20 11:06:29 +02:00
for ( ImGuiMouseCursor cursor_n = 0 ; cursor_n < ImGuiMouseCursor_COUNT ; cursor_n + + )
2021-06-28 16:52:10 +02:00
glfwDestroyCursor ( bd - > MouseCursors [ cursor_n ] ) ;
io . BackendPlatformName = NULL ;
io . BackendPlatformUserData = NULL ;
2021-06-30 15:22:15 +02:00
IM_DELETE ( bd ) ;
2018-06-08 19:37:33 +02:00
}
static void ImGui_ImplGlfw_UpdateMousePosAndButtons ( )
{
2021-06-28 16:52:10 +02:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2018-06-08 19:37:33 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-08-02 15:48:20 +02:00
const ImVec2 mouse_pos_prev = io . MousePos ;
io . MousePos = ImVec2 ( - FLT_MAX , - FLT_MAX ) ;
// Update mouse buttons
// (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)
2018-06-08 19:37:33 +02:00
for ( int i = 0 ; i < IM_ARRAYSIZE ( io . MouseDown ) ; i + + )
{
2021-06-28 16:52:10 +02:00
io . MouseDown [ i ] = bd - > MouseJustPressed [ i ] | | glfwGetMouseButton ( bd - > Window , i ) ! = 0 ;
bd - > MouseJustPressed [ i ] = false ;
2018-06-08 19:37:33 +02:00
}
2018-08-01 11:34:17 +02:00
# ifdef __EMSCRIPTEN__
2021-08-02 15:48:20 +02:00
const bool focused = true ;
2018-08-01 11:34:17 +02:00
# else
2021-06-28 16:52:10 +02:00
const bool focused = glfwGetWindowAttrib ( bd - > Window , GLFW_FOCUSED ) ! = 0 ;
2018-08-01 11:34:17 +02:00
# endif
2021-07-29 18:59:45 +02:00
GLFWwindow * mouse_window = ( bd - > MouseWindow = = bd - > Window | | focused ) ? bd - > Window : NULL ;
2021-08-02 15:48:20 +02:00
// Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
if ( io . WantSetMousePos & & focused )
glfwSetCursorPos ( bd - > Window , ( double ) mouse_pos_prev . x , ( double ) mouse_pos_prev . y ) ;
// Set Dear ImGui mouse position from OS position
if ( mouse_window ! = NULL )
2021-07-29 18:59:45 +02:00
{
double mouse_x , mouse_y ;
glfwGetCursorPos ( mouse_window , & mouse_x , & mouse_y ) ;
io . MousePos = ImVec2 ( ( float ) mouse_x , ( float ) mouse_y ) ;
2018-06-08 19:37:33 +02:00
}
}
static void ImGui_ImplGlfw_UpdateMouseCursor ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-06-28 16:52:10 +02:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
if ( ( io . ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange ) | | glfwGetInputMode ( bd - > Window , GLFW_CURSOR ) = = GLFW_CURSOR_DISABLED )
2018-06-08 19:37:33 +02:00
return ;
ImGuiMouseCursor imgui_cursor = ImGui : : GetMouseCursor ( ) ;
if ( imgui_cursor = = ImGuiMouseCursor_None | | io . MouseDrawCursor )
{
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
2021-06-28 16:52:10 +02:00
glfwSetInputMode ( bd - > Window , GLFW_CURSOR , GLFW_CURSOR_HIDDEN ) ;
2018-06-08 19:37:33 +02:00
}
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.
2021-06-28 16:52:10 +02:00
glfwSetCursor ( bd - > Window , bd - > MouseCursors [ imgui_cursor ] ? bd - > MouseCursors [ imgui_cursor ] : bd - > MouseCursors [ ImGuiMouseCursor_Arrow ] ) ;
glfwSetInputMode ( bd - > Window , GLFW_CURSOR , GLFW_CURSOR_NORMAL ) ;
2018-06-08 19:37:33 +02:00
}
}
2019-02-14 18:55:08 +01:00
static void ImGui_ImplGlfw_UpdateGamepads ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
memset ( io . NavInputs , 0 , sizeof ( io . NavInputs ) ) ;
if ( ( io . ConfigFlags & ImGuiConfigFlags_NavEnableGamepad ) = = 0 )
return ;
// Update gamepad inputs
# define MAP_BUTTON(NAV_NO, BUTTON_NO) { if (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS) io.NavInputs[NAV_NO] = 1.0f; }
# define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float v = (axes_count > AXIS_NO) ? axes[AXIS_NO] : V0; v = (v - V0) / (V1 - V0); if (v > 1.0f) v = 1.0f; if (io.NavInputs[NAV_NO] < v) io.NavInputs[NAV_NO] = v; }
int axes_count = 0 , buttons_count = 0 ;
const float * axes = glfwGetJoystickAxes ( GLFW_JOYSTICK_1 , & axes_count ) ;
const unsigned char * buttons = glfwGetJoystickButtons ( GLFW_JOYSTICK_1 , & buttons_count ) ;
MAP_BUTTON ( ImGuiNavInput_Activate , 0 ) ; // Cross / A
MAP_BUTTON ( ImGuiNavInput_Cancel , 1 ) ; // Circle / B
MAP_BUTTON ( ImGuiNavInput_Menu , 2 ) ; // Square / X
MAP_BUTTON ( ImGuiNavInput_Input , 3 ) ; // Triangle / Y
MAP_BUTTON ( ImGuiNavInput_DpadLeft , 13 ) ; // D-Pad Left
MAP_BUTTON ( ImGuiNavInput_DpadRight , 11 ) ; // D-Pad Right
MAP_BUTTON ( ImGuiNavInput_DpadUp , 10 ) ; // D-Pad Up
MAP_BUTTON ( ImGuiNavInput_DpadDown , 12 ) ; // D-Pad Down
MAP_BUTTON ( ImGuiNavInput_FocusPrev , 4 ) ; // L1 / LB
MAP_BUTTON ( ImGuiNavInput_FocusNext , 5 ) ; // R1 / RB
MAP_BUTTON ( ImGuiNavInput_TweakSlow , 4 ) ; // L1 / LB
MAP_BUTTON ( ImGuiNavInput_TweakFast , 5 ) ; // R1 / RB
MAP_ANALOG ( ImGuiNavInput_LStickLeft , 0 , - 0.3f , - 0.9f ) ;
MAP_ANALOG ( ImGuiNavInput_LStickRight , 0 , + 0.3f , + 0.9f ) ;
MAP_ANALOG ( ImGuiNavInput_LStickUp , 1 , + 0.3f , + 0.9f ) ;
MAP_ANALOG ( ImGuiNavInput_LStickDown , 1 , - 0.3f , - 0.9f ) ;
# undef MAP_BUTTON
# undef MAP_ANALOG
if ( axes_count > 0 & & buttons_count > 0 )
io . BackendFlags | = ImGuiBackendFlags_HasGamepad ;
else
io . BackendFlags & = ~ ImGuiBackendFlags_HasGamepad ;
}
2018-06-08 19:37:33 +02:00
void ImGui_ImplGlfw_NewFrame ( )
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-06-28 16:52:10 +02:00
ImGui_ImplGlfw_Data * bd = ImGui_ImplGlfw_GetBackendData ( ) ;
2021-06-29 17:53:41 +02:00
IM_ASSERT ( bd ! = NULL & & " Did you call ImGui_ImplGlfw_InitForXXX()? " ) ;
2018-06-08 19:37:33 +02:00
2018-12-23 17:39:04 +01:00
// Setup display size (every frame to accommodate for window resizing)
2018-06-08 19:37:33 +02:00
int w , h ;
int display_w , display_h ;
2021-06-28 16:52:10 +02:00
glfwGetWindowSize ( bd - > Window , & w , & h ) ;
glfwGetFramebufferSize ( bd - > Window , & display_w , & display_h ) ;
2018-06-08 19:37:33 +02:00
io . DisplaySize = ImVec2 ( ( float ) w , ( float ) h ) ;
2019-03-12 18:27:14 +01:00
if ( w > 0 & & h > 0 )
io . DisplayFramebufferScale = ImVec2 ( ( float ) display_w / w , ( float ) display_h / h ) ;
2018-06-08 19:37:33 +02:00
// Setup time step
double current_time = glfwGetTime ( ) ;
2021-06-28 16:52:10 +02:00
io . DeltaTime = bd - > Time > 0.0 ? ( float ) ( current_time - bd - > Time ) : ( float ) ( 1.0f / 60.0f ) ;
bd - > Time = current_time ;
2018-06-08 19:37:33 +02:00
ImGui_ImplGlfw_UpdateMousePosAndButtons ( ) ;
ImGui_ImplGlfw_UpdateMouseCursor ( ) ;
2019-04-23 12:26:14 +02:00
// Update game controllers (if enabled and available)
2019-02-14 18:55:08 +01:00
ImGui_ImplGlfw_UpdateGamepads ( ) ;
2018-06-08 19:37:33 +02:00
}