From d16c87a5b19e82b922e7a400b897f83d62c8715c Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 10 Feb 2020 16:44:28 +0100 Subject: [PATCH 01/16] Internals: Minor renaming --- imgui_draw.cpp | 5 +++-- imgui_internal.h | 2 +- misc/freetype/imgui_freetype.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 4bb91ccf..5c9d2c6a 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1942,7 +1942,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) { IM_ASSERT(atlas->ConfigData.Size > 0); - ImFontAtlasBuildRegisterDefaultCustomRects(atlas); + ImFontAtlasBuildInit(atlas); // Clear atlas atlas->TexID = (ImTextureID)NULL; @@ -2194,7 +2194,8 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) return true; } -void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas) +// Register default custom rectangles (this is called/shared by both the stb_truetype and the FreeType builder) +void ImFontAtlasBuildInit(ImFontAtlas* atlas) { if (atlas->CustomRectIds[0] >= 0) return; diff --git a/imgui_internal.h b/imgui_internal.h index 5de13c36..8c1de54e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1868,7 +1868,7 @@ namespace ImGui // ImFontAtlas internals IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas); -IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque); IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas); diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index 6695fb65..fb2b399d 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -317,7 +317,7 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns { IM_ASSERT(atlas->ConfigData.Size > 0); - ImFontAtlasBuildRegisterDefaultCustomRects(atlas); + ImFontAtlasBuildInit(atlas); // Clear atlas atlas->TexID = (ImTextureID)NULL; From f346b4b3021a83ea920dbf4348b2aa208c9bb0b9 Mon Sep 17 00:00:00 2001 From: coding_jackalope Date: Fri, 7 Feb 2020 12:48:59 -0800 Subject: [PATCH 02/16] Examples: SDL+Metal example. --- examples/example_sdl_metal/Makefile | 46 +++++++ examples/example_sdl_metal/main.mm | 190 ++++++++++++++++++++++++++++ examples/imgui_impl_sdl.cpp | 33 +++++ examples/imgui_impl_sdl.h | 2 + 4 files changed, 271 insertions(+) create mode 100644 examples/example_sdl_metal/Makefile create mode 100644 examples/example_sdl_metal/main.mm diff --git a/examples/example_sdl_metal/Makefile b/examples/example_sdl_metal/Makefile new file mode 100644 index 00000000..9d0d5e0f --- /dev/null +++ b/examples/example_sdl_metal/Makefile @@ -0,0 +1,46 @@ +# +# You will need SDL2 (http://www.libsdl.org): +# brew install sdl2 +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_sdl_metal +SOURCES = main.mm +SOURCES += ../imgui_impl_sdl.cpp ../imgui_impl_metal.mm +SOURCES += ../../imgui.cpp ../../imgui_widgets.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) + +LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore +LIBS += `sdl2-config --libs` +LIBS += -L/usr/local/lib + +CXXFLAGS = -I../ -I../../ -I/usr/local/include +CXXFLAGS += `sdl2-config --cflags` +CXXFLAGS += -Wall -Wformat +CFLAGS = $(CXXFLAGS) + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:../%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:../../%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:../%.mm + $(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $< + +%.o:%.mm + $(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $< + +all: $(EXE) + @echo Build complete + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/examples/example_sdl_metal/main.mm b/examples/example_sdl_metal/main.mm new file mode 100644 index 00000000..7801ca14 --- /dev/null +++ b/examples/example_sdl_metal/main.mm @@ -0,0 +1,190 @@ +// ImGui - standalone example application for GLFW + Metal, using programmable pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include "imgui.h" +#include "imgui_impl_sdl.h" +#include "imgui_impl_metal.h" + +#include "SDL.h" + +#import +#import + +#include + +int main(int, char**) +{ + // Setup Dear ImGui binding + 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 style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'docs/FONTS.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + // Setup SDL + // (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems, + // depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to latest version of SDL is recommended!) + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + SDL_Window* window = SDL_CreateWindow( + "Dear ImGui SDL+Metal example", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + 1280, + 720, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI + ); + + if (window == NULL) + { + printf("Error creating window: %s\n", SDL_GetError()); + return -2; + } + + SDL_Renderer* renderer = SDL_CreateRenderer( + window, + -1, + SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC + ); + + if (renderer == NULL) + { + printf("Error creating renderer: %s\n", SDL_GetError()); + return -3; + } + + CAMetalLayer* layer = (__bridge CAMetalLayer*)SDL_RenderGetMetalLayer(renderer); + layer.pixelFormat = MTLPixelFormatBGRA8Unorm; + ImGui_ImplMetal_Init(layer.device); + ImGui_ImplSDL2_InitForMetal(window); + + id commandQueue = [layer.device newCommandQueue]; + MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor new]; + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + float clear_color[4] = {0.45f, 0.55f, 0.60f, 1.00f}; + + // Main loop + bool done = false; + while (!done) + { + @autoreleasepool + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL2_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) + done = true; + } + + int width, height; + SDL_GetRendererOutputSize(renderer, &width, &height); + layer.drawableSize = CGSizeMake(width, height); + id drawable = [layer nextDrawable]; + + id commandBuffer = [commandQueue commandBuffer]; + renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0], clear_color[1], clear_color[2], clear_color[3]); + renderPassDescriptor.colorAttachments[0].texture = drawable.texture; + renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; + renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + id renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + [renderEncoder pushDebugGroup:@"ImGui demo"]; + + // Start the Dear ImGui frame + ImGui_ImplMetal_NewFrame(renderPassDescriptor); + ImGui_ImplSDL2_NewFrame_Metal(window); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder); + + [renderEncoder popDebugGroup]; + [renderEncoder endEncoding]; + + [commandBuffer presentDrawable:drawable]; + [commandBuffer commit]; + } + } + + // Cleanup + ImGui_ImplMetal_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/examples/imgui_impl_sdl.cpp b/examples/imgui_impl_sdl.cpp index 32722bf6..aac3b82c 100644 --- a/examples/imgui_impl_sdl.cpp +++ b/examples/imgui_impl_sdl.cpp @@ -212,6 +212,11 @@ bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window) return ImGui_ImplSDL2_Init(window); } +bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window) +{ + return ImGui_ImplSDL2_Init(window); +} + void ImGui_ImplSDL2_Shutdown() { g_Window = NULL; @@ -359,3 +364,31 @@ void ImGui_ImplSDL2_NewFrame(SDL_Window* window) // Update game controllers (if enabled and available) ImGui_ImplSDL2_UpdateGamepads(); } + +void ImGui_ImplSDL2_NewFrame_Metal(SDL_Window* window) +{ + ImGuiIO& io = ImGui::GetIO(); + IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplMetal_NewFrame()."); + + // Setup display size (every frame to accommodate for window resizing) + SDL_Renderer* renderer = SDL_GetRenderer(window); + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GetRendererOutputSize(renderer, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + if (w > 0 && h > 0) + io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); + + // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) + static Uint64 frequency = SDL_GetPerformanceFrequency(); + Uint64 current_time = SDL_GetPerformanceCounter(); + io.DeltaTime = g_Time > 0 ? (float)((double)(current_time - g_Time) / frequency) : (float)(1.0f / 60.0f); + g_Time = current_time; + + ImGui_ImplSDL2_UpdateMousePosAndButtons(); + ImGui_ImplSDL2_UpdateMouseCursor(); + + // Update game controllers (if enabled and available) + ImGui_ImplSDL2_UpdateGamepads(); +} diff --git a/examples/imgui_impl_sdl.h b/examples/imgui_impl_sdl.h index 376e622c..42da71ed 100644 --- a/examples/imgui_impl_sdl.h +++ b/examples/imgui_impl_sdl.h @@ -22,6 +22,8 @@ typedef union SDL_Event SDL_Event; IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context); IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window); IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown(); IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame(SDL_Window* window); +IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame_Metal(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event); From 21b9e42964cfaa44b949b701fea37f2e6012e319 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Mon, 10 Feb 2020 16:13:29 +0200 Subject: [PATCH 03/16] Minor fixes to example_sdl_metal and a changelog entry. Add example_sdl_metal to CI builds. Closes #3017. --- .github/workflows/build.yml | 3 +++ docs/CHANGELOG.txt | 9 +++++++ examples/README.txt | 6 ++++- examples/example_glfw_metal/main.mm | 8 +++---- examples/example_glfw_opengl2/main.cpp | 2 +- examples/example_glfw_opengl3/main.cpp | 2 +- examples/example_sdl_directx11/main.cpp | 2 +- examples/example_sdl_metal/main.mm | 31 ++++++++----------------- examples/example_sdl_opengl2/main.cpp | 2 +- examples/example_sdl_opengl3/main.cpp | 2 +- examples/imgui_impl_sdl.cpp | 28 ---------------------- examples/imgui_impl_sdl.h | 3 +-- 12 files changed, 37 insertions(+), 61 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a874bfff..ff83bd3d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -241,6 +241,9 @@ jobs: - name: Build example_glfw_metal run: make -C examples/example_glfw_metal + - name: Build example_sdl_metal + run: make -C examples/example_sdl_metal + - name: Build example_sdl_opengl2 run: make -C examples/example_sdl_opengl2 if: github.event_name == 'schedule' diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 736cb447..66c5160a 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -30,6 +30,15 @@ HOW TO UPDATE? - Please report any issue! +----------------------------------------------------------------------- + VERSION 1.76 WIP (In Progress) +----------------------------------------------------------------------- + +Other Changes: + +- Backends: Added SDL2+Metal example application. (#3017) [@coding-jackalope] + + ----------------------------------------------------------------------- VERSION 1.75 (Released 2020-02-10) ----------------------------------------------------------------------- diff --git a/examples/README.txt b/examples/README.txt index 5bd16be4..5d07a210 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -190,7 +190,7 @@ example_empscripten: example_glfw_metal/ GLFW (Mac) + Metal example. - = main.mm + imgui_impl_glfw.cpp + imgui_impl_metal.mm. + = main.mm + imgui_impl_glfw.cpp + imgui_impl_metal.mm example_glfw_opengl2/ GLFW + OpenGL2 example (legacy, fixed pipeline). @@ -237,6 +237,10 @@ example_sdl_directx11/ = main.cpp + imgui_impl_sdl.cpp + imgui_impl_dx11.cpp This to demonstrate usage of DirectX with SDL. +example_sdl_metal/ + SDL2 (Mac) + Metal example. + = main.mm + imgui_impl_sdl.cpp + imgui_impl_metal.mm + example_sdl_opengl2/ SDL2 (Win32, Mac, Linux etc.) + OpenGL example (legacy, fixed pipeline). = main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl2.cpp diff --git a/examples/example_glfw_metal/main.mm b/examples/example_glfw_metal/main.mm index 45dbb37b..d6f9ae3f 100644 --- a/examples/example_glfw_metal/main.mm +++ b/examples/example_glfw_metal/main.mm @@ -1,9 +1,11 @@ -// ImGui - standalone example application for GLFW + Metal, using programmable pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// dear imgui: standalone example application for GLFW + Metal, using programmable pipeline +// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_metal.h" +#include #define GLFW_INCLUDE_NONE #define GLFW_EXPOSE_NATIVE_COCOA @@ -13,8 +15,6 @@ #import #import -#include - static void glfw_error_callback(int error, const char* description) { fprintf(stderr, "Glfw Error %d: %s\n", error, description); diff --git a/examples/example_glfw_opengl2/main.cpp b/examples/example_glfw_opengl2/main.cpp index 5630b6c3..a50b4637 100644 --- a/examples/example_glfw_opengl2/main.cpp +++ b/examples/example_glfw_opengl2/main.cpp @@ -1,6 +1,6 @@ // dear imgui: standalone example application for GLFW + OpenGL2, using legacy fixed pipeline // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. -// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** // **Prefer using the code in the example_glfw_opengl2/ folder** diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp index ef7ddfed..55b379de 100644 --- a/examples/example_glfw_opengl3/main.cpp +++ b/examples/example_glfw_opengl3/main.cpp @@ -1,6 +1,6 @@ // dear imgui: standalone example application for GLFW + OpenGL 3, using programmable pipeline // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. -// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) #include "imgui.h" #include "imgui_impl_glfw.h" diff --git a/examples/example_sdl_directx11/main.cpp b/examples/example_sdl_directx11/main.cpp index 812b40f4..0a97325d 100644 --- a/examples/example_sdl_directx11/main.cpp +++ b/examples/example_sdl_directx11/main.cpp @@ -1,6 +1,6 @@ // dear imgui: standalone example application for SDL2 + DirectX 11 // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. -// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) #include "imgui.h" #include "imgui_impl_sdl.h" diff --git a/examples/example_sdl_metal/main.mm b/examples/example_sdl_metal/main.mm index 7801ca14..3cb1ea4d 100644 --- a/examples/example_sdl_metal/main.mm +++ b/examples/example_sdl_metal/main.mm @@ -1,17 +1,16 @@ -// ImGui - standalone example application for GLFW + Metal, using programmable pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// Dear ImGui: standalone example application for SDL2 + Metal +// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) #include "imgui.h" #include "imgui_impl_sdl.h" #include "imgui_impl_metal.h" - -#include "SDL.h" +#include +#include #import #import -#include - int main(int, char**) { // Setup Dear ImGui binding @@ -49,27 +48,17 @@ int main(int, char**) return -1; } - SDL_Window* window = SDL_CreateWindow( - "Dear ImGui SDL+Metal example", - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - 1280, - 720, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI - ); + // Inform SDL that we will be using metal for rendering. Without this hint initialization of metal renderer may fail. + SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal"); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL+Metal example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); if (window == NULL) { printf("Error creating window: %s\n", SDL_GetError()); return -2; } - SDL_Renderer* renderer = SDL_CreateRenderer( - window, - -1, - SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC - ); - + SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (renderer == NULL) { printf("Error creating renderer: %s\n", SDL_GetError()); @@ -125,7 +114,7 @@ int main(int, char**) // Start the Dear ImGui frame ImGui_ImplMetal_NewFrame(renderPassDescriptor); - ImGui_ImplSDL2_NewFrame_Metal(window); + ImGui_ImplSDL2_NewFrame(window); ImGui::NewFrame(); // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). diff --git a/examples/example_sdl_opengl2/main.cpp b/examples/example_sdl_opengl2/main.cpp index b55cb22f..ff54ec41 100644 --- a/examples/example_sdl_opengl2/main.cpp +++ b/examples/example_sdl_opengl2/main.cpp @@ -1,6 +1,6 @@ // dear imgui: standalone example application for SDL2 + OpenGL // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. -// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** // **Prefer using the code in the example_sdl_opengl3/ folder** diff --git a/examples/example_sdl_opengl3/main.cpp b/examples/example_sdl_opengl3/main.cpp index a0cfe240..20801a19 100644 --- a/examples/example_sdl_opengl3/main.cpp +++ b/examples/example_sdl_opengl3/main.cpp @@ -1,6 +1,6 @@ // dear imgui: standalone example application for SDL2 + OpenGL // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. -// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) // (GL3W is a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc.) #include "imgui.h" diff --git a/examples/imgui_impl_sdl.cpp b/examples/imgui_impl_sdl.cpp index aac3b82c..69172622 100644 --- a/examples/imgui_impl_sdl.cpp +++ b/examples/imgui_impl_sdl.cpp @@ -364,31 +364,3 @@ void ImGui_ImplSDL2_NewFrame(SDL_Window* window) // Update game controllers (if enabled and available) ImGui_ImplSDL2_UpdateGamepads(); } - -void ImGui_ImplSDL2_NewFrame_Metal(SDL_Window* window) -{ - ImGuiIO& io = ImGui::GetIO(); - IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplMetal_NewFrame()."); - - // Setup display size (every frame to accommodate for window resizing) - SDL_Renderer* renderer = SDL_GetRenderer(window); - int w, h; - int display_w, display_h; - SDL_GetWindowSize(window, &w, &h); - SDL_GetRendererOutputSize(renderer, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - if (w > 0 && h > 0) - io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); - - // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) - static Uint64 frequency = SDL_GetPerformanceFrequency(); - Uint64 current_time = SDL_GetPerformanceCounter(); - io.DeltaTime = g_Time > 0 ? (float)((double)(current_time - g_Time) / frequency) : (float)(1.0f / 60.0f); - g_Time = current_time; - - ImGui_ImplSDL2_UpdateMousePosAndButtons(); - ImGui_ImplSDL2_UpdateMouseCursor(); - - // Update game controllers (if enabled and available) - ImGui_ImplSDL2_UpdateGamepads(); -} diff --git a/examples/imgui_impl_sdl.h b/examples/imgui_impl_sdl.h index 42da71ed..a672ca83 100644 --- a/examples/imgui_impl_sdl.h +++ b/examples/imgui_impl_sdl.h @@ -22,8 +22,7 @@ typedef union SDL_Event SDL_Event; IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context); IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window); -IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window); +IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window); IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown(); IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame(SDL_Window* window); -IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame_Metal(SDL_Window* window); IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event); From d8948b5343fb0102fcea304969a8ba5063362728 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 10 Feb 2020 21:23:34 +0100 Subject: [PATCH 04/16] ColorButton: Added ImGuiColorEditFlags_NoBorder flag to remove the border normally enforced by default. --- docs/CHANGELOG.txt | 2 ++ imgui.h | 3 ++- imgui_demo.cpp | 4 +++- imgui_widgets.cpp | 19 +++++++++++++------ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 66c5160a..d071c7de 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -36,6 +36,8 @@ HOW TO UPDATE? Other Changes: +- ColorButton: Added ImGuiColorEditFlags_NoBorder flag to remove the border normally enforced + by default for standalone ColorButton. - Backends: Added SDL2+Metal example application. (#3017) [@coding-jackalope] diff --git a/imgui.h b/imgui.h index c2bbb7f7..a7b191ee 100644 --- a/imgui.h +++ b/imgui.h @@ -60,7 +60,7 @@ Index of this file: // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) #define IMGUI_VERSION "1.75" -#define IMGUI_VERSION_NUM 17500 +#define IMGUI_VERSION_NUM 17501 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) // Define attributes of all API symbols declarations (e.g. for DLL under Windows) @@ -1158,6 +1158,7 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_NoLabel = 1 << 7, // // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source. + ImGuiColorEditFlags_NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default) // User Options (right-click on widget to change some of them). ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7664f1b4..32579d19 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1264,7 +1264,9 @@ static void ShowDemoWindowWidgets() } ImGui::Text("Color button only:"); - ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags, ImVec2(80,80)); + static bool no_border = false; + ImGui::Checkbox("ImGuiColorEditFlags_NoBorder", &no_border); + ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80,80)); ImGui::Text("Color picker:"); static bool alpha = true; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 6d2c95d9..a892b15a 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4956,8 +4956,12 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl float grid_step = ImMin(size.x, size.y) / 2.99f; float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); ImRect bb_inner = bb; - float off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts. - bb_inner.Expand(off); + float off = 0.0f; + if ((flags & ImGuiColorEditFlags_NoBorder) == 0) + { + off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts. + bb_inner.Expand(off); + } if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f) { float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f); @@ -4974,10 +4978,13 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ImDrawCornerFlags_All); } RenderNavHighlight(bb, id); - if (g.Style.FrameBorderSize > 0.0f) - RenderFrameBorder(bb.Min, bb.Max, rounding); - else - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border + if ((flags & ImGuiColorEditFlags_NoBorder) == 0) + { + if (g.Style.FrameBorderSize > 0.0f) + RenderFrameBorder(bb.Min, bb.Max, rounding); + else + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border + } // Drag and Drop Source // NB: The ActiveId test is merely an optional micro-optimization, BeginDragDropSource() does the same test. From 70975fe44d22dc758c5b6ba430107ee2b4a16b74 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 10 Feb 2020 22:08:52 +0100 Subject: [PATCH 05/16] Demo: Added a black and white gradient to Demo>Examples>Custom Rendering. --- docs/CHANGELOG.txt | 5 ++++- imgui_demo.cpp | 22 +++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d071c7de..b96c0d66 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -38,7 +38,10 @@ Other Changes: - ColorButton: Added ImGuiColorEditFlags_NoBorder flag to remove the border normally enforced by default for standalone ColorButton. -- Backends: Added SDL2+Metal example application. (#3017) [@coding-jackalope] +- Demo: Added a black and white gradient to Demo>Examples>Custom Rendering. +- Backends: SDL: Added ImGui_ImplSDL2_InitForMetal() for API consistency (even though the function + currently does nothing). +- Examples: Added SDL2+Metal example application. (#3017) [@coding-jackalope] ----------------------------------------------------------------------- diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 32579d19..2a1676d6 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -4471,7 +4471,6 @@ static void ShowExampleAppCustomRendering(bool* p_open) if (ImGui::SliderInt("Circle segments", &circle_segments_override_v, 3, 40)) circle_segments_override = true; ImGui::ColorEdit4("Color", &colf.x); - ImGui::PopItemWidth(); const ImVec2 p = ImGui::GetCursorScreenPos(); const ImU32 col = ImColor(colf); const float spacing = 10.0f; @@ -4510,6 +4509,27 @@ static void ShowExampleAppCustomRendering(bool* p_open) draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine) draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255)); ImGui::Dummy(ImVec2((sz + spacing) * 9.8f, (sz + spacing) * 3)); + + // Draw black and white gradients + static int gradient_steps = 16; + ImGui::Separator(); + ImGui::AlignTextToFramePadding(); + ImGui::Text("Gradient steps"); + ImGui::SameLine(); if (ImGui::RadioButton("16", gradient_steps == 16)) { gradient_steps = 16; } + ImGui::SameLine(); if (ImGui::RadioButton("32", gradient_steps == 32)) { gradient_steps = 32; } + ImGui::SameLine(); if (ImGui::RadioButton("256", gradient_steps == 256)) { gradient_steps = 256; } + ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), 64.0f); + x = ImGui::GetCursorScreenPos().x; + y = ImGui::GetCursorScreenPos().y; + for (int n = 0; n < gradient_steps; n++) + { + float f = n / (float)gradient_steps; + ImU32 col32 = ImGui::GetColorU32(ImVec4(f, f, f, 1.0f)); + draw_list->AddRectFilled(ImVec2(x + gradient_size.x * (n / (float)gradient_steps), y), ImVec2(x + gradient_size.x * ((n+1) / (float)gradient_steps), y + gradient_size.y), col32); + } + ImGui::InvisibleButton("##gradient", gradient_size); + + ImGui::PopItemWidth(); ImGui::EndTabItem(); } From 30bb15672d158864aa19914a0dc5f64c27358d14 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 10 Feb 2020 23:22:03 +0100 Subject: [PATCH 06/16] Remove trailing spaces --- imconfig.h | 6 +++--- imgui.cpp | 2 +- imgui.h | 4 ++-- imgui_internal.h | 6 +++--- imgui_widgets.cpp | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/imconfig.h b/imconfig.h index 09bfd16c..4f629795 100644 --- a/imconfig.h +++ b/imconfig.h @@ -26,10 +26,10 @@ //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS -//---- Disable all of Dear ImGui or don't implement standard windows. +//---- Disable all of Dear ImGui or don't implement standard windows. // It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp. -//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. -//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. +//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. +//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. //#define IMGUI_DISABLE_METRICS_WINDOW // Disable debug/metrics window: ShowMetricsWindow() will be empty. //---- Don't implement some functions to reduce linkage requirements. diff --git a/imgui.cpp b/imgui.cpp index 1b78dd83..a5dd85a3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4159,7 +4159,7 @@ void ImGui::Render() g.FrameCountRendered = g.FrameCount; g.IO.MetricsRenderWindows = 0; g.DrawDataBuilder.Clear(); - + // Add background ImDrawList if (!g.BackgroundDrawList.VtxBuffer.empty()) AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.BackgroundDrawList); diff --git a/imgui.h b/imgui.h index a7b191ee..60bd9395 100644 --- a/imgui.h +++ b/imgui.h @@ -1944,8 +1944,8 @@ struct ImDrawList // Primitives // - For rectangular primitives, "p_min" and "p_max" represent the upper-left and lower-right corners. - // - For circle primitives, use "num_segments == 0" to automatically calculate tessellation (preferred). - // In future versions we will use textures to provide cheaper and higher-quality circles. + // - For circle primitives, use "num_segments == 0" to automatically calculate tessellation (preferred). + // In future versions we will use textures to provide cheaper and higher-quality circles. // Use AddNgon() and AddNgonFilled() functions if you need to guaranteed a specific number of sides. IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f); IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size), rounding_corners_flags: 4 bits corresponding to which corner to round diff --git a/imgui_internal.h b/imgui_internal.h index 8c1de54e..a5cbb05c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -431,10 +431,10 @@ enum ImGuiButtonFlags_ ImGuiButtonFlags_NoHoldingActiveId = 1 << 13, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) ImGuiButtonFlags_NoNavFocus = 1 << 14, // don't override navigation focus when activated ImGuiButtonFlags_NoHoveredOnNav = 1 << 15, // don't report as hovered when navigated on - ImGuiButtonFlags_MouseButtonLeft = 1 << 16, // [Default] react on left mouse button + ImGuiButtonFlags_MouseButtonLeft = 1 << 16, // [Default] react on left mouse button ImGuiButtonFlags_MouseButtonRight = 1 << 17, // react on right mouse button ImGuiButtonFlags_MouseButtonMiddle = 1 << 18, // react on center mouse button - + ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, ImGuiButtonFlags_MouseButtonShift_ = 16, ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft, @@ -1642,7 +1642,7 @@ namespace ImGui IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window); IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window); IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window); - + // Fonts, drawing IMGUI_API void SetCurrentFont(ImFont* font); inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a892b15a..de403718 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3273,8 +3273,8 @@ static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const Im #define STB_TEXTEDIT_IMPLEMENTATION #include "imstb_textedit.h" -// stb_textedit internally allows for a single undo record to do addition and deletion, but somehow, calling -// the stb_textedit_paste() function creates two separate records, so we perform it manually. (FIXME: Report to nothings/stb?) +// stb_textedit internally allows for a single undo record to do addition and deletion, but somehow, calling +// the stb_textedit_paste() function creates two separate records, so we perform it manually. (FIXME: Report to nothings/stb?) static void stb_textedit_replace(STB_TEXTEDIT_STRING* str, STB_TexteditState* state, const STB_TEXTEDIT_CHARTYPE* text, int text_len) { stb_text_makeundo_replace(str, state, 0, str->CurLenW, text_len); @@ -3859,7 +3859,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } // When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer before clearing ActiveId, even though strictly speaking it wasn't modified on this frame. - // If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail. + // If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail. // This also allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage (please note that if you use this property along ImGuiInputTextFlags_CallbackResize you can end up with your temporary string object unnecessarily allocating once a frame, either store your string data, either if you don't then don't use ImGuiInputTextFlags_CallbackResize). bool apply_edit_back_to_user_buffer = !cancel_edit || (enter_pressed && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0); if (apply_edit_back_to_user_buffer) From ccaec1a270970ee550bc7586468ffbe7ebcb71ac Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 11 Feb 2020 16:56:56 +0100 Subject: [PATCH 07/16] Version 1.76 WIP --- examples/README.txt | 2 +- imgui.cpp | 2 +- imgui.h | 6 +++--- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_widgets.cpp | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/README.txt b/examples/README.txt index 5d07a210..146d79ee 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -1,5 +1,5 @@ ----------------------------------------------------------------------- - dear imgui, v1.75 + dear imgui, v1.76 WIP ----------------------------------------------------------------------- examples/README.txt (This is the README file for the examples/ folder. See docs/ for more documentation) diff --git a/imgui.cpp b/imgui.cpp index a5dd85a3..53b05aa4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.75 +// dear imgui, v1.76 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index 60bd9395..ac2b4c69 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.75 +// dear imgui, v1.76 WIP // (headers) // Help: @@ -59,8 +59,8 @@ Index of this file: // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) -#define IMGUI_VERSION "1.75" -#define IMGUI_VERSION_NUM 17501 +#define IMGUI_VERSION "1.76 WIP" +#define IMGUI_VERSION_NUM 17502 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) // Define attributes of all API symbols declarations (e.g. for DLL under Windows) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 2a1676d6..737d9c3c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.75 +// dear imgui, v1.76 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 5c9d2c6a..ab45bbb7 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.75 +// dear imgui, v1.76 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index a5cbb05c..450318da 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.75 +// dear imgui, v1.76 WIP // (internal structures/api) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index de403718..ef154760 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.75 +// dear imgui, v1.76 WIP // (widgets code) /* From d284a6cffc6d86edf9281b7acf869fc85c034702 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 11 Feb 2020 18:53:57 +0100 Subject: [PATCH 08/16] InputText: Fixed password fields displaying ASCII spaces as blanks. Fixed non-ASCII space occasionally creating unnecessary empty polygons. (#2149, #515) --- docs/CHANGELOG.txt | 3 + imgui.h | 6 +- imgui_demo.cpp | 9 +-- imgui_draw.cpp | 144 ++++++++++++++++++++++++--------------------- 4 files changed, 89 insertions(+), 73 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index b96c0d66..4216ab50 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -38,6 +38,9 @@ Other Changes: - ColorButton: Added ImGuiColorEditFlags_NoBorder flag to remove the border normally enforced by default for standalone ColorButton. +- InputText: Fixed password fields displaying ASCII spaces as blanks instead of using the '*' + glyph. (#2149, #515) +- Font: Fixed non-ASCII space occasionally creating unnecessary empty polygons. - Demo: Added a black and white gradient to Demo>Examples>Custom Rendering. - Backends: SDL: Added ImGui_ImplSDL2_InitForMetal() for API consistency (even though the function currently does nothing). diff --git a/imgui.h b/imgui.h index ac2b4c69..7dfc891a 100644 --- a/imgui.h +++ b/imgui.h @@ -2068,9 +2068,12 @@ struct ImFontConfig IMGUI_API ImFontConfig(); }; +// Hold rendering data for one glyph. +// (Note: some language parsers may fail to convert the 31+1 bitfield members, in this case maybe drop store a single u32 or we can rework this) struct ImFontGlyph { - ImWchar Codepoint; // 0x0000..0xFFFF + unsigned int Codepoint : 31; // 0x0000..0xFFFF + unsigned int Visible : 1; // Flag to allow early out when rendering float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) float X0, Y0, X1, Y1; // Glyph corners float U0, V0, U1, V1; // Texture coordinates @@ -2265,6 +2268,7 @@ struct ImFont IMGUI_API void GrowIndex(int new_size); IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. + IMGUI_API void SetGlyphVisible(ImWchar c, bool visible); IMGUI_API void SetFallbackChar(ImWchar c); }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 737d9c3c..c5f845de 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1040,11 +1040,11 @@ static void ShowDemoWindowWidgets() static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); ImGui::Text("Password input"); - static char bufpass[64] = "password123"; - ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); + static char password[64] = "password123"; + ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); - ImGui::InputTextWithHint("password (w/ hint)", "", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); - ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank); + ImGui::InputTextWithHint("password (w/ hint)", "", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); + ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_CharsNoBlank); ImGui::TreePop(); } @@ -3465,6 +3465,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::BeginTooltip(); ImGui::Text("Codepoint: U+%04X", base + n); ImGui::Separator(); + ImGui::Text("Visible: %d", glyph->Visible); ImGui::Text("AdvanceX: %.1f", glyph->AdvanceX); ImGui::Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1); ImGui::Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index ab45bbb7..b34358d6 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2622,6 +2622,7 @@ void ImFont::BuildLookupTable() for (int i = 0; i != Glyphs.Size; i++) max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); + // Build lookup table IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved IndexAdvanceX.clear(); IndexLookup.clear(); @@ -2638,7 +2639,7 @@ void ImFont::BuildLookupTable() // FIXME: Needs proper TAB handling but it needs to be contextualized (or we could arbitrary say that each string starts at "column 0" ?) if (FindGlyph((ImWchar)' ')) { - if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times + if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times (FIXME: Flaky) Glyphs.resize(Glyphs.Size + 1); ImFontGlyph& tab_glyph = Glyphs.back(); tab_glyph = *FindGlyph((ImWchar)' '); @@ -2648,6 +2649,11 @@ void ImFont::BuildLookupTable() IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size-1); } + // Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons) + SetGlyphVisible((ImWchar)' ', false); + SetGlyphVisible((ImWchar)'\t', false); + + // Setup fall-backs FallbackGlyph = FindGlyphNoFallback(FallbackChar); FallbackAdvanceX = FallbackGlyph ? FallbackGlyph->AdvanceX : 0.0f; for (int i = 0; i < max_codepoint + 1; i++) @@ -2655,6 +2661,12 @@ void ImFont::BuildLookupTable() IndexAdvanceX[i] = FallbackAdvanceX; } +void ImFont::SetGlyphVisible(ImWchar c, bool visible) +{ + if (ImFontGlyph* glyph = (ImFontGlyph*)(void*)FindGlyph((ImWchar)c)) + glyph->Visible = visible ? 1 : 0; +} + void ImFont::SetFallbackChar(ImWchar c) { FallbackChar = c; @@ -2676,7 +2688,8 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, { Glyphs.resize(Glyphs.Size + 1); ImFontGlyph& glyph = Glyphs.back(); - glyph.Codepoint = (ImWchar)codepoint; + glyph.Codepoint = (unsigned int)codepoint; + glyph.Visible = (x0 != x1) && (y0 != y1); glyph.X0 = x0; glyph.Y0 = y0; glyph.X1 = x1; @@ -2925,16 +2938,14 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const { - if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded. + const ImFontGlyph* glyph = FindGlyph(c); + if (!glyph || !glyph->Visible) return; - if (const ImFontGlyph* glyph = FindGlyph(c)) - { - float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; - pos.x = IM_FLOOR(pos.x + DisplayOffset.x); - pos.y = IM_FLOOR(pos.y + DisplayOffset.y); - draw_list->PrimReserve(6, 4); - draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); - } + float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; + pos.x = IM_FLOOR(pos.x + DisplayOffset.x); + pos.y = IM_FLOOR(pos.y + DisplayOffset.y); + draw_list->PrimReserve(6, 4); + draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); } void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const @@ -3047,73 +3058,70 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col continue; } - float char_width = 0.0f; - if (const ImFontGlyph* glyph = FindGlyph((ImWchar)c)) + const ImFontGlyph* glyph = FindGlyph((ImWchar)c); + if (glyph == NULL) + continue; + + float char_width = glyph->AdvanceX * scale; + if (glyph->Visible) { - char_width = glyph->AdvanceX * scale; - - // Arbitrarily assume that both space and tabs are empty glyphs as an optimization - if (c != ' ' && c != '\t') + // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w + float x1 = x + glyph->X0 * scale; + float x2 = x + glyph->X1 * scale; + float y1 = y + glyph->Y0 * scale; + float y2 = y + glyph->Y1 * scale; + if (x1 <= clip_rect.z && x2 >= clip_rect.x) { - // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w - float x1 = x + glyph->X0 * scale; - float x2 = x + glyph->X1 * scale; - float y1 = y + glyph->Y0 * scale; - float y2 = y + glyph->Y1 * scale; - if (x1 <= clip_rect.z && x2 >= clip_rect.x) + // Render a character + float u1 = glyph->U0; + float v1 = glyph->V0; + float u2 = glyph->U1; + float v2 = glyph->V1; + + // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quads. + if (cpu_fine_clip) { - // Render a character - float u1 = glyph->U0; - float v1 = glyph->V0; - float u2 = glyph->U1; - float v2 = glyph->V1; - - // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quads. - if (cpu_fine_clip) + if (x1 < clip_rect.x) { - if (x1 < clip_rect.x) - { - u1 = u1 + (1.0f - (x2 - clip_rect.x) / (x2 - x1)) * (u2 - u1); - x1 = clip_rect.x; - } - if (y1 < clip_rect.y) - { - v1 = v1 + (1.0f - (y2 - clip_rect.y) / (y2 - y1)) * (v2 - v1); - y1 = clip_rect.y; - } - if (x2 > clip_rect.z) - { - u2 = u1 + ((clip_rect.z - x1) / (x2 - x1)) * (u2 - u1); - x2 = clip_rect.z; - } - if (y2 > clip_rect.w) - { - v2 = v1 + ((clip_rect.w - y1) / (y2 - y1)) * (v2 - v1); - y2 = clip_rect.w; - } - if (y1 >= y2) - { - x += char_width; - continue; - } + u1 = u1 + (1.0f - (x2 - clip_rect.x) / (x2 - x1)) * (u2 - u1); + x1 = clip_rect.x; } - - // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here: + if (y1 < clip_rect.y) { - idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2); - idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3); - vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1; - vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1; - vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2; - vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2; - vtx_write += 4; - vtx_current_idx += 4; - idx_write += 6; + v1 = v1 + (1.0f - (y2 - clip_rect.y) / (y2 - y1)) * (v2 - v1); + y1 = clip_rect.y; } + if (x2 > clip_rect.z) + { + u2 = u1 + ((clip_rect.z - x1) / (x2 - x1)) * (u2 - u1); + x2 = clip_rect.z; + } + if (y2 > clip_rect.w) + { + v2 = v1 + ((clip_rect.w - y1) / (y2 - y1)) * (v2 - v1); + y2 = clip_rect.w; + } + if (y1 >= y2) + { + x += char_width; + continue; + } + } + + // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here: + { + idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2); + idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3); + vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1; + vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1; + vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2; + vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2; + vtx_write += 4; + vtx_current_idx += 4; + idx_write += 6; } } } - x += char_width; } From b4ac420fc5c839982476bd2b24ffabd2668dc7d0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 11 Feb 2020 19:31:33 +0100 Subject: [PATCH 09/16] Demo: Amend d284a6c (#2149, #515) --- imgui_demo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index c5f845de..0d800cd4 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1043,8 +1043,8 @@ static void ShowDemoWindowWidgets() static char password[64] = "password123"; ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); - ImGui::InputTextWithHint("password (w/ hint)", "", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); - ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_CharsNoBlank); + ImGui::InputTextWithHint("password (w/ hint)", "", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); + ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password)); ImGui::TreePop(); } From 2bc3a92f9614c32283a28c61214b9247a3fbc21b Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 12 Feb 2020 16:10:58 +0100 Subject: [PATCH 10/16] Update README.md --- docs/README.md | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/docs/README.md b/docs/README.md index cc1ac39e..a25e10f9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -190,24 +190,16 @@ Individuals: support continued maintenance and development via [PayPal](https:// Ongoing Dear ImGui development is financially supported by users and private sponsors, recently: *Platinum-chocolate sponsors* -- Blizzard Entertainment -- Google -- Ubisoft -- Nvidia +- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/fr/ubisoft-commandite-la-bibliotheque-dinterface-utilisateur-pour-c-dear-imgui/) -*Double-chocolate sponsors* -- Media Molecule, Mobigame, Aras Pranckevičius, Greggman, DotEmu, Nadeo, Supercell, Aiden Koss, Kylotonn. +*Double-chocolate and Salty caramel sponsors* +- DotEmu, Framefield, Kylotonn, Media Molecule, Mesh Consultants, Mobigame, Nadeo, Next Level Games, Remedy Entertainment, Supercell, Unit 2 Games. -*Salty caramel supporters* -- Remedy Entertainment, Next Level Games, Recognition Robotics, ikrima, Geoffrey Evans, Mercury Labs, Singularity Demo Group, Lionel Landwerlin, Ron Gilbert, Brandon Townsend, G3DVu, Cort Stratton, drudru, Harfang 3D, Jeff Roberts, Rainway inc, Ondra Voves, Mesh Consultants, Unit 2 Games, Neil Bickford, Bill Six, Graham Manders. +From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations. Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors). -*Caramel supporters* -- Jerome Lanquetot, Daniel Collin, Ctrl Alt Ninja, Neil Henning, Neil Blakey-Milner, Aleksei, NeiloGD, Eric, Game Atelier, Vincent Hamm, Morten Skaaning, Colin Riley, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Josh Faust, Martin Donlon, Codecat, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Jonas Bernemann, Johan Andersson, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Andrew Johnson, Sean Hunter, Jordan Mellow, Nefarius Software Solutions, Laura Wieme, Robert Nix, Mick Honey, Steven Kah Hien Wong, Bartosz Bielecki, Oscar Penas, A M, Liam Moynihan, Artometa, Mark Lee, Dimitri Diakopoulos, Pete Goodwin, Johnathan Roatch, nyu lea, Oswald Hurlem, Semyon Smelyanskiy, Le Bach, Jeong MyeongSoo, Chris Matthews, Astrofra, Frederik De Bleser, Anticrisis, Matt Reyer. +**THANK YOU to all past and present supporters for helping to keep this project alive and thriving!** -And all other past and present supporters; THANK YOU! -(Please contact me if you would like to be added or removed from this list) - -Dear ImGui is using software and services kindly provided free of charge for open source projects: +Dear ImGui is using software and services provided free of charge for open source projects: - [PVS-Studio](https://www.viva64.com/en/b/0570/) for static analysis. - [GitHub actions](https://github.com/features/actions) for continuous integration systems. From f339b24b3a0b6270c5e1a70df66e39b87d1ccdc6 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 12 Feb 2020 16:19:54 +0100 Subject: [PATCH 11/16] Links, alphabetical order --- docs/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index a25e10f9..72d35ded 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ dear imgui Businesses: support continued development via invoiced technical support, maintenance, sponsoring contracts:
  _E-mail: contact @ dearimgui dot org_ -Individuals: support continued maintenance and development via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S) donations. +Individuals: support continued maintenance and development with [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S). ---- @@ -164,7 +164,7 @@ You may also peak at the [Multi-Viewport](https://github.com/ocornut/imgui/issue **Who uses Dear ImGui?** -See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) and [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for a list of games/software which are publicly known to use dear imgui. Please add yours if you can! Also see the [Gallery Threads](https://github.com/ocornut/imgui/issues/2847)! +See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors), [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also see the [Gallery Threads](https://github.com/ocornut/imgui/issues/2847)! How to help ----------- @@ -183,17 +183,18 @@ Your contributions are keeping this project alive. The library is available unde Businesses: support continued development via invoiced technical support, maintenance, sponsoring contracts:
  _E-mail: contact @ dearimgui dot org_ -Individuals: support continued maintenance and development via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S) donations. +Individuals: support continued maintenance and development with [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S). -### Sponsors +Sponsors +-------- Ongoing Dear ImGui development is financially supported by users and private sponsors, recently: *Platinum-chocolate sponsors* -- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/fr/ubisoft-commandite-la-bibliotheque-dinterface-utilisateur-pour-c-dear-imgui/) +- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui/) *Double-chocolate and Salty caramel sponsors* -- DotEmu, Framefield, Kylotonn, Media Molecule, Mesh Consultants, Mobigame, Nadeo, Next Level Games, Remedy Entertainment, Supercell, Unit 2 Games. +- [DotEmu](http://www.dotemu.com), [Framefield](http://framefield.com), [Hexagon](https://hexagonxalt.com/the-technology/xalt-visualization), [Kylotonn](https://www.kylotonn.com), [Media Molecule](http://www.mediamolecule.com), [Mesh Consultants](https://www.meshconsultants.ca), [Mobigame](http://www.mobigame.net), [Nadeo](https://www.nadeo.com), [Supercell](http://www.supercell.com), [Remedy Entertainment](https://www.remedygames.com/), [Unit 2 Games](https://unit2games.com/) From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations. Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors). From 8601187feed8e2b937a8b07eb5a59b0ecebb49b4 Mon Sep 17 00:00:00 2001 From: Omar Date: Mon, 17 Feb 2020 10:11:26 +0100 Subject: [PATCH 12/16] Backends: Win32: Clarify how the WndProc handler requires a forward declaration. --- examples/example_win32_directx10/main.cpp | 4 +++- examples/example_win32_directx11/main.cpp | 4 +++- examples/example_win32_directx12/main.cpp | 4 +++- examples/example_win32_directx9/main.cpp | 4 +++- examples/imgui_impl_win32.cpp | 13 +++++++++---- examples/imgui_impl_win32.h | 10 +++++----- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/examples/example_win32_directx10/main.cpp b/examples/example_win32_directx10/main.cpp index 024e5eb7..41833cb5 100644 --- a/examples/example_win32_directx10/main.cpp +++ b/examples/example_win32_directx10/main.cpp @@ -207,8 +207,10 @@ void CleanupRenderTarget() if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; } } +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + // Win32 message handler -extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) diff --git a/examples/example_win32_directx11/main.cpp b/examples/example_win32_directx11/main.cpp index fe462e74..05de7433 100644 --- a/examples/example_win32_directx11/main.cpp +++ b/examples/example_win32_directx11/main.cpp @@ -211,8 +211,10 @@ void CleanupRenderTarget() if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; } } +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + // Win32 message handler -extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) diff --git a/examples/example_win32_directx12/main.cpp b/examples/example_win32_directx12/main.cpp index 87235125..139dea6e 100644 --- a/examples/example_win32_directx12/main.cpp +++ b/examples/example_win32_directx12/main.cpp @@ -427,8 +427,10 @@ void ResizeSwapChain(HWND hWnd, int width, int height) assert(g_hSwapChainWaitableObject != NULL); } +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + // Win32 message handler -extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) diff --git a/examples/example_win32_directx9/main.cpp b/examples/example_win32_directx9/main.cpp index 3586bd6f..f510ca4d 100644 --- a/examples/example_win32_directx9/main.cpp +++ b/examples/example_win32_directx9/main.cpp @@ -202,8 +202,10 @@ void ResetDevice() ImGui_ImplDX9_CreateDeviceObjects(); } +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + // Win32 message handler -extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index 140e1e4b..2740fe0e 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -2,7 +2,7 @@ // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) // Implemented features: -// [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) +// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. @@ -255,13 +255,18 @@ void ImGui_ImplWin32_NewFrame() #define DBT_DEVNODES_CHANGED 0x0007 #endif -// Process Win32 mouse/keyboard inputs. -// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// Win32 message handler (process Win32 mouse/keyboard inputs, etc.) +// Call from your application's message handler. +// When implementing your own back-end, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. -// 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. // PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds. // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. +#if 0 +// Copy this line into your .cpp file to forward declare the function. +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +#endif IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (ImGui::GetCurrentContext() == NULL) diff --git a/examples/imgui_impl_win32.h b/examples/imgui_impl_win32.h index 93dc75a0..e4b9ec3a 100644 --- a/examples/imgui_impl_win32.h +++ b/examples/imgui_impl_win32.h @@ -2,7 +2,7 @@ // This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) // Implemented features: -// [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) +// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. @@ -17,9 +17,9 @@ IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); //#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD //#define IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT -// Handler for Win32 messages, update mouse/keyboard data. -// You may or not need this for your implementation, but it can serve as reference for handling inputs. -// Intentionally commented out to avoid dragging dependencies on types. You can COPY this line into your .cpp code instead. +// Win32 message handler +// - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on +// - You can COPY this line into your .cpp code to forward declare the function. #if 0 -IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); #endif From ceec3cd3fd1c2331e45b18dd64d985a07328b4cc Mon Sep 17 00:00:00 2001 From: Omar Date: Mon, 17 Feb 2020 11:11:08 +0100 Subject: [PATCH 13/16] Backends: Win32: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helpers functions. (backported from the docking branch) --- docs/CHANGELOG.txt | 4 ++ examples/imgui_impl_win32.cpp | 100 ++++++++++++++++++++++++++++++++++ examples/imgui_impl_win32.h | 10 ++++ 3 files changed, 114 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4216ab50..f3d7cbfe 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -42,6 +42,10 @@ Other Changes: glyph. (#2149, #515) - Font: Fixed non-ASCII space occasionally creating unnecessary empty polygons. - Demo: Added a black and white gradient to Demo>Examples>Custom Rendering. +- Backends: Win32: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), + ImGui_ImplWin32_GetDpiScaleForMonitor() helpers functions (backported from the docking branch). + Those functions makes it easier for example apps to support hi-dpi features without setting up + a manifest. - Backends: SDL: Added ImGui_ImplSDL2_InitForMetal() for API consistency (even though the function currently does nothing). - Examples: Added SDL2+Metal example application. (#3017) [@coding-jackalope] diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index 2740fe0e..449922f5 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -28,6 +28,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions. // 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT. // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter(). @@ -337,3 +338,102 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA return 0; } + +//-------------------------------------------------------------------------------------------------------- +// DPI-related helpers (optional) +//-------------------------------------------------------------------------------------------------------- +// - Use to enable DPI awareness without having to create an application manifest. +// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. +// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. +// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, +// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. +//--------------------------------------------------------------------------------------------------------- +// This is the scheme successfully used by GLFW (from which we borrowed some of the code) and other apps aiming to be highly portable. +// ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically. +// If you are trying to implement your own back-end for your own engine, you may ignore that noise. +//--------------------------------------------------------------------------------------------------------- + +// Implement some of the functions and types normally declared in recent Windows SDK. +#if !defined(_versionhelpers_H_INCLUDED_) && !defined(_INC_VERSIONHELPERS) +static BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp) +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, { 0 }, sp }; + DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR; + ULONGLONG cond = ::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); + cond = ::VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); + cond = ::VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + return ::VerifyVersionInfoW(&osvi, mask, cond); +} +#define IsWindows8Point1OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WINBLUE +#endif + +#ifndef DPI_ENUMS_DECLARED +typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS; +typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE; +#endif +#ifndef _DPI_AWARENESS_CONTEXTS_ +DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3 +#endif +#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4 +#endif +typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+ +typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+ +typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update) + +// Helper function to enable DPI awareness without setting up a manifest +void ImGui_ImplWin32_EnableDpiAwareness() +{ + // if (IsWindows10OrGreater()) // This needs a manifest to succeed. Instead we try to grab the function pointer! + { + static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process + if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext")) + { + SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + return; + } + } + if (IsWindows8Point1OrGreater()) + { + static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process + if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness")) + { + SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE); + return; + } + } + SetProcessDPIAware(); +} + +#ifdef _MSC_VER +#pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps() +#endif + +float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) +{ + UINT xdpi = 96, ydpi = 96; + if (IsWindows8Point1OrGreater()) + { + static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process + if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor")) + GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); + } + else + { + const HDC dc = ::GetDC(NULL); + xdpi = ::GetDeviceCaps(dc, LOGPIXELSX); + ydpi = ::GetDeviceCaps(dc, LOGPIXELSY); + ::ReleaseDC(NULL, dc); + } + IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert! + return xdpi / 96.0f; +} + +float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) +{ + HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST); + return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); +} + +//--------------------------------------------------------------------------------------------------------- diff --git a/examples/imgui_impl_win32.h b/examples/imgui_impl_win32.h index e4b9ec3a..daadf317 100644 --- a/examples/imgui_impl_win32.h +++ b/examples/imgui_impl_win32.h @@ -23,3 +23,13 @@ IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame(); #if 0 extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); #endif + +// DPI-related helpers (optional) +// - Use to enable DPI awareness without having to create an application manifest. +// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps. +// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc. +// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime, +// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies. +IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness(); +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd +IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor From 09329ea4e6e7ff6d0f3ecbb16588a2ccd61dedd1 Mon Sep 17 00:00:00 2001 From: Omar Date: Mon, 17 Feb 2020 15:29:59 +0100 Subject: [PATCH 14/16] Fix Clang 9.0 zealous warnings --- imgui_demo.cpp | 2 +- imgui_draw.cpp | 6 +++--- imstb_truetype.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0d800cd4..13a0e8c2 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -629,7 +629,7 @@ static void ShowDemoWindowWidgets() { ImGui::Text("blah blah"); ImGui::SameLine(); - if (ImGui::SmallButton("button")) {}; + if (ImGui::SmallButton("button")) {} ImGui::TreePop(); } } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b34358d6..69d18945 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -617,8 +617,8 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c // On AddPolyline() and AddConvexPolyFilled() we intentionally avoid using ImVec2 and superflous function calls to optimize debug/non-inlined builds. // Those macros expects l-values. -#define IM_NORMALIZE2F_OVER_ZERO(VX,VY) { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = 1.0f / ImSqrt(d2); VX *= inv_len; VY *= inv_len; } } -#define IM_FIXNORMAL2F(VX,VY) { float d2 = VX*VX + VY*VY; if (d2 < 0.5f) d2 = 0.5f; float inv_lensq = 1.0f / d2; VX *= inv_lensq; VY *= inv_lensq; } +#define IM_NORMALIZE2F_OVER_ZERO(VX,VY) do { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = 1.0f / ImSqrt(d2); VX *= inv_len; VY *= inv_len; } } while (0) +#define IM_FIXNORMAL2F(VX,VY) do { float d2 = VX*VX + VY*VY; if (d2 < 0.5f) d2 = 0.5f; float inv_lensq = 1.0f / d2; VX *= inv_lensq; VY *= inv_lensq; } while (0) // TODO: Thickness anti-aliased lines cap are missing their AA fringe. // We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds. @@ -680,7 +680,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 // Average normals float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f; float dm_y = (temp_normals[i1].y + temp_normals[i2].y) * 0.5f; - IM_FIXNORMAL2F(dm_x, dm_y) + IM_FIXNORMAL2F(dm_x, dm_y); dm_x *= AA_SIZE; dm_y *= AA_SIZE; diff --git a/imstb_truetype.h b/imstb_truetype.h index 193338af..7ccc13e8 100644 --- a/imstb_truetype.h +++ b/imstb_truetype.h @@ -2538,11 +2538,11 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i // There are no other cases. STBTT_assert(0); break; - }; + } // [DEAR IMGUI] removed ; } } break; - }; + } // [DEAR IMGUI] removed ; default: // TODO: Implement other stuff. From b62f1ea8e914b66d1bfb58719d07d074eead0c8f Mon Sep 17 00:00:00 2001 From: Omar Date: Mon, 17 Feb 2020 16:07:46 +0100 Subject: [PATCH 15/16] Fix zealous PVS studio warnings. Minor tweaks. --- examples/example_win32_directx9/main.cpp | 6 +++--- examples/imgui_impl_dx9.cpp | 12 ++++++------ imgui_demo.cpp | 7 ++++--- imgui_internal.h | 2 +- imstb_truetype.h | 2 +- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/examples/example_win32_directx9/main.cpp b/examples/example_win32_directx9/main.cpp index f510ca4d..33123625 100644 --- a/examples/example_win32_directx9/main.cpp +++ b/examples/example_win32_directx9/main.cpp @@ -136,9 +136,9 @@ int main(int, char**) // Rendering ImGui::EndFrame(); - g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false); - g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false); - g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false); + g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*255.0f), (int)(clear_color.y*255.0f), (int)(clear_color.z*255.0f), (int)(clear_color.w*255.0f)); g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, clear_col_dx, 1.0f, 0); if (g_pd3dDevice->BeginScene() >= 0) diff --git a/examples/imgui_impl_dx9.cpp b/examples/imgui_impl_dx9.cpp index 342f9d54..03114aa8 100644 --- a/examples/imgui_impl_dx9.cpp +++ b/examples/imgui_impl_dx9.cpp @@ -60,16 +60,16 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data) g_pd3dDevice->SetPixelShader(NULL); g_pd3dDevice->SetVertexShader(NULL); g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false); - g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false); - g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true); - g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, false); + g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + g_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, true); + g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); - g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, false); + g_pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 13a0e8c2..35fe94d9 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -4524,9 +4524,10 @@ static void ShowExampleAppCustomRendering(bool* p_open) y = ImGui::GetCursorScreenPos().y; for (int n = 0; n < gradient_steps; n++) { - float f = n / (float)gradient_steps; - ImU32 col32 = ImGui::GetColorU32(ImVec4(f, f, f, 1.0f)); - draw_list->AddRectFilled(ImVec2(x + gradient_size.x * (n / (float)gradient_steps), y), ImVec2(x + gradient_size.x * ((n+1) / (float)gradient_steps), y + gradient_size.y), col32); + float f0 = n / (float)gradient_steps; + float f1 = (n + 1) / (float)gradient_steps; + ImU32 col32 = ImGui::GetColorU32(ImVec4(f0, f0, f0, 1.0f)); + draw_list->AddRectFilled(ImVec2(x + gradient_size.x * f0, y), ImVec2(x + gradient_size.x * f1, y + gradient_size.y), col32); } ImGui::InvisibleButton("##gradient", gradient_size); diff --git a/imgui_internal.h b/imgui_internal.h index 450318da..d3a30257 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -866,7 +866,7 @@ struct ImGuiColumns // Helper function to calculate a circle's segment count given its radius and a "maximum error" value. #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 12 #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512 -#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp((int)((IM_PI * 2.0f) / ImAcos((_RAD - _MAXERROR) / _RAD)), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX) +#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp((int)((IM_PI * 2.0f) / ImAcos(((_RAD) - (_MAXERROR)) / (_RAD))), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX) // Data shared between all ImDrawList instances // You may want to create your own instance of this if you want to use ImDrawList completely without ImGui. In that case, watch out for future changes to this structure. diff --git a/imstb_truetype.h b/imstb_truetype.h index 7ccc13e8..b4bdbd86 100644 --- a/imstb_truetype.h +++ b/imstb_truetype.h @@ -4132,7 +4132,7 @@ STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { stbtt_fontinfo info; - int i,j,n, return_value = 1; + int i,j,n, return_value; // [DEAR IMGUI] removed = 1 //stbrp_context *context = (stbrp_context *) spc->pack_info; stbrp_rect *rects; From 8836975dcfc770731932ebec3bbb69579fb29071 Mon Sep 17 00:00:00 2001 From: Omar Date: Mon, 17 Feb 2020 17:41:45 +0100 Subject: [PATCH 16/16] Drag and Drop, Nav: Disabling navigation arrow keys when drag and drop is active. (#3025) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index f3d7cbfe..765b81d8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -36,6 +36,8 @@ HOW TO UPDATE? Other Changes: +- Drag and Drop, Nav: Disabling navigation arrow keys when drag and drop is active. In the docking + branch pressing arrow keys while dragging a window from a tab could trigger an assert. (#3025) - ColorButton: Added ImGuiColorEditFlags_NoBorder flag to remove the border normally enforced by default for standalone ColorButton. - InputText: Fixed password fields displaying ASCII spaces as blanks instead of using the '*' diff --git a/imgui.cpp b/imgui.cpp index 53b05aa4..85ecc45c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3254,6 +3254,9 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window) // Handle mouse moving window // Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing() +// FIXME: We don't have strong guarantee that g.MovingWindow stay synched with g.ActiveId == g.MovingWindow->MoveId. +// This is currently enforced by the fact that BeginDragDropSource() is setting all g.ActiveIdUsingXXXX flags to inhibit navigation inputs, +// but if we should more thoroughly test cases where g.ActiveId or g.MovingWindow gets changed and not the other. void ImGui::UpdateMouseMovingWindowNewFrame() { ImGuiContext& g = *GImGui; @@ -8999,6 +9002,11 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) return false; source_parent_id = window->IDStack.back(); source_drag_active = IsMouseDragging(mouse_button); + + // Disable navigation and key inputs while dragging + g.ActiveIdUsingNavDirMask = ~(ImU32)0; + g.ActiveIdUsingNavInputMask = ~(ImU32)0; + g.ActiveIdUsingKeyInputMask = ~(ImU64)0; } else {