Merge branch 'master' into docking + fixes for #3259

# Conflicts:
#	examples/example_glfw_vulkan/main.cpp
#	examples/example_sdl_vulkan/main.cpp
#	examples/imgui_impl_sdl.cpp
#	imgui.cpp
docking
ocornut 5 years ago
commit 5d472c4895

@ -288,6 +288,14 @@ jobs:
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime, Clang)
run: |
echo '#define IMGUI_IMPLEMENTATION' > example_single_file.cpp
echo '#define IMGUI_DISABLE_DEMO_WINDOWS' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2 - name: Build example_glfw_opengl2
run: make -C examples/example_glfw_opengl2 run: make -C examples/example_glfw_opengl2
@ -324,6 +332,13 @@ jobs:
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
clang++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp clang++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime)
run: |
echo '#define IMGUI_IMPLEMENTATION' > example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2 - name: Build example_glfw_opengl2
run: make -C examples/example_glfw_opengl2 run: make -C examples/example_glfw_opengl2

@ -123,16 +123,25 @@ Other Changes:
- Metrics: Added a "Settings" section with some details about persistent ini settings. - Metrics: Added a "Settings" section with some details about persistent ini settings.
- Nav, Menus: Fix vertical wrap-around in menus or popups created with multiple appending calls to - Nav, Menus: Fix vertical wrap-around in menus or popups created with multiple appending calls to
BeginMenu()/EndMenu() or BeginPopup/EndPopup(). (#3223, #1207) [@rokups] BeginMenu()/EndMenu() or BeginPopup/EndPopup(). (#3223, #1207) [@rokups]
- Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when
drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups]
- CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups,
static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns).
Fixed a static contructor which led to this dependency on some compiler setups (unclear which).
- Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327)
- Backends: Win32: Fix _WIN32_WINNT < 0x0600 (MinGW defaults to 0x502 == Windows 2003). (#3183) - Backends: Win32: Fix _WIN32_WINNT < 0x0600 (MinGW defaults to 0x502 == Windows 2003). (#3183)
- Backends: SDL: Report a zero display-size when window is minimized, consistent with other backends,
making more render/clipping code use an early out path.
- Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the - Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the
projection matrix top and bottom values. (#3143, #3146) [@u3shit] projection matrix top and bottom values. (#3143, #3146) [@u3shit]
- Backends: OpenGL: On OSX, if unspecified by app, made default GLSL version 150. (#3199) [@albertvaka] - Backends: OpenGL: On OSX, if unspecified by app, made default GLSL version 150. (#3199) [@albertvaka]
- Backends: Vulkan: Fixed error in if initial frame has no vertices. (#3177) - Backends: Vulkan: Fixed error in if initial frame has no vertices. (#3177)
- Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData - Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData
structure didn't have any vertices. (#2697) [@kudaba] structure didn't have any vertices. (#2697) [@kudaba]
- Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when - Backends: OSX: Added workaround to avoid fast mouse clicks. (#3261, #1992, #2525) [@nburrus]
drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] - Examples: GLFW+Vulkan, SDL+Vulkan: Fix for handling of minimized windows. (#3259)
- Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm
not forwarding right and center mouse clicks. (#3260) [@nburrus]
----------------------------------------------------------------------- -----------------------------------------------------------------------

@ -72,14 +72,38 @@
ImGui_ImplOSX_HandleEvent(event, self.view); ImGui_ImplOSX_HandleEvent(event, self.view);
} }
- (void)rightMouseDown:(NSEvent *)event {
ImGui_ImplOSX_HandleEvent(event, self.view);
}
- (void)otherMouseDown:(NSEvent *)event {
ImGui_ImplOSX_HandleEvent(event, self.view);
}
- (void)mouseUp:(NSEvent *)event { - (void)mouseUp:(NSEvent *)event {
ImGui_ImplOSX_HandleEvent(event, self.view); ImGui_ImplOSX_HandleEvent(event, self.view);
} }
- (void)rightMouseUp:(NSEvent *)event {
ImGui_ImplOSX_HandleEvent(event, self.view);
}
- (void)otherMouseUp:(NSEvent *)event {
ImGui_ImplOSX_HandleEvent(event, self.view);
}
- (void)mouseDragged:(NSEvent *)event { - (void)mouseDragged:(NSEvent *)event {
ImGui_ImplOSX_HandleEvent(event, self.view); ImGui_ImplOSX_HandleEvent(event, self.view);
} }
- (void)rightMouseDragged:(NSEvent *)event {
ImGui_ImplOSX_HandleEvent(event, self.view);
}
- (void)otherMouseDragged:(NSEvent *)event {
ImGui_ImplOSX_HandleEvent(event, self.view);
}
- (void)scrollWheel:(NSEvent *)event { - (void)scrollWheel:(NSEvent *)event {
ImGui_ImplOSX_HandleEvent(event, self.view); ImGui_ImplOSX_HandleEvent(event, self.view);
} }

@ -139,14 +139,22 @@
} }
// Forward Mouse/Keyboard events to dear imgui OSX back-end. It returns true when imgui is expecting to use the event. // Forward Mouse/Keyboard events to dear imgui OSX back-end. It returns true when imgui is expecting to use the event.
-(void)keyUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)keyUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)rightMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)otherMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } -(void)rightMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)otherMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)rightMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)otherMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)rightMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)otherMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
-(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); }
@end @end

