From 131bf5ee4aa36298e30d5cd96c82af6a28411e95 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 6 Nov 2018 09:46:43 +0100 Subject: [PATCH 01/11] Examples: SDL: Tweaked Windows instructions and batch files. (#2175) --- examples/example_sdl_opengl2/README.md | 7 +++++-- examples/example_sdl_opengl2/build_win32.bat | 9 +++++++-- examples/example_sdl_opengl3/README.md | 7 +++++-- examples/example_sdl_opengl3/build_win32.bat | 9 +++++++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/examples/example_sdl_opengl2/README.md b/examples/example_sdl_opengl2/README.md index dfbfa7b6..60a5e377 100644 --- a/examples/example_sdl_opengl2/README.md +++ b/examples/example_sdl_opengl2/README.md @@ -4,8 +4,11 @@ - On Windows with Visual Studio's CLI ``` -set SDL2DIR=path_to_your_sdl2_folder -cl /Zi /MD /I %SDL2DIR%\include /I .. /I ..\.. main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl2.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +set SDL2_DIR=path_to_your_sdl2_folder +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl2.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_opengl2.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +# ^^ include paths ^^ source files ^^ output exe ^^ output dir ^^ libraries +# or for 64-bit: +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl2.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_opengl2.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x64 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console ``` - On Linux and similar Unixes diff --git a/examples/example_sdl_opengl2/build_win32.bat b/examples/example_sdl_opengl2/build_win32.bat index bc2eb3b2..97692d9e 100644 --- a/examples/example_sdl_opengl2/build_win32.bat +++ b/examples/example_sdl_opengl2/build_win32.bat @@ -1,3 +1,8 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I .. /I ..\.. /I ..\libs\gl3w /I %SDL2_DIR%\include *.cpp ..\imgui_impl_opengl2.cpp ..\imgui_impl_sdl.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/example_sdl_opengl2.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +set OUT_DIR=Debug +set OUT_EXE=example_sdl_opengl2.exe +set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include +set SOURCES=main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl2.cpp ..\..\imgui*.cpp +set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_DIR%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console diff --git a/examples/example_sdl_opengl3/README.md b/examples/example_sdl_opengl3/README.md index f029ce71..ec21fb78 100644 --- a/examples/example_sdl_opengl3/README.md +++ b/examples/example_sdl_opengl3/README.md @@ -4,8 +4,11 @@ - On Windows with Visual Studio's CLI ``` -set SDL2DIR=path_to_your_sdl2_folder -cl /Zi /MD /I .. /I ..\.. /I ..\libs\gl3w /I %SDL2DIR%\include main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /link /libpath:%SDL2DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +set SDL2_DIR=path_to_your_sdl2_folder +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include /I..\libs\gl3w main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/example_sdl_opengl3.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +# ^^ include paths ^^ source files ^^ output exe ^^ output dir ^^ libraries +# or for 64-bit: +cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include /I..\libs\gl3w main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/example_sdl_opengl3.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x64 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console ``` - On Linux and similar Unixes diff --git a/examples/example_sdl_opengl3/build_win32.bat b/examples/example_sdl_opengl3/build_win32.bat index d2cfa67f..f263c4b3 100644 --- a/examples/example_sdl_opengl3/build_win32.bat +++ b/examples/example_sdl_opengl3/build_win32.bat @@ -1,3 +1,8 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I .. /I ..\.. /I ..\libs\gl3w /I %SDL2_DIR%\include *.cpp ..\imgui_impl_opengl3.cpp ..\imgui_impl_sdl.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/example_sdl_opengl3.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +set OUT_DIR=Debug +set OUT_EXE=example_sdl_opengl3.exe +set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include /I..\libs\gl3w +set SOURCES=main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c +set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib +mkdir %OUT_DIR% +cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console From a419d462059d28579b5ec76325a1af48cab48d8c Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 8 Nov 2018 15:14:09 +0100 Subject: [PATCH 02/11] Examples: OpenGL3+GLFW/SDL: Made main.cpp compile with IMGUI_IMPL_OPENGL_LOADER_CUSTOM (may be missing init). (#2178) --- docs/CHANGELOG.txt | 1 + examples/example_glfw_opengl3/main.cpp | 2 ++ examples/example_sdl_opengl3/main.cpp | 2 ++ 3 files changed, 5 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a521d354..ef8d9645 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -79,6 +79,7 @@ Other Changes: - Examples: DirectX10, DirectX11: Removed seemingly unnecessary calls to invalidate and recreate device objects in the WM_SIZE handler. (#2088) [@ice1000] - Examples: OpenGL3+GLFW: Fixed error condition when using the GLAD loader. (#2157) [@blackball] +- Examples: OpenGL3+GLFW/SDL: Made main.cpp compile with IMGUI_IMPL_OPENGL_LOADER_CUSTOM (may be missing init). (#2178) [@doug-moen] ----------------------------------------------------------------------- diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp index 713accef..1a45405f 100644 --- a/examples/example_glfw_opengl3/main.cpp +++ b/examples/example_glfw_opengl3/main.cpp @@ -73,6 +73,8 @@ int main(int, char**) bool err = glewInit() != GLEW_OK; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) bool err = gladLoadGL() == 0; +#else + bool err = false; // If you use IMGUI_IMPL_OPENGL_LOADER_CUSTOM, your loader is likely to requires some form of initialization. #endif if (err) { diff --git a/examples/example_sdl_opengl3/main.cpp b/examples/example_sdl_opengl3/main.cpp index 577e84c4..69f06ef9 100644 --- a/examples/example_sdl_opengl3/main.cpp +++ b/examples/example_sdl_opengl3/main.cpp @@ -65,6 +65,8 @@ int main(int, char**) bool err = glewInit() != GLEW_OK; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) bool err = gladLoadGL() == 0; +#else + bool err = false; // If you use IMGUI_IMPL_OPENGL_LOADER_CUSTOM, your loader is likely to requires some form of initialization. #endif if (err) { From 9d155c73bcd4c99e0bd3e7c6c135e31c790d9759 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 8 Nov 2018 16:06:22 +0100 Subject: [PATCH 03/11] Examples: Misc comments mainly related to GLFW callbacks. (#1759) --- examples/example_allegro5/main.cpp | 6 ++++-- examples/example_apple_opengl2/main.mm | 5 +++-- examples/example_freeglut_opengl2/main.cpp | 5 +++-- examples/example_glfw_opengl2/main.cpp | 6 ++++-- examples/example_glfw_opengl3/main.cpp | 6 ++++-- examples/example_glfw_vulkan/main.cpp | 9 ++++----- examples/example_marmalade/main.cpp | 6 ++++-- examples/example_sdl_opengl2/main.cpp | 5 +++-- examples/example_sdl_opengl3/main.cpp | 5 +++-- examples/example_sdl_vulkan/main.cpp | 8 +++----- examples/example_win32_directx10/main.cpp | 5 +++-- examples/example_win32_directx11/main.cpp | 5 +++-- examples/example_win32_directx12/main.cpp | 5 +++-- examples/example_win32_directx9/main.cpp | 6 ++++-- examples/imgui_impl_glfw.cpp | 15 ++++++--------- examples/imgui_impl_glfw.h | 7 ++++--- 16 files changed, 58 insertions(+), 46 deletions(-) diff --git a/examples/example_allegro5/main.cpp b/examples/example_allegro5/main.cpp index a5998b64..a1fdd825 100644 --- a/examples/example_allegro5/main.cpp +++ b/examples/example_allegro5/main.cpp @@ -22,14 +22,16 @@ int main(int, char**) al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + + // Setup Platform/Renderer bindings ImGui_ImplAllegro5_Init(display); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index 5eb8b19b..1b79ca64 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -237,16 +237,17 @@ if ([view openGLContext] == nil) NSLog(@"No OpenGL Context!"); - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + // Setup Platform/Renderer bindings ImGui_ImplOSX_Init(); ImGui_ImplOpenGL2_Init(); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_freeglut_opengl2/main.cpp b/examples/example_freeglut_opengl2/main.cpp index d57ee07f..6ebf324d 100644 --- a/examples/example_freeglut_opengl2/main.cpp +++ b/examples/example_freeglut_opengl2/main.cpp @@ -95,16 +95,17 @@ int main(int argc, char** argv) // otherwise it is possible to install our own functions and call the imgui_impl_freeglut.h functions ourselves. glutDisplayFunc(glut_display_func); - // Setup Dear ImGui binding + // Setup Dear ImGui context ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + // Setup Platform/Renderer bindings ImGui_ImplFreeGLUT_Init(); ImGui_ImplFreeGLUT_InstallFuncs(); ImGui_ImplOpenGL2_Init(); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_glfw_opengl2/main.cpp b/examples/example_glfw_opengl2/main.cpp index fcfdabfc..6010b689 100644 --- a/examples/example_glfw_opengl2/main.cpp +++ b/examples/example_glfw_opengl2/main.cpp @@ -36,17 +36,19 @@ int main(int, char**) glfwMakeContextCurrent(window); glfwSwapInterval(1); // Enable vsync - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + // Setup Platform/Renderer bindings + // If you have already installed GLFW callbacks in your app, call ImGui_ImplGlfw_InitForOpenGL() with install_callbacks=false and call them yourself. ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL2_Init(); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp index 1a45405f..2e0ebbf9 100644 --- a/examples/example_glfw_opengl3/main.cpp +++ b/examples/example_glfw_opengl3/main.cpp @@ -82,17 +82,19 @@ int main(int, char**) return 1; } - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + // Setup Platform/Renderer bindings + // If you have already installed GLFW callbacks in your app, call ImGui_ImplGlfw_InitForOpenGL() with install_callbacks=false and call them yourself. ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init(glsl_version); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index ec89e67c..8eba5df1 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -350,17 +350,16 @@ int main(int, char**) ImGui_ImplVulkanH_WindowData* wd = &g_WindowData; SetupVulkanWindowData(wd, surface, w, h); - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls - // Setup GLFW binding + // Setup Platform/Renderer bindings + // If you have already installed GLFW callbacks in your app, call ImGui_ImplGlfw_InitForVulkan() with install_callbacks=false and call the functions yourself. ImGui_ImplGlfw_InitForVulkan(window, true); - - // Setup Vulkan binding ImGui_ImplVulkan_InitInfo init_info = {}; init_info.Instance = g_Instance; init_info.PhysicalDevice = g_PhysicalDevice; @@ -373,7 +372,7 @@ int main(int, char**) init_info.CheckVkResultFn = check_vk_result; ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_marmalade/main.cpp b/examples/example_marmalade/main.cpp index 92316a67..c29164cd 100644 --- a/examples/example_marmalade/main.cpp +++ b/examples/example_marmalade/main.cpp @@ -16,14 +16,16 @@ int main(int, char**) { IwGxInit(); - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + + // Setup Platform/Renderer bindings ImGui_Marmalade_Init(true); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_sdl_opengl2/main.cpp b/examples/example_sdl_opengl2/main.cpp index 7e92b853..54351f13 100644 --- a/examples/example_sdl_opengl2/main.cpp +++ b/examples/example_sdl_opengl2/main.cpp @@ -34,16 +34,17 @@ int main(int, char**) SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GL_SetSwapInterval(1); // Enable vsync - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + // Setup Platform/Renderer bindings ImGui_ImplSDL2_InitForOpenGL(window, gl_context); ImGui_ImplOpenGL2_Init(); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_sdl_opengl3/main.cpp b/examples/example_sdl_opengl3/main.cpp index 69f06ef9..dc31a6e3 100644 --- a/examples/example_sdl_opengl3/main.cpp +++ b/examples/example_sdl_opengl3/main.cpp @@ -74,16 +74,17 @@ int main(int, char**) return 1; } - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + // Setup Platform/Renderer bindings ImGui_ImplSDL2_InitForOpenGL(window, gl_context); ImGui_ImplOpenGL3_Init(glsl_version); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index dc7da3ea..c4e8abb5 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -333,15 +333,13 @@ int main(int, char**) ImGui_ImplVulkanH_WindowData* wd = &g_WindowData; SetupVulkanWindowData(wd, surface, w, h); - // Setup Dear ImGui binding + // Setup Dear ImGui context ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - // Setup SDL binding + // Setup Platform/Renderer bindings ImGui_ImplSDL2_InitForVulkan(window); - - // Setup Vulkan binding ImGui_ImplVulkan_InitInfo init_info = {}; init_info.Instance = g_Instance; init_info.PhysicalDevice = g_PhysicalDevice; @@ -354,7 +352,7 @@ int main(int, char**) init_info.CheckVkResultFn = check_vk_result; ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_win32_directx10/main.cpp b/examples/example_win32_directx10/main.cpp index c55ec5e2..4ea355b8 100644 --- a/examples/example_win32_directx10/main.cpp +++ b/examples/example_win32_directx10/main.cpp @@ -110,16 +110,17 @@ int main(int, char**) ShowWindow(hwnd, SW_SHOWDEFAULT); UpdateWindow(hwnd); - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + // Setup Platform/Renderer bindings ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX10_Init(g_pd3dDevice); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_win32_directx11/main.cpp b/examples/example_win32_directx11/main.cpp index c89b6192..e58a338c 100644 --- a/examples/example_win32_directx11/main.cpp +++ b/examples/example_win32_directx11/main.cpp @@ -113,16 +113,17 @@ int main(int, char**) ShowWindow(hwnd, SW_SHOWDEFAULT); UpdateWindow(hwnd); - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + // Setup Platform/Renderer bindings ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_win32_directx12/main.cpp b/examples/example_win32_directx12/main.cpp index 50cb3777..3379b2fe 100644 --- a/examples/example_win32_directx12/main.cpp +++ b/examples/example_win32_directx12/main.cpp @@ -286,19 +286,20 @@ int main(int, char**) ShowWindow(hwnd, SW_SHOWDEFAULT); UpdateWindow(hwnd); - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + // Setup Platform/Renderer bindings ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT, DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart()); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/example_win32_directx9/main.cpp b/examples/example_win32_directx9/main.cpp index 7e5b957a..27944e00 100644 --- a/examples/example_win32_directx9/main.cpp +++ b/examples/example_win32_directx9/main.cpp @@ -75,15 +75,17 @@ int main(int, char**) return 0; } - // Setup Dear ImGui binding + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + + // Setup Platform/Renderer bindings ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX9_Init(g_pd3dDevice); - // Setup style + // Setup Style ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index 753909ed..32baea7f 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -102,14 +102,6 @@ void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) io.AddInputCharacter((unsigned short)c); } -void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) -{ - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); -} - static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api) { g_Window = window; @@ -160,7 +152,12 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw g_MouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR); if (install_callbacks) - ImGui_ImplGlfw_InstallCallbacks(window); + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } g_ClientApi = client_api; return true; diff --git a/examples/imgui_impl_glfw.h b/examples/imgui_impl_glfw.h index 938fe784..4bacd77b 100644 --- a/examples/imgui_impl_glfw.h +++ b/examples/imgui_impl_glfw.h @@ -25,9 +25,10 @@ IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool in IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown(); IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame(); -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. +// GLFW callbacks are installed by default if you call the InitXXX function with 'install_callbacks=true'. +// If you already have GLFW callbacks installed by your application, call the InitXXX function with install_callbacks=false, +// then call the functions yourselves from your own GLFW callbacks. +// You may also handle inputs yourself and use those as a reference. IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); From 772354377bc1dffd0e161279efbf48a9a2f1548e Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 8 Nov 2018 16:24:41 +0100 Subject: [PATCH 04/11] Examples: GLFW: User previously installed GLFW callbacks are now saved and chain-called by the default callbacks. (#1759) --- docs/CHANGELOG.txt | 1 + examples/example_glfw_opengl2/main.cpp | 1 - examples/example_glfw_opengl3/main.cpp | 1 - examples/example_glfw_vulkan/main.cpp | 1 - examples/imgui_impl_glfw.cpp | 52 +++++++++++++++++++------- examples/imgui_impl_glfw.h | 6 +-- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ef8d9645..b0409bf9 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -78,6 +78,7 @@ Other Changes: in particular, points_count==0 could lead to a memory stomp if the draw list was previously empty. - Examples: DirectX10, DirectX11: Removed seemingly unnecessary calls to invalidate and recreate device objects in the WM_SIZE handler. (#2088) [@ice1000] +- Examples: GLFW: User previously installed GLFW callbacks are now saved and chain-called by the default callbacks. (#1759) - Examples: OpenGL3+GLFW: Fixed error condition when using the GLAD loader. (#2157) [@blackball] - Examples: OpenGL3+GLFW/SDL: Made main.cpp compile with IMGUI_IMPL_OPENGL_LOADER_CUSTOM (may be missing init). (#2178) [@doug-moen] diff --git a/examples/example_glfw_opengl2/main.cpp b/examples/example_glfw_opengl2/main.cpp index 6010b689..7074b5d7 100644 --- a/examples/example_glfw_opengl2/main.cpp +++ b/examples/example_glfw_opengl2/main.cpp @@ -44,7 +44,6 @@ int main(int, char**) //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls // Setup Platform/Renderer bindings - // If you have already installed GLFW callbacks in your app, call ImGui_ImplGlfw_InitForOpenGL() with install_callbacks=false and call them yourself. ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL2_Init(); diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp index 2e0ebbf9..cf939c11 100644 --- a/examples/example_glfw_opengl3/main.cpp +++ b/examples/example_glfw_opengl3/main.cpp @@ -90,7 +90,6 @@ int main(int, char**) //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls // Setup Platform/Renderer bindings - // If you have already installed GLFW callbacks in your app, call ImGui_ImplGlfw_InitForOpenGL() with install_callbacks=false and call them yourself. ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init(glsl_version); diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 8eba5df1..18016003 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -358,7 +358,6 @@ int main(int, char**) //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls // Setup Platform/Renderer bindings - // If you have already installed GLFW callbacks in your app, call ImGui_ImplGlfw_InitForVulkan() with install_callbacks=false and call the functions yourself. ImGui_ImplGlfw_InitForVulkan(window, true); ImGui_ImplVulkan_InitInfo init_info = {}; init_info.Instance = g_Instance; diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index 32baea7f..a4bcc31a 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -14,6 +14,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 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: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. // 2018-06-08: Misc: Extracted imgui_impl_glfw.cpp/.h away from the old combined GLFW+OpenGL/Vulkan examples. @@ -51,11 +52,17 @@ enum GlfwClientApi GlfwClientApi_OpenGL, GlfwClientApi_Vulkan }; -static GLFWwindow* g_Window = NULL; -static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown; -static double g_Time = 0.0; -static bool g_MouseJustPressed[5] = { false, false, false, false, false }; -static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; +static GLFWwindow* g_Window = NULL; +static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown; +static double g_Time = 0.0; +static bool g_MouseJustPressed[5] = { false, false, false, false, false }; +static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; + +// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any. +static GLFWmousebuttonfun g_PrevUserCallbackMousebutton = NULL; +static GLFWscrollfun g_PrevUserCallbackScroll = NULL; +static GLFWkeyfun g_PrevUserCallbackKey = NULL; +static GLFWcharfun g_PrevUserCallbackChar = NULL; static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data) { @@ -67,36 +74,48 @@ static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text) glfwSetClipboardString((GLFWwindow*)user_data, text); } -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) { + if (g_PrevUserCallbackMousebutton != NULL) + g_PrevUserCallbackMousebutton(window, button, action, mods); + if (action == GLFW_PRESS && button >= 0 && button < IM_ARRAYSIZE(g_MouseJustPressed)) g_MouseJustPressed[button] = true; } -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) { + if (g_PrevUserCallbackScroll != NULL) + g_PrevUserCallbackScroll(window, xoffset, yoffset); + ImGuiIO& io = ImGui::GetIO(); io.MouseWheelH += (float)xoffset; io.MouseWheel += (float)yoffset; } -void ImGui_ImplGlfw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (g_PrevUserCallbackKey != NULL) + g_PrevUserCallbackKey(window, key, scancode, action, mods); + ImGuiIO& io = ImGui::GetIO(); if (action == GLFW_PRESS) io.KeysDown[key] = true; if (action == GLFW_RELEASE) io.KeysDown[key] = false; - (void)mods; // Modifiers are not reliable across systems + // Modifiers are not reliable across systems 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]; io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; } -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c) { + if (g_PrevUserCallbackChar != NULL) + g_PrevUserCallbackChar(window, c); + ImGuiIO& io = ImGui::GetIO(); if (c > 0 && c < 0x10000) io.AddInputCharacter((unsigned short)c); @@ -151,12 +170,17 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this. g_MouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(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) { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + 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); } g_ClientApi = client_api; diff --git a/examples/imgui_impl_glfw.h b/examples/imgui_impl_glfw.h index 4bacd77b..ccbe840d 100644 --- a/examples/imgui_impl_glfw.h +++ b/examples/imgui_impl_glfw.h @@ -25,10 +25,8 @@ IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool in IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown(); IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame(); -// GLFW callbacks are installed by default if you call the InitXXX function with 'install_callbacks=true'. -// If you already have GLFW callbacks installed by your application, call the InitXXX function with install_callbacks=false, -// then call the functions yourselves from your own GLFW callbacks. -// You may also handle inputs yourself and use those as a reference. +// InitXXX function with 'install_callbacks=true': install GLFW callbacks. They will call user's previously installed callbacks, if any. +// InitXXX function with 'install_callbacks=false': do not install GLFW callbacks. You will need to call them yourself from your own GLFW callbacks. IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); From 6d7677534f80d0bc501f093ae606f6277cc57e6e Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 9 Nov 2018 14:31:14 +0100 Subject: [PATCH 05/11] Internals: SliderBehavior: Using axis indexing. --- imgui_widgets.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index e8a47b3b..963ada41 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2081,20 +2081,20 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0; + const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X; const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); const bool is_power = (power != 1.0f) && is_decimal; const float grab_padding = 2.0f; - const float slider_sz = is_horizontal ? (bb.GetWidth() - grab_padding * 2.0f) : (bb.GetHeight() - grab_padding * 2.0f); + const float slider_sz = (bb.Max[axis] - bb.Min[axis]) - grab_padding * 2.0f; float grab_sz = style.GrabMinSize; SIGNEDTYPE v_range = (v_min < v_max ? v_max - v_min : v_min - v_max); if (!is_decimal && v_range >= 0) // v_range < 0 may happen on integer overflows grab_sz = ImMax((float)(slider_sz / (v_range + 1)), style.GrabMinSize); // For integer sliders: if possible have the grab size represent 1 unit grab_sz = ImMin(grab_sz, slider_sz); const float slider_usable_sz = slider_sz - grab_sz; - const float slider_usable_pos_min = (is_horizontal ? bb.Min.x : bb.Min.y) + grab_padding + grab_sz*0.5f; - const float slider_usable_pos_max = (is_horizontal ? bb.Max.x : bb.Max.y) - grab_padding - grab_sz*0.5f; + const float slider_usable_pos_min = bb.Min[axis] + grab_padding + grab_sz*0.5f; + const float slider_usable_pos_max = bb.Max[axis] - grab_padding - grab_sz*0.5f; // For power curve sliders that cross over sign boundary we want the curve to be symmetric around 0.0f float linear_zero_pos; // 0.0->1.0f @@ -2125,9 +2125,9 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ } else { - const float mouse_abs_pos = is_horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; + const float mouse_abs_pos = g.IO.MousePos[axis]; clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f; - if (!is_horizontal) + if (axis == ImGuiAxis_Y) clicked_t = 1.0f - clicked_t; set_new_value = true; } @@ -2135,7 +2135,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ else if (g.ActiveIdSource == ImGuiInputSource_Nav) { const ImVec2 delta2 = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 0.0f, 0.0f); - float delta = is_horizontal ? delta2.x : -delta2.y; + float delta = (axis == ImGuiAxis_X) ? delta2.x : -delta2.y; if (g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) { ClearActiveID(); @@ -2227,10 +2227,10 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ // Output grab position so it can be displayed by the caller float grab_t = SliderCalcRatioFromValueT(data_type, *v, v_min, v_max, power, linear_zero_pos); - if (!is_horizontal) + if (axis == ImGuiAxis_Y) grab_t = 1.0f - grab_t; const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); - if (is_horizontal) + if (axis == ImGuiAxis_X) *out_grab_bb = ImRect(grab_pos - grab_sz*0.5f, bb.Min.y + grab_padding, grab_pos + grab_sz*0.5f, bb.Max.y - grab_padding); else *out_grab_bb = ImRect(bb.Min.x + grab_padding, grab_pos - grab_sz*0.5f, bb.Max.x - grab_padding, grab_pos + grab_sz*0.5f); From 6c1ae6cc71c6c6b9c0b5c19e1a793e15e8f0cde2 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 9 Nov 2018 14:41:40 +0100 Subject: [PATCH 06/11] Internals: DragBehavior: Added support for ImGuiDragFlags_Vertical to implement a vertical drag widget (no frontend function provided). --- imgui_internal.h | 11 +++++++++-- imgui_widgets.cpp | 27 ++++++++++++++++----------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index bac04ae6..b31aed4b 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -63,6 +63,7 @@ typedef int ImGuiNavDirSourceFlags; // -> enum ImGuiNavDirSourceFlags_ // Flags: typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for Separator() - internal typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for SliderBehavior() +typedef int ImGuiDragFlags; // -> enum ImGuiDragFlags_ // Flags: for DragBehavior() //------------------------------------------------------------------------- // STB libraries @@ -249,6 +250,12 @@ enum ImGuiSliderFlags_ ImGuiSliderFlags_Vertical = 1 << 0 }; +enum ImGuiDragFlags_ +{ + ImGuiDragFlags_None = 0, + ImGuiDragFlags_Vertical = 1 << 0 +}; + enum ImGuiColumnsFlags_ { // Default: 0 @@ -1246,7 +1253,7 @@ namespace ImGui // Widgets low-level behaviors IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); - IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power); + IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power, ImGuiDragFlags flags); IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb); IMGUI_API bool SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f); IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); @@ -1256,7 +1263,7 @@ namespace ImGui // Template functions are instantiated in imgui_widgets.cpp for a finite number of types. // To use them externally (for custom widget) you may need an "extern template" statement in your code in order to link to existing instances and silence Clang warnings (see #2036). // e.g. " extern template IMGUI_API float RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, float v); " - template IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, const T v_min, const T v_max, const char* format, float power); + template IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, const T v_min, const T v_max, const char* format, float power, ImGuiDragFlags flags); template IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, const T v_min, const T v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb); template IMGUI_API float SliderCalcRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, float power, float linear_zero_pos); template IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 963ada41..580bfc4e 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1706,9 +1706,10 @@ TYPE ImGui::RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, // This is called by DragBehavior() when the widget is active (held by mouse or being manipulated with Nav controls) template -bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_min, const TYPE v_max, const char* format, float power) +bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiDragFlags flags) { ImGuiContext& g = *GImGui; + const ImGuiAxis axis = (flags & ImGuiDragFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X; const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); const bool has_min_max = (v_min != v_max); @@ -1720,7 +1721,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const float adjust_delta = 0.0f; if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && g.IO.MouseDragMaxDistanceSqr[0] > 1.0f*1.0f) { - adjust_delta = g.IO.MouseDelta.x; + adjust_delta = g.IO.MouseDelta[axis]; if (g.IO.KeyAlt) adjust_delta *= 1.0f / 100.0f; if (g.IO.KeyShift) @@ -1729,11 +1730,15 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const else if (g.ActiveIdSource == ImGuiInputSource_Nav) { int decimal_precision = is_decimal ? ImParseFormatPrecision(format, 3) : 0; - adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f / 10.0f, 10.0f).x; + adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f / 10.0f, 10.0f)[axis]; v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); } adjust_delta *= v_speed; + // For vertical drag we currently assume that Up=higher value (like we do with vertical sliders). This may become a parameter. + if (axis == ImGuiAxis_Y) + adjust_delta = -adjust_delta; + // Clear current value on activation // Avoid altering values and clamping when we are _already_ past the limits and heading in the same direction, so e.g. if range is 0..255, current value is 300 and we are pushing to the right side, keep the 300. bool is_just_activated = g.ActiveIdIsJustActivated; @@ -1804,7 +1809,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const return true; } -bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power) +bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power, ImGuiDragFlags flags) { ImGuiContext& g = *GImGui; if (g.ActiveId == id) @@ -1819,12 +1824,12 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_s switch (data_type) { - case ImGuiDataType_S32: return DragBehaviorT(data_type, (ImS32*)v, v_speed, v_min ? *(const ImS32* )v_min : IM_S32_MIN, v_max ? *(const ImS32* )v_max : IM_S32_MAX, format, power); - case ImGuiDataType_U32: return DragBehaviorT(data_type, (ImU32*)v, v_speed, v_min ? *(const ImU32* )v_min : IM_U32_MIN, v_max ? *(const ImU32* )v_max : IM_U32_MAX, format, power); - case ImGuiDataType_S64: return DragBehaviorT(data_type, (ImS64*)v, v_speed, v_min ? *(const ImS64* )v_min : IM_S64_MIN, v_max ? *(const ImS64* )v_max : IM_S64_MAX, format, power); - case ImGuiDataType_U64: return DragBehaviorT(data_type, (ImU64*)v, v_speed, v_min ? *(const ImU64* )v_min : IM_U64_MIN, v_max ? *(const ImU64* )v_max : IM_U64_MAX, format, power); - case ImGuiDataType_Float: return DragBehaviorT(data_type, (float*)v, v_speed, v_min ? *(const float* )v_min : -FLT_MAX, v_max ? *(const float* )v_max : FLT_MAX, format, power); - case ImGuiDataType_Double: return DragBehaviorT(data_type, (double*)v, v_speed, v_min ? *(const double*)v_min : -DBL_MAX, v_max ? *(const double*)v_max : DBL_MAX, format, power); + case ImGuiDataType_S32: return DragBehaviorT(data_type, (ImS32*)v, v_speed, v_min ? *(const ImS32* )v_min : IM_S32_MIN, v_max ? *(const ImS32* )v_max : IM_S32_MAX, format, power, flags); + case ImGuiDataType_U32: return DragBehaviorT(data_type, (ImU32*)v, v_speed, v_min ? *(const ImU32* )v_min : IM_U32_MIN, v_max ? *(const ImU32* )v_max : IM_U32_MAX, format, power, flags); + case ImGuiDataType_S64: return DragBehaviorT(data_type, (ImS64*)v, v_speed, v_min ? *(const ImS64* )v_min : IM_S64_MIN, v_max ? *(const ImS64* )v_max : IM_S64_MAX, format, power, flags); + case ImGuiDataType_U64: return DragBehaviorT(data_type, (ImU64*)v, v_speed, v_min ? *(const ImU64* )v_min : IM_U64_MIN, v_max ? *(const ImU64* )v_max : IM_U64_MAX, format, power, flags); + case ImGuiDataType_Float: return DragBehaviorT(data_type, (float*)v, v_speed, v_min ? *(const float* )v_min : -FLT_MAX, v_max ? *(const float* )v_max : FLT_MAX, format, power, flags); + case ImGuiDataType_Double: return DragBehaviorT(data_type, (double*)v, v_speed, v_min ? *(const double*)v_min : -DBL_MAX, v_max ? *(const double*)v_max : DBL_MAX, format, power, flags); case ImGuiDataType_COUNT: break; } IM_ASSERT(0); @@ -1889,7 +1894,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa // Actual drag behavior ItemSize(total_bb, style.FramePadding.y); - const bool value_changed = DragBehavior(id, data_type, v, v_speed, v_min, v_max, format, power); + const bool value_changed = DragBehavior(id, data_type, v, v_speed, v_min, v_max, format, power, ImGuiDragFlags_None); if (value_changed) MarkItemEdited(id); From 5b1394c5ac351a1317e42fb45a066f441740a7af Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 9 Nov 2018 15:02:19 +0100 Subject: [PATCH 07/11] Update README.md --- docs/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 50ae7819..ecedfe66 100644 --- a/docs/README.md +++ b/docs/README.md @@ -109,7 +109,7 @@ Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/ _NB: those third-party bindings may be more or less maintained, more or less close to the original API (as people who create language bindings sometimes haven't used the C++ API themselves.. for the good reason that they aren't C++ users). Dear ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ Languages: (third-party bindings) -- C: [cimgui](https://github.com/cimgui/cimgui) (new 2018 auto-generated version!) +- C: [cimgui](https://github.com/cimgui/cimgui) (2018: now auto-generated! you can use its json output to generate bindings for other languages) - C#/.Net: [ImGui.NET](https://github.com/mellinoe/ImGui.NET) - ChaiScript: [imgui-chaiscript](https://github.com/JuJuBoSc/imgui-chaiscript) - D: [DerelictImgui](https://github.com/Extrawurst/DerelictImgui) @@ -126,12 +126,11 @@ Languages: (third-party bindings) - Swift [swift-imgui](https://github.com/mnmly/Swift-imgui) Frameworks: -- Renderers: DirectX 9, DirectX 10, DirectX 11, DirectX 12, Metal, OpenGL2, OpenGL3+/ES2/ES3, Vulkan: [examples/](https://github.com/ocornut/imgui/tree/master/examples) +- Renderers: DirectX 9/10/11/12, Metal, OpenGL2, OpenGL3+/ES2/ES3, Vulkan: [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Platform: GLFW, SDL, Win32, OSX, Freeglut: [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Framework: Allegro 5, Marmalade: [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Unmerged PR: SDL2 + OpenGLES + Emscripten: [#336](https://github.com/ocornut/imgui/pull/336) - Unmerged PR: Android: [#421](https://github.com/ocornut/imgui/pull/421) -- Unmerged PR: ORX: [#1843](https://github.com/ocornut/imgui/pull/1843) - Cinder: [Cinder-ImGui](https://github.com/simongeilfus/Cinder-ImGui) - Cocos2d-x: [imguix](https://github.com/c0i/imguix), [#551](https://github.com/ocornut/imgui/issues/551) - Flexium: [FlexGUI](https://github.com/DXsmiley/FlexGUI) @@ -140,6 +139,7 @@ Frameworks: - Ogre: [ogreimgui](https://bitbucket.org/LMCrashy/ogreimgui/src) - OpenFrameworks: [ofxImGui](https://github.com/jvcleave/ofxImGui) - OpenSceneGraph/OSG: [gist](https://gist.github.com/fulezi/d2442ca7626bf270226014501357042c) +- ORX: [pr #1843](https://github.com/ocornut/imgui/pull/1843) - LÖVE+Lua: [love-imgui](https://github.com/slages/love-imgui) - Magnum: [magnum-imgui](https://github.com/lecopivo/magnum-imgui), [MagnumImguiPort](https://github.com/lecopivo/MagnumImguiPort) - NanoRT: [syoyo/imgui](https://github.com/syoyo/imgui/tree/nanort) From 19b4fcdacb71b3901e8f5831f37218c6afff3aca Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 13 Nov 2018 11:23:15 +0100 Subject: [PATCH 08/11] Made IsWindowFocused() work outside of NewFrame()-EndFrame() and added comments about how ImGuiFocusedFlags_AnyWindow should NOT be used in place of io.WantCaptureMouse. (#2185) --- imgui.cpp | 2 +- imgui.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index da8ac5bc..54fac2cb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5642,11 +5642,11 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) { ImGuiContext& g = *GImGui; - IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() if (flags & ImGuiFocusedFlags_AnyWindow) return g.NavWindow != NULL; + IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() switch (flags & (ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows)) { case ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows: diff --git a/imgui.h b/imgui.h index 90cde630..24f24ff0 100644 --- a/imgui.h +++ b/imgui.h @@ -732,7 +732,7 @@ enum ImGuiFocusedFlags_ ImGuiFocusedFlags_None = 0, ImGuiFocusedFlags_ChildWindows = 1 << 0, // IsWindowFocused(): Return true if any children of the window is focused ImGuiFocusedFlags_RootWindow = 1 << 1, // IsWindowFocused(): Test from root window (top most parent of the current hierarchy) - ImGuiFocusedFlags_AnyWindow = 1 << 2, // IsWindowFocused(): Return true if any window is focused + ImGuiFocusedFlags_AnyWindow = 1 << 2, // IsWindowFocused(): Return true if any window is focused. Important: If you are trying to tell how to dispatch your low-level inputs, do NOT use this. Use ImGui::GetIO().WantCaptureMouse instead. ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows }; From f52f0a52771f9609267e9ad67d4f2835e0df0072 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 13 Nov 2018 18:54:02 +0100 Subject: [PATCH 09/11] Examples: OpenGL3: Added support for GL 4.5's glClipControl(GL_UPPER_LEFT). (#2186) --- docs/CHANGELOG.txt | 1 + examples/imgui_impl_opengl3.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index b0409bf9..9126cfd1 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -79,6 +79,7 @@ Other Changes: - Examples: DirectX10, DirectX11: Removed seemingly unnecessary calls to invalidate and recreate device objects in the WM_SIZE handler. (#2088) [@ice1000] - Examples: GLFW: User previously installed GLFW callbacks are now saved and chain-called by the default callbacks. (#1759) +- Examples: OpenGL3: Added support for GL 4.5's glClipControl(GL_UPPER_LEFT). (#2186) - Examples: OpenGL3+GLFW: Fixed error condition when using the GLAD loader. (#2157) [@blackball] - Examples: OpenGL3+GLFW/SDL: Made main.cpp compile with IMGUI_IMPL_OPENGL_LOADER_CUSTOM (may be missing init). (#2178) [@doug-moen] diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp index 2a031004..18b62f86 100644 --- a/examples/imgui_impl_opengl3.cpp +++ b/examples/imgui_impl_opengl3.cpp @@ -11,6 +11,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT). // 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used. // 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES". // 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation. @@ -162,6 +163,11 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + bool clip_origin_lower_left = true; +#ifdef GL_CLIP_ORIGIN + GLenum last_clip_origin; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) + clip_origin_lower_left = (last_clip_origin == GL_LOWER_LEFT); +#endif // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill glEnable(GL_BLEND); @@ -234,7 +240,10 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) { // Apply scissor/clipping rectangle - glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); + if (clip_origin_lower_left) + glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); + else + glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) // Bind texture, Draw glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); From f2d577c33f2f20869fc5d3f507e6b3109395829d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 13 Nov 2018 22:00:12 +0100 Subject: [PATCH 10/11] Viewport: BeginMainMenuBar(): explicitly set viewport to avoid creating new one when ImGuiConfigFlags_ViewportsNoMerge is set + misc shallow changes. --- imgui.cpp | 9 +++------ imgui_widgets.cpp | 6 ++++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 80c8baad..43b52917 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3001,7 +3001,8 @@ void ImGui::UpdateMouseMovingWindow() { // Try to merge the window back into the main viewport. // This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports) - UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport); + if (g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport); // Restore the mouse viewport so that we don't hover the viewport _under_ the moved window during the frame we released the mouse button. if (!IsDragDropPayloadBeingAccepted()) @@ -5073,7 +5074,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->Pos = FindBestWindowPosForPopup(window); if (window->ViewportAllowPlatformMonitorExtend >= 0 && !window->ViewportOwned) - { if (!window->Viewport->GetRect().Contains(window->Rect())) { // Late create viewport, based on the assumption that with our calculations, the DPI will be known ahead (same as the DPI of the selection done in UpdateSelectWindowViewport) @@ -5089,7 +5089,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->FontDpiScale = (g.IO.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleFonts) ? window->Viewport->DpiScale : 1.0f; SetCurrentWindow(window); } - } // Synchronize viewport --> window in case the platform window has been moved or resized from the OS/WM if (window->ViewportOwned) @@ -7197,8 +7196,6 @@ static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window) static void ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport) { ImGuiContext& g = *GImGui; - if (!(g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) - return; if (!(viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) || window->Viewport == viewport) return; if (!viewport->GetRect().Contains(window->Rect())) @@ -7510,10 +7507,10 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) // Mark window as allowed to protrude outside of its viewport and into the current monitor // We need to take account of the possibility that mouse may become invalid. - const bool use_mouse_ref = (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow); if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) { ImVec2 mouse_ref = (flags & ImGuiWindowFlags_Tooltip) ? g.IO.MousePos : g.CurrentPopupStack.back().OpenMousePos; + bool use_mouse_ref = (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow); bool mouse_valid = IsMousePosValid(&mouse_ref); if ((window->Appearing || (flags & ImGuiWindowFlags_Tooltip)) && (!use_mouse_ref || mouse_valid)) window->ViewportAllowPlatformMonitorExtend = FindPlatformMonitorForPos((use_mouse_ref && mouse_valid) ? mouse_ref : NavCalcPreferredRefPos()); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 75c15ea1..18e74020 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5439,9 +5439,11 @@ float ImGuiMenuColumns::CalcExtraSpace(float avail_w) bool ImGui::BeginMainMenuBar() { ImGuiContext& g = *GImGui; + ImGuiViewport* viewport = g.Viewports[0]; g.NextWindowData.MenuBarOffsetMinVal = ImVec2(g.Style.DisplaySafeAreaPadding.x, ImMax(g.Style.DisplaySafeAreaPadding.y - g.Style.FramePadding.y, 0.0f)); - SetNextWindowPos(g.Viewports[0]->Pos); - SetNextWindowSize(ImVec2(g.Viewports[0]->Size.x, g.NextWindowData.MenuBarOffsetMinVal.y + g.FontBaseSize + g.Style.FramePadding.y)); + SetNextWindowPos(viewport->Pos); + SetNextWindowSize(ImVec2(viewport->Size.x, g.NextWindowData.MenuBarOffsetMinVal.y + g.FontBaseSize + g.Style.FramePadding.y)); + SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our onw viewport when ImGuiConfigFlags_ViewportsNoMerge is set. PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0,0)); ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar; From aa668c410a020e6cb40dbdd66620df1f8c7daa3c Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 15 Nov 2018 13:53:53 +0100 Subject: [PATCH 11/11] Nav: Fixed an assert in certain circumstance (mostly when using popups) when mouse positions stop being valid. (#2168) + adding a else block to make NavCalcPreferredRefPos() more explicit. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 25 ++++++++++++++++--------- imgui_internal.h | 4 +++- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9126cfd1..c7603717 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -46,6 +46,7 @@ Other Changes: accidental alteration of window position. We now round the provided size. (#2067) - Nav, Focus: Fixed ImGuiWindowFlags_NoBringToFrontOnFocus windows not being restoring focus properly after the main menu bar or last focused window is deactivated. +- Nav: Fixed an assert in certain circumstance (mostly when using popups) when mouse positions stop being valid. (#2168) - DragFloat: Fixed a situation where dragging with value rounding enabled or with a power curve erroneously wrapped the value to one of the min/max edge. (#2024, #708, #320, #2075). - DragFloat: Disabled using power curve when one edge is FLT_MAX (broken in 1.61). (#2024) diff --git a/imgui.cpp b/imgui.cpp index 54fac2cb..c6452b97 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2966,7 +2966,7 @@ static void ImGui::UpdateMouseInputs() // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well) if (IsMousePosValid(&g.IO.MousePos)) - g.IO.MousePos = ImFloor(g.IO.MousePos); + g.IO.MousePos = g.LastValidMousePos = ImFloor(g.IO.MousePos); // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MousePosPrev)) @@ -6415,8 +6415,8 @@ void ImGui::OpenPopupEx(ImGuiID id) popup_ref.ParentWindow = parent_window; popup_ref.OpenFrameCount = g.FrameCount; popup_ref.OpenParentId = parent_window->IDStack.back(); - popup_ref.OpenMousePos = g.IO.MousePos; popup_ref.OpenPopupPos = NavCalcPreferredRefPos(); + popup_ref.OpenMousePos = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : popup_ref.OpenPopupPos; //printf("[%05d] OpenPopupEx(0x%08X)\n", g.FrameCount, id); if (g.OpenPopupStack.Size < current_stack_size + 1) @@ -7093,13 +7093,20 @@ static ImVec2 ImGui::NavCalcPreferredRefPos() { ImGuiContext& g = *GImGui; if (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow) - return ImFloor(g.IO.MousePos); - - // When navigation is active and mouse is disabled, decide on an arbitrary position around the bottom left of the currently navigated item - const ImRect& rect_rel = g.NavWindow->NavRectRel[g.NavLayer]; - ImVec2 pos = g.NavWindow->Pos + ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x*4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); - ImRect visible_rect = GetViewportRect(); - return ImFloor(ImClamp(pos, visible_rect.Min, visible_rect.Max)); // ImFloor() is important because non-integer mouse position application in back-end might be lossy and result in undesirable non-zero delta. + { + // Mouse (we need a fallback in case the mouse becomes invalid after being used) + if (IsMousePosValid(&g.IO.MousePos)) + return g.IO.MousePos; + return g.LastValidMousePos; + } + else + { + // When navigation is active and mouse is disabled, decide on an arbitrary position around the bottom left of the currently navigated item. + const ImRect& rect_rel = g.NavWindow->NavRectRel[g.NavLayer]; + ImVec2 pos = g.NavWindow->Pos + ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); + ImRect visible_rect = GetViewportRect(); + return ImFloor(ImClamp(pos, visible_rect.Min, visible_rect.Max)); // ImFloor() is important because non-integer mouse position application in back-end might be lossy and result in undesirable non-zero delta. + } } float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode) diff --git a/imgui_internal.h b/imgui_internal.h index b31aed4b..f3385d85 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -687,8 +687,9 @@ struct ImGuiContext ImGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard) ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation. float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation. + ImVec2 LastValidMousePos; ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow. - ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() + ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() ImVector FontStack; // Stack for PushFont()/PopFont() ImVector OpenPopupStack; // Which popups are open (persistent) @@ -833,6 +834,7 @@ struct ImGuiContext ActiveIdSource = ImGuiInputSource_None; LastActiveId = 0; LastActiveIdTimer = 0.0f; + LastValidMousePos = ImVec2(0.0f, 0.0f); MovingWindow = NULL; NextTreeNodeOpenVal = false; NextTreeNodeOpenCond = 0;