@ -48,8 +48,9 @@ static int g_SwapChainResizeHeight = 0;
static void check_vk_result(VkResult err) static void check_vk_result(VkResult err)
{ {
if (err == 0) return; if (err == 0)
printf("VkResult %d\n", err); return;
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
if (err < 0) if (err < 0)
abort(); abort();
} }
@ -58,7 +59,7 @@ static void check_vk_result(VkResult err)
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
{ {
(void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments
fprintf(stderr, "[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
return VK_FALSE; return VK_FALSE;
} }
#endif // IMGUI_VULKAN_DEBUG_REPORT #endif // IMGUI_VULKAN_DEBUG_REPORT
@ -225,7 +226,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
// Create SwapChain, RenderPass, Framebuffer, etc. // Create SwapChain, RenderPass, Framebuffer, etc.
IM_ASSERT(g_MinImageCount >= 2); IM_ASSERT(g_MinImageCount >= 2);
ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
} }
static void CleanupVulkan() static void CleanupVulkan()
@ -247,7 +248,7 @@ static void CleanupVulkanWindow()
ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator);
} }
static void FrameRender(ImGui_ImplVulkanH_Window* wd) static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
{ {
VkResult err; VkResult err;
@ -285,8 +286,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
} }
// Record Imgui Draw Data and draw funcs into command buffer // Record dear imgui primitives into command buffer
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer);
// Submit command buffer // Submit command buffer
vkCmdEndRenderPass(fd->CommandBuffer); vkCmdEndRenderPass(fd->CommandBuffer);
@ -467,11 +468,12 @@ int main(int, char**)
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents(); glfwPollEvents();
if (g_SwapChainRebuild) // Resize swap chain?
if (g_SwapChainRebuild && g_SwapChainResizeWidth > 0 && g_SwapChainResizeHeight > 0)
{ {
g_SwapChainRebuild = false; g_SwapChainRebuild = false;
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount); ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount);
g_MainWindowData.FrameIndex = 0; g_MainWindowData.FrameIndex = 0;
} }
@ -519,8 +521,11 @@ int main(int, char**)
// Rendering // Rendering
ImGui::Render(); ImGui::Render();
ImDrawData* main_draw_data = ImGui::GetDrawData();
const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f);
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
FrameRender(wd); if (!main_is_minimized)
FrameRender(wd, main_draw_data);
// Update and Render additional Platform Windows // Update and Render additional Platform Windows
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
@ -529,7 +534,9 @@ int main(int, char**)
ImGui::RenderPlatformWindowsDefault(); ImGui::RenderPlatformWindowsDefault();
} }
FramePresent(wd); // Present Main Platform Window
if (!main_is_minimized)
FramePresent(wd);
} }
// Cleanup // Cleanup

@ -8,7 +8,7 @@
# Mac OS X: # Mac OS X:
# brew install sdl2 # brew install sdl2
# MSYS2: # MSYS2:
# pacman -S mingw-w64-i686-SDL # pacman -S mingw-w64-i686-SDL2
# #
#CXX = g++ #CXX = g++

@ -8,7 +8,7 @@
# Mac OS X: # Mac OS X:
# brew install sdl2 # brew install sdl2
# MSYS2: # MSYS2:
# pacman -S mingw-w64-i686-SDL # pacman -S mingw-w64-i686-SDL2
# #
#CXX = g++ #CXX = g++

@ -40,8 +40,9 @@ static int g_SwapChainResizeHeight = 0;
static void check_vk_result(VkResult err) static void check_vk_result(VkResult err)
{ {
if (err == 0) return; if (err == 0)
printf("VkResult %d\n", err); return;
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
if (err < 0) if (err < 0)
abort(); abort();
} }
@ -50,7 +51,7 @@ static void check_vk_result(VkResult err)
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
{ {
(void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments
fprintf(stderr, "[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
return VK_FALSE; return VK_FALSE;
} }
#endif // IMGUI_VULKAN_DEBUG_REPORT #endif // IMGUI_VULKAN_DEBUG_REPORT
@ -217,7 +218,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
// Create SwapChain, RenderPass, Framebuffer, etc. // Create SwapChain, RenderPass, Framebuffer, etc.
IM_ASSERT(g_MinImageCount >= 2); IM_ASSERT(g_MinImageCount >= 2);
ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
} }
static void CleanupVulkan() static void CleanupVulkan()
@ -239,7 +240,7 @@ static void CleanupVulkanWindow()
ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator);
} }
static void FrameRender(ImGui_ImplVulkanH_Window* wd) static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
{ {
VkResult err; VkResult err;
@ -277,8 +278,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd)
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
} }
// Record Imgui Draw Data and draw funcs into command buffer // Record dear imgui primitives into command buffer
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer);
// Submit command buffer // Submit command buffer
vkCmdEndRenderPass(fd->CommandBuffer); vkCmdEndRenderPass(fd->CommandBuffer);
@ -458,17 +459,21 @@ int main(int, char**)
done = true; done = true;
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window)) if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window))
{ {
// Note: your own application may rely on SDL_WINDOWEVENT_MINIMIZED/SDL_WINDOWEVENT_RESTORED to skip updating all-together.
// Here ImGui_ImplSDL2_NewFrame() will set io.DisplaySize to zero which will disable rendering but let application run.
// Please note that you can't Present into a minimized window.
g_SwapChainResizeWidth = (int)event.window.data1; g_SwapChainResizeWidth = (int)event.window.data1;
g_SwapChainResizeHeight = (int)event.window.data2; g_SwapChainResizeHeight = (int)event.window.data2;
g_SwapChainRebuild = true; g_SwapChainRebuild = true;
} }
} }
if (g_SwapChainRebuild) // Resize swap chain?
if (g_SwapChainRebuild && g_SwapChainResizeWidth > 0 && g_SwapChainResizeHeight > 0)
{ {
g_SwapChainRebuild = false; g_SwapChainRebuild = false;
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount); ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount);
g_MainWindowData.FrameIndex = 0; g_MainWindowData.FrameIndex = 0;
} }
@ -516,8 +521,11 @@ int main(int, char**)
// Rendering // Rendering
ImGui::Render(); ImGui::Render();
ImDrawData* main_draw_data = ImGui::GetDrawData();
const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f);
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
FrameRender(wd); if (!main_is_minimized)
FrameRender(wd, main_draw_data);
// Update and Render additional Platform Windows // Update and Render additional Platform Windows
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
@ -526,7 +534,9 @@ int main(int, char**)
ImGui::RenderPlatformWindowsDefault(); ImGui::RenderPlatformWindowsDefault();
} }
FramePresent(wd); // Present Main Platform Window
if (!main_is_minimized)
FramePresent(wd);
} }
// Cleanup // Cleanup

@ -357,7 +357,8 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT *ev)
return true; return true;
case ALLEGRO_EVENT_KEY_CHAR: case ALLEGRO_EVENT_KEY_CHAR:
if (ev->keyboard.display == g_Display) if (ev->keyboard.display == g_Display)
io.AddInputCharacter((unsigned int)ev->keyboard.unichar); if (ev->keyboard.unichar != 0)
io.AddInputCharacter((unsigned int)ev->keyboard.unichar);
return true; return true;
case ALLEGRO_EVENT_KEY_DOWN: case ALLEGRO_EVENT_KEY_DOWN:
case ALLEGRO_EVENT_KEY_UP: case ALLEGRO_EVENT_KEY_UP:

@ -74,7 +74,7 @@ enum GlfwClientApi
static GLFWwindow* g_Window = NULL; // Main window static GLFWwindow* g_Window = NULL; // Main window
static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown; static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown;
static double g_Time = 0.0; static double g_Time = 0.0;
static bool g_MouseJustPressed[5] = { false, false, false, false, false }; static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {};
static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
static bool g_InstalledCallbacks = false; static bool g_InstalledCallbacks = false;
static bool g_WantUpdateMonitors = true; static bool g_WantUpdateMonitors = true;

@ -15,6 +15,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2020-05-25: Inputs: Added a fix for missing trackpad clicks when done with "soft tap".
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
// 2019-10-11: Inputs: Fix using Backspace key. // 2019-10-11: Inputs: Fix using Backspace key.
// 2019-07-21: Re-added clipboard handlers as they are not enabled by default in core imgui.cpp (reverted 2019-05-18 change). // 2019-07-21: Re-added clipboard handlers as they are not enabled by default in core imgui.cpp (reverted 2019-05-18 change).
@ -28,6 +29,8 @@
static CFAbsoluteTime g_Time = 0.0; static CFAbsoluteTime g_Time = 0.0;
static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
static bool g_MouseCursorHidden = false; static bool g_MouseCursorHidden = false;
static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {};
static bool g_MouseDown[ImGuiMouseButton_COUNT] = {};
// Undocumented methods for creating cursors. // Undocumented methods for creating cursors.
@interface NSCursor() @interface NSCursor()
@ -122,9 +125,17 @@ void ImGui_ImplOSX_Shutdown()
{ {
} }
static void ImGui_ImplOSX_UpdateMouseCursor() static void ImGui_ImplOSX_UpdateMouseCursorAndButtons()
{ {
// Update buttons
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
{
// If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
io.MouseDown[i] = g_MouseJustPressed[i] || g_MouseDown[i];
g_MouseJustPressed[i] = false;
}
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return; return;
@ -168,7 +179,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
io.DeltaTime = current_time - g_Time; io.DeltaTime = current_time - g_Time;
g_Time = current_time; g_Time = current_time;
ImGui_ImplOSX_UpdateMouseCursor(); ImGui_ImplOSX_UpdateMouseCursorAndButtons();
} }
static int mapCharacterToKey(int c) static int mapCharacterToKey(int c)
@ -198,16 +209,16 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown) if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown)
{ {
int button = (int)[event buttonNumber]; int button = (int)[event buttonNumber];
if (button >= 0 && button < IM_ARRAYSIZE(io.MouseDown)) if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown))
io.MouseDown[button] = true; g_MouseDown[button] = g_MouseJustPressed[button] = true;
return io.WantCaptureMouse; return io.WantCaptureMouse;
} }
if (event.type == NSEventTypeLeftMouseUp || event.type == NSEventTypeRightMouseUp || event.type == NSEventTypeOtherMouseUp) if (event.type == NSEventTypeLeftMouseUp || event.type == NSEventTypeRightMouseUp || event.type == NSEventTypeOtherMouseUp)
{ {
int button = (int)[event buttonNumber]; int button = (int)[event buttonNumber];
if (button >= 0 && button < IM_ARRAYSIZE(io.MouseDown)) if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown))
io.MouseDown[button] = false; g_MouseDown[button] = false;
return io.WantCaptureMouse; return io.WantCaptureMouse;
} }

@ -20,6 +20,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
// 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2). // 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2).
// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state). // 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state).
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
@ -452,6 +453,8 @@ void ImGui_ImplSDL2_NewFrame(SDL_Window* window)
int w, h; int w, h;
int display_w, display_h; int display_w, display_h;
SDL_GetWindowSize(window, &w, &h); SDL_GetWindowSize(window, &w, &h);
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
w = h = 0;
SDL_GL_GetDrawableSize(window, &display_w, &display_h); SDL_GL_GetDrawableSize(window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h); io.DisplaySize = ImVec2((float)w, (float)h);
if (w > 0 && h > 0) if (w > 0 && h > 0)

@ -1036,6 +1036,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
{ {
VkResult err; VkResult err;
VkSwapchainKHR old_swapchain = wd->Swapchain; VkSwapchainKHR old_swapchain = wd->Swapchain;
wd->Swapchain = NULL;
err = vkDeviceWaitIdle(device); err = vkDeviceWaitIdle(device);
check_vk_result(err); check_vk_result(err);
@ -1192,7 +1193,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
} }
} }
void ImGui_ImplVulkanH_CreateWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count) // Create or resize window
void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count)
{ {
(void)instance; (void)instance;
ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count); ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count);
@ -1308,7 +1310,7 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
// Create SwapChain, RenderPass, Framebuffer, etc. // Create SwapChain, RenderPass, Framebuffer, etc.
wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true; wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
ImGui_ImplVulkanH_CreateWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount); ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount);
data->WindowOwned = true; data->WindowOwned = true;
} }
@ -1333,7 +1335,7 @@ static void ImGui_ImplVulkan_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
return; return;
ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo; ImGui_ImplVulkan_InitInfo* v = &g_VulkanInitInfo;
data->Window.ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true; data->Window.ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
ImGui_ImplVulkanH_CreateWindow(v->Instance, v->PhysicalDevice, v->Device, &data->Window, v->QueueFamily, v->Allocator, (int)size.x, (int)size.y, v->MinImageCount); ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &data->Window, v->QueueFamily, v->Allocator, (int)size.x, (int)size.y, v->MinImageCount);
} }
static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*) static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)

@ -73,7 +73,7 @@ struct ImGui_ImplVulkanH_Frame;
struct ImGui_ImplVulkanH_Window; struct ImGui_ImplVulkanH_Window;
// Helpers // Helpers
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wnd, const VkAllocationCallbacks* allocator); IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wnd, const VkAllocationCallbacks* allocator);
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space); IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count); IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);

@ -1178,17 +1178,21 @@ ImGuiIO::ImGuiIO()
// - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message // - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message
void ImGuiIO::AddInputCharacter(unsigned int c) void ImGuiIO::AddInputCharacter(unsigned int c)
{ {
InputQueueCharacters.push_back(c > 0 && c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID); if (c != 0)
InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID);
} }
// UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so // UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so
// we should save the high surrogate. // we should save the high surrogate.
void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c) void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
{ {
if (c == 0 && InputQueueSurrogate == 0)
return;
if ((c & 0xFC00) == 0xD800) // High surrogate, must save if ((c & 0xFC00) == 0xD800) // High surrogate, must save
{ {
if (InputQueueSurrogate != 0) if (InputQueueSurrogate != 0)
InputQueueCharacters.push_back(0xFFFD); InputQueueCharacters.push_back(IM_UNICODE_CODEPOINT_INVALID);
InputQueueSurrogate = c; InputQueueSurrogate = c;
return; return;
} }
@ -1213,7 +1217,7 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
{ {
unsigned int c = 0; unsigned int c = 0;
utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL); utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL);
if (c > 0) if (c != 0)
InputQueueCharacters.push_back((ImWchar)c); InputQueueCharacters.push_back((ImWchar)c);
} }
} }
@ -5419,6 +5423,21 @@ static const ImGuiResizeGripDef resize_grip_def[4] =
{ ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper-right (Unused) { ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper-right (Unused)
}; };
struct ImGuiResizeBorderDef
{
ImVec2 InnerDir;
ImVec2 CornerPosN1, CornerPosN2;
float OuterAngle;
};
static const ImGuiResizeBorderDef resize_border_def[4] =
{
{ ImVec2(0,+1), ImVec2(0,0), ImVec2(1,0), IM_PI*1.50f }, // Top
{ ImVec2(-1,0), ImVec2(1,0), ImVec2(1,1), IM_PI*0.00f }, // Right
{ ImVec2(0,-1), ImVec2(1,1), ImVec2(0,1), IM_PI*0.50f }, // Bottom
{ ImVec2(+1,0), ImVec2(0,1), ImVec2(0,0), IM_PI*1.00f } // Left
};
static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness) static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness)
{ {
ImRect rect = window->Rect(); ImRect rect = window->Rect();
@ -5595,19 +5614,6 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
int border_held = window->ResizeBorderHeld; int border_held = window->ResizeBorderHeld;
if (border_held != -1) if (border_held != -1)
{ {
struct ImGuiResizeBorderDef
{
ImVec2 InnerDir;
ImVec2 CornerPosN1, CornerPosN2;
float OuterAngle;
};
static const ImGuiResizeBorderDef resize_border_def[4] =
{
{ ImVec2(0,+1), ImVec2(0,0), ImVec2(1,0), IM_PI*1.50f }, // Top
{ ImVec2(-1,0), ImVec2(1,0), ImVec2(1,1), IM_PI*0.00f }, // Right
{ ImVec2(0,-1), ImVec2(1,1), ImVec2(0,1), IM_PI*0.50f }, // Bottom
{ ImVec2(+1,0), ImVec2(0,1), ImVec2(0,0), IM_PI*1.00f } // Left
};
const ImGuiResizeBorderDef& def = resize_border_def[border_held]; const ImGuiResizeBorderDef& def = resize_border_def[border_held];
ImRect border_r = GetResizeBorderRect(window, border_held, rounding, 0.0f); ImRect border_r = GetResizeBorderRect(window, border_held, rounding, 0.0f);
window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.CornerPosN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI*0.25f, def.OuterAngle); window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.CornerPosN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI*0.25f, def.OuterAngle);
@ -15302,8 +15308,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
// Debugging enums // Debugging enums
enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type
const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentRegionRect" }; const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentRegionRect" };
enum { TRT_OuterRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersDesired, TRT_ColumnsContentRowsFrozen, TRT_ColumnsContentRowsUnfrozen, TRT_Count }; // Tables Rect Type enum { TRT_OuterRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersIdeal, TRT_ColumnsContentRowsFrozen, TRT_ColumnsContentRowsUnfrozen, TRT_Count }; // Tables Rect Type
const char* trt_rects_names[TRT_Count] = { "OuterRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersDesired", "ColumnsContentRowsFrozen", "ColumnsContentRowsUnfrozen" }; const char* trt_rects_names[TRT_Count] = { "OuterRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersIdeal", "ColumnsContentRowsFrozen", "ColumnsContentRowsUnfrozen" };
// State // State
static bool show_windows_rects = false; static bool show_windows_rects = false;
@ -15658,7 +15664,6 @@ void ImGui::ShowMetricsWindow(bool* p_open)
} }
}; };
// Tools // Tools
if (ImGui::TreeNode("Tools")) if (ImGui::TreeNode("Tools"))
{ {
@ -15747,7 +15752,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Funcs::NodeTable(g.Tables.GetByIndex(n)); Funcs::NodeTable(g.Tables.GetByIndex(n));
ImGui::TreePop(); ImGui::TreePop();
} }
#endif // #define IMGUI_HAS_TABLE #endif // #ifdef IMGUI_HAS_TABLE
// Details for Docking // Details for Docking
#ifdef IMGUI_HAS_DOCK #ifdef IMGUI_HAS_DOCK
@ -15764,7 +15769,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Funcs::NodeDockNode(node, "Node"); Funcs::NodeDockNode(node, "Node");
ImGui::TreePop(); ImGui::TreePop();
} }
#endif // #define IMGUI_HAS_DOCK #endif // #ifdef IMGUI_HAS_DOCK
// Settings // Settings
if (ImGui::TreeNode("Settings")) if (ImGui::TreeNode("Settings"))
@ -15803,7 +15808,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Funcs::NodeTableSettings(settings); Funcs::NodeTableSettings(settings);
ImGui::TreePop(); ImGui::TreePop();
} }
#endif #endif // #ifdef IMGUI_HAS_TABLE
#ifdef IMGUI_HAS_DOCK #ifdef IMGUI_HAS_DOCK
if (ImGui::TreeNode("SettingsDocking", "Settings packed data: Docking")) if (ImGui::TreeNode("SettingsDocking", "Settings packed data: Docking"))
@ -15829,7 +15834,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
} }
ImGui::TreePop(); ImGui::TreePop();
} }
#endif #endif // #ifdef IMGUI_HAS_DOCK
if (ImGui::TreeNode("SettingsIniData", "Settings unpacked data (.ini): %d bytes", g.SettingsIniData.size())) if (ImGui::TreeNode("SettingsIniData", "Settings unpacked data (.ini): %d bytes", g.SettingsIniData.size()))
{ {
@ -15897,7 +15902,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGuiTable* table = g.Tables.GetByIndex(table_n); ImGuiTable* table = g.Tables.GetByIndex(table_n);
} }
} }
#endif // #define IMGUI_HAS_TABLE #endif // #ifdef IMGUI_HAS_TABLE
#ifdef IMGUI_HAS_DOCK #ifdef IMGUI_HAS_DOCK
// Overlay: Display Docking info // Overlay: Display Docking info
@ -15925,7 +15930,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
overlay_draw_list->AddText(NULL, 0.0f, pos, IM_COL32(255, 255, 255, 255), buf); overlay_draw_list->AddText(NULL, 0.0f, pos, IM_COL32(255, 255, 255, 255), buf);
} }
} }
#endif // #define IMGUI_HAS_DOCK #endif // #ifdef IMGUI_HAS_DOCK
ImGui::End(); ImGui::End();
} }

@ -1570,7 +1570,7 @@ struct ImGuiIO
//------------------------------------------------------------------ //------------------------------------------------------------------
ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.)
bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API.
float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text.
float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends.
ImGuiID MouseHoveredViewport; // (Optional) When using multiple viewports: viewport the OS mouse cursor is hovering _IGNORING_ viewports with the ImGuiViewportFlags_NoInputs flag, and _REGARDLESS_ of whether another viewport is focused. Set io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport if you can provide this info. If you don't imgui will infer the value using the rectangles and last focused time of the viewports it knows about (ignoring other OS windows). ImGuiID MouseHoveredViewport; // (Optional) When using multiple viewports: viewport the OS mouse cursor is hovering _IGNORING_ viewports with the ImGuiViewportFlags_NoInputs flag, and _REGARDLESS_ of whether another viewport is focused. Set io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport if you can provide this info. If you don't imgui will infer the value using the rectangles and last focused time of the viewports it knows about (ignoring other OS windows).

@ -633,13 +633,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
if (points_count < 2) if (points_count < 2)
return; return;
const ImVec2 uv = _Data->TexUvWhitePixel; const ImVec2 opaque_uv = _Data->TexUvWhitePixel;
int count = points_count; int count = points_count;
if (!closed) if (!closed)
count = points_count-1; count = points_count-1;
const bool thick_line = thickness > 1.0f; const bool thick_line = (thickness > 1.0f);
if (Flags & ImDrawListFlags_AntiAliasedLines) if (Flags & ImDrawListFlags_AntiAliasedLines)
{ {
// Anti-aliased stroke // Anti-aliased stroke
@ -710,9 +709,9 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
// Add vertices // Add vertices
for (int i = 0; i < points_count; i++) for (int i = 0; i < points_count; i++)
{ {
_VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col;
_VtxWritePtr[1].pos = temp_points[i*2+0]; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; _VtxWritePtr[1].pos = temp_points[i*2+0]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col_trans;
_VtxWritePtr[2].pos = temp_points[i*2+1]; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col_trans; _VtxWritePtr[2].pos = temp_points[i*2+1]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col_trans;
_VtxWritePtr += 3; _VtxWritePtr += 3;
} }
} }
@ -721,22 +720,23 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f;
if (!closed) if (!closed)
{ {
const int points_last = points_count - 1;
temp_points[0] = points[0] + temp_normals[0] * (half_inner_thickness + AA_SIZE); temp_points[0] = points[0] + temp_normals[0] * (half_inner_thickness + AA_SIZE);
temp_points[1] = points[0] + temp_normals[0] * (half_inner_thickness); temp_points[1] = points[0] + temp_normals[0] * (half_inner_thickness);
temp_points[2] = points[0] - temp_normals[0] * (half_inner_thickness); temp_points[2] = points[0] - temp_normals[0] * (half_inner_thickness);
temp_points[3] = points[0] - temp_normals[0] * (half_inner_thickness + AA_SIZE); temp_points[3] = points[0] - temp_normals[0] * (half_inner_thickness + AA_SIZE);
temp_points[(points_count-1)*4+0] = points[points_count-1] + temp_normals[points_count-1] * (half_inner_thickness + AA_SIZE); temp_points[points_last * 4 + 0] = points[points_last] + temp_normals[points_last] * (half_inner_thickness + AA_SIZE);
temp_points[(points_count-1)*4+1] = points[points_count-1] + temp_normals[points_count-1] * (half_inner_thickness); temp_points[points_last * 4 + 1] = points[points_last] + temp_normals[points_last] * (half_inner_thickness);
temp_points[(points_count-1)*4+2] = points[points_count-1] - temp_normals[points_count-1] * (half_inner_thickness); temp_points[points_last * 4 + 2] = points[points_last] - temp_normals[points_last] * (half_inner_thickness);
temp_points[(points_count-1)*4+3] = points[points_count-1] - temp_normals[points_count-1] * (half_inner_thickness + AA_SIZE); temp_points[points_last * 4 + 3] = points[points_last] - temp_normals[points_last] * (half_inner_thickness + AA_SIZE);
} }
// FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer.
unsigned int idx1 = _VtxCurrentIdx; unsigned int idx1 = _VtxCurrentIdx;
for (int i1 = 0; i1 < count; i1++) for (int i1 = 0; i1 < count; i1++)
{ {
const int i2 = (i1+1) == points_count ? 0 : i1+1; const int i2 = (i1 + 1) == points_count ? 0 : (i1 + 1); // i2 is the second point of the line segment
unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+4; const unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : (idx1 + 4); // Vertex index for end of segment
// Average normals // Average normals
float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f; float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f;
@ -759,12 +759,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
out_vtx[3].y = points[i2].y - dm_out_y; out_vtx[3].y = points[i2].y - dm_out_y;
// Add indexes // Add indexes
_IdxWritePtr[0] = (ImDrawIdx)(idx2+1); _IdxWritePtr[1] = (ImDrawIdx)(idx1+1); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2); _IdxWritePtr[0] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 2);
_IdxWritePtr[3] = (ImDrawIdx)(idx1+2); _IdxWritePtr[4] = (ImDrawIdx)(idx2+2); _IdxWritePtr[5] = (ImDrawIdx)(idx2+1); _IdxWritePtr[3] = (ImDrawIdx)(idx1 + 2); _IdxWritePtr[4] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 1);
_IdxWritePtr[6] = (ImDrawIdx)(idx2+1); _IdxWritePtr[7] = (ImDrawIdx)(idx1+1); _IdxWritePtr[8] = (ImDrawIdx)(idx1+0); _IdxWritePtr[6] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[7] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[8] = (ImDrawIdx)(idx1 + 0);
_IdxWritePtr[9] = (ImDrawIdx)(idx1+0); _IdxWritePtr[10] = (ImDrawIdx)(idx2+0); _IdxWritePtr[11] = (ImDrawIdx)(idx2+1); _IdxWritePtr[9] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[10] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[11] = (ImDrawIdx)(idx2 + 1);
_IdxWritePtr[12] = (ImDrawIdx)(idx2+2); _IdxWritePtr[13] = (ImDrawIdx)(idx1+2); _IdxWritePtr[14] = (ImDrawIdx)(idx1+3); _IdxWritePtr[12] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr[13] = (ImDrawIdx)(idx1 + 2); _IdxWritePtr[14] = (ImDrawIdx)(idx1 + 3);
_IdxWritePtr[15] = (ImDrawIdx)(idx1+3); _IdxWritePtr[16] = (ImDrawIdx)(idx2+3); _IdxWritePtr[17] = (ImDrawIdx)(idx2+2); _IdxWritePtr[15] = (ImDrawIdx)(idx1 + 3); _IdxWritePtr[16] = (ImDrawIdx)(idx2 + 3); _IdxWritePtr[17] = (ImDrawIdx)(idx2 + 2);
_IdxWritePtr += 18; _IdxWritePtr += 18;
idx1 = idx2; idx1 = idx2;
@ -773,10 +773,10 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
// Add vertices // Add vertices
for (int i = 0; i < points_count; i++) for (int i = 0; i < points_count; i++)
{ {
_VtxWritePtr[0].pos = temp_points[i*4+0]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col_trans; _VtxWritePtr[0].pos = temp_points[i * 4 + 0]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col_trans;
_VtxWritePtr[1].pos = temp_points[i*4+1]; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; _VtxWritePtr[1].pos = temp_points[i * 4 + 1]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col;
_VtxWritePtr[2].pos = temp_points[i*4+2]; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; _VtxWritePtr[2].pos = temp_points[i * 4 + 2]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col;
_VtxWritePtr[3].pos = temp_points[i*4+3]; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col_trans; _VtxWritePtr[3].pos = temp_points[i * 4 + 3]; _VtxWritePtr[3].uv = opaque_uv; _VtxWritePtr[3].col = col_trans;
_VtxWritePtr += 4; _VtxWritePtr += 4;
} }
} }
@ -801,14 +801,14 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
dx *= (thickness * 0.5f); dx *= (thickness * 0.5f);
dy *= (thickness * 0.5f); dy *= (thickness * 0.5f);
_VtxWritePtr[0].pos.x = p1.x + dy; _VtxWritePtr[0].pos.y = p1.y - dx; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; _VtxWritePtr[0].pos.x = p1.x + dy; _VtxWritePtr[0].pos.y = p1.y - dx; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col;
_VtxWritePtr[1].pos.x = p2.x + dy; _VtxWritePtr[1].pos.y = p2.y - dx; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; _VtxWritePtr[1].pos.x = p2.x + dy; _VtxWritePtr[1].pos.y = p2.y - dx; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col;
_VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; _VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col;
_VtxWritePtr[3].pos.x = p1.x - dy; _VtxWritePtr[3].pos.y = p1.y + dx; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col; _VtxWritePtr[3].pos.x = p1.x - dy; _VtxWritePtr[3].pos.y = p1.y + dx; _VtxWritePtr[3].uv = opaque_uv; _VtxWritePtr[3].col = col;
_VtxWritePtr += 4; _VtxWritePtr += 4;
_IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+2); _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + 1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + 2);
_IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx+2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx+3); _IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx + 2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx + 3);
_IdxWritePtr += 6; _IdxWritePtr += 6;
_VtxCurrentIdx += 4; _VtxCurrentIdx += 4;
} }

Loading…
Cancel
Save