diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 50a6133c91a3..352cdcb3dccf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,8 +1,8 @@ name: build on: - push: {} - pull_request: {} + push: + pull_request: schedule: - cron: '0 9 * * *' @@ -12,21 +12,19 @@ jobs: env: VS_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\ MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\ - # Until gh-actions allow us to use env variables inside other env variables (because we need %GITHUB_WORKSPACE%) we have to use relative path to imgui/examples/example_name directory. - SDL2_DIR: ..\..\SDL2-devel-2.0.10-VC\SDL2-2.0.10\ - VULKAN_SDK: ..\..\vulkan-sdk-1.1.121.2\ steps: - - uses: actions/checkout@v1 - with: - fetch-depth: 1 + - uses: actions/checkout@v2 - name: Install Dependencies shell: powershell run: | Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.0.10-VC.zip" -OutFile "SDL2-devel-2.0.10-VC.zip" Expand-Archive -Path SDL2-devel-2.0.10-VC.zip + echo "SDL2_DIR=$(pwd)\SDL2-devel-2.0.10-VC\SDL2-2.0.10\" >>${env:GITHUB_ENV} + Invoke-WebRequest -Uri "https://github.com/ocornut/imgui/files/3789205/vulkan-sdk-1.1.121.2.zip" -OutFile vulkan-sdk-1.1.121.2.zip Expand-Archive -Path vulkan-sdk-1.1.121.2.zip + echo "VULKAN_SDK=$(pwd)\vulkan-sdk-1.1.121.2\" >>${env:GITHUB_ENV} - name: Fix Projects shell: powershell @@ -55,24 +53,33 @@ jobs: - name: Build example_null (single file build) shell: bash 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_WIN32_FUNCTIONS) shell: bash run: | - echo '#define IMGUI_DISABLE_WIN32_FUNCTIONS' > example_single_file.cpp - 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_DISABLE_WIN32_FUNCTIONS + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF g++ -I. -Wall -Wformat -o example_single_file.exe example_single_file.cpp - name: Build example_null (as DLL) shell: cmd run: | call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat" + echo #ifdef _EXPORT > example_single_file.cpp echo # define IMGUI_API __declspec(dllexport) >> example_single_file.cpp echo #else >> example_single_file.cpp @@ -80,6 +87,7 @@ jobs: echo #endif >> example_single_file.cpp echo #define IMGUI_IMPLEMENTATION >> example_single_file.cpp echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp + cl.exe /D_USRDLL /D_WINDLL /D_EXPORT /I. example_single_file.cpp /LD /FeImGui.dll /link cl.exe /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp @@ -183,9 +191,7 @@ jobs: Linux: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v1 - with: - fetch-depth: 1 + - uses: actions/checkout@v2 - name: Install Dependencies run: | @@ -219,82 +225,118 @@ jobs: - name: Build example_null (single file build) 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with ImWchar32) run: | - echo '#define IMGUI_USE_WCHAR32' > example_single_file.cpp - 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_USE_WCHAR32 + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with large ImDrawIdx) run: | - echo '#define ImDrawIdx unsigned int' > example_single_file.cpp - 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 + cat > example_single_file.cpp <<'EOF' + + #define ImDrawIdx unsigned int + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS) run: | - echo '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' > example_single_file.cpp - 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_METRICS_WINDOW) run: | - echo '#define IMGUI_DISABLE_DEMO_WINDOWS' > example_single_file.cpp - echo '#define IMGUI_DISABLE_METRICS_WINDOW' >> example_single_file.cpp - 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_DISABLE_DEMO_WINDOWS + #define IMGUI_DISABLE_METRICS_WINDOW + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS) run: | - echo '#define IMGUI_DISABLE_FILE_FUNCTIONS' > example_single_file.cpp - 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_DISABLE_FILE_FUNCTIONS + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR) run: | - echo '#define IMGUI_USE_BGRA_PACKED_COLOR' > example_single_file.cpp - 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_USE_BGRA_PACKED_COLOR + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp - name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA) run: | - echo 'struct MyVec2 { float x; float y; MyVec2(float x, float y) : x(x), y(y) { } };' > example_single_file.cpp - echo 'struct MyVec4 { float x; float y; float z; float w;' >> example_single_file.cpp - echo 'MyVec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { } };' >> example_single_file.cpp - echo '#define IM_VEC2_CLASS_EXTRA \' >> example_single_file.cpp - echo ' ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \' >> example_single_file.cpp - echo ' operator MyVec2() const { return MyVec2(x, y); }' >> example_single_file.cpp - echo '#define IM_VEC4_CLASS_EXTRA \' >> example_single_file.cpp - echo ' ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \' >> example_single_file.cpp - echo ' operator MyVec4() const { return MyVec4(x, y, z, w); }' >> example_single_file.cpp - 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 + cat > example_single_file.cpp <<'EOF' + + struct MyVec2 { float x; float y; MyVec2(float x, float y) : x(x), y(y) { } }; + struct MyVec4 { float x; float y; float z; float w; + MyVec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { } }; + #define IM_VEC2_CLASS_EXTRA \ + ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ + operator MyVec2() const { return MyVec2(x, y); } + #define IM_VEC4_CLASS_EXTRA \ + ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ + operator MyVec4() const { return MyVec4(x, y, z, w); } + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_IMPLEMENTATION + #define IMGUI_DISABLE_DEMO_WINDOWS + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF 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 @@ -314,30 +356,35 @@ jobs: MacOS: runs-on: macOS-latest steps: - - uses: actions/checkout@v1 - with: - fetch-depth: 1 + - uses: actions/checkout@v2 - name: Install Dependencies run: | - brew install glfw3 - brew install sdl2 + brew install glfw3 sdl2 - name: Build example_null (extra warnings, clang 64-bit) run: make -C examples/example_null WITH_EXTRA_WARNINGS=1 - name: Build example_null (single file build) 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF 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 + cat > example_single_file.cpp <<'EOF' + + #define IMGUI_IMPLEMENTATION + #include "misc/single_file/imgui_single_file.h" + #include "examples/example_null/main.cpp" + + EOF 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 @@ -369,9 +416,7 @@ jobs: iOS: runs-on: macOS-latest steps: - - uses: actions/checkout@v1 - with: - fetch-depth: 1 + - uses: actions/checkout@v2 - name: Build example_apple_metal run: | @@ -381,9 +426,7 @@ jobs: Emscripten: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v1 - with: - fetch-depth: 1 + - uses: actions/checkout@v2 - name: Install Dependencies run: | diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4a1201b27021..6fdfeb58a710 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -124,6 +124,21 @@ Breaking Changes: Other Changes: +- Viewports Added ImGui::GetMainViewport() as a way to get the bounds and work area of the host display. (#3789, #1542) + - In 'master' branch or without multi-viewports feature enabled: + - GetMainViewport()->Pos is always == (0,0) + - GetMainViewport()->Size is always == io.DisplaySize + - In 'docking' branch and with the multi-viewports feature enabled: + - GetMainViewport() will return information from your host Platform Window. + - In the future, we will support a "no main viewport" mode and this may return bounds of your main monitor. + - For forward compatibility with multi-viewports/multi-monitors: + - Code using (0,0) as a way to signify "upper-left of the host window" should use GetMainViewport()->Pos. + - Code using io.DisplaySize as a way to signify "size of the host window" should use GetMainViewport()->Size. + - We are also exposing a work area in ImGuiViewport ('WorkPos', 'WorkSize' vs 'Pos', 'Size' for full area): + - For a Platform Window, the work area is generally the full area minus space used by menu-bars. + - For a Platform Monitor, the work area is generally the full area minus space used by task-bars. + - All of this has been the case in 'docking' branch for a long time. What we've done is merely merging + a small chunk of the multi-viewport logic into 'master' to standardize some concepts ahead of time. - Tables: Fixed PopItemWidth() or multi-components items not restoring per-colum ItemWidth correctly. (#3760) - Window: Fixed minor title bar text clipping issue when FramePadding is small/zero and there are no close button in the window. (#3731) @@ -152,7 +167,9 @@ Other Changes: Would lead to a buffer read overflow. - ImDrawList: Clarified PathArcTo() need for a_min <= a_max with an assert. - ImDrawList: Fixed PathArcToFast() handling of a_min > a_max. -- Demo: Added 'Examples->Fullscreen Window' demo. (#3789) +- Metrics: Backported "Viewports" debug visualizer from 'docking' branch. +- Demo: Added 'Examples->Fullscreen Window' demo using GetMainViewport() values. (#3789) +- Demo: 'Simple Overlay' demo now moves under main menu-bar (if any) using GetMainViewport()'s work area. - Backends: Win32: Dynamically loading XInput DLL instead of linking with it, facilite compiling with old WindowSDK versions or running on Windows 7. (#3646, #3645, #3248, #2716) [@Demonese] - Backends: Vulkan: Add support for custom Vulkan function loader and VK_NO_PROTOTYPES. (#3759, #3227) [@Hossein-Noroozpour] diff --git a/imgui.cpp b/imgui.cpp index 6355fc2c02c1..8f43e9bf2191 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -311,10 +311,11 @@ CODE // We are using scissoring to clip some objects. All low-level graphics API should supports it. // - If your engine doesn't support scissoring yet, you may ignore this at first. You will get some small glitches // (some elements visible outside their bounds) but you can fix that once everything else works! - // - Clipping coordinates are provided in imgui coordinates space (from draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize) - // In a single viewport application, draw_data->DisplayPos will always be (0,0) and draw_data->DisplaySize will always be == io.DisplaySize. - // However, in the interest of supporting multi-viewport applications in the future (see 'viewport' branch on github), - // always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space. + // - Clipping coordinates are provided in imgui coordinates space: + // - For a given viewport, draw_data->DisplayPos == viewport->Pos and draw_data->DisplaySize == viewport->Size + // - In a single viewport application, draw_data->DisplayPos == (0,0) and draw_data->DisplaySize == io.DisplaySize, but always use GetMainViewport()->Pos/Size instead of hardcoding those values. + // - In the interest of supporting multi-viewport applications (see 'docking' branch on github), + // always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space. // - Note that pcmd->ClipRect contains Min+Max bounds. Some graphics API may use Min+Max, other may use Min+Size (size being Max-Min) ImVec2 pos = draw_data->DisplayPos; MyEngineScissor((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(pcmd->ClipRect.z - pos.x), (int)(pcmd->ClipRect.w - pos.y)); @@ -4220,7 +4221,6 @@ void ImGui::Initialize(ImGuiContext* context) TableSettingsInstallHandler(context); #endif // #ifdef IMGUI_HAS_TABLE -#ifdef IMGUI_HAS_DOCK // Create default viewport ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)(); viewport->ID = IMGUI_VIEWPORT_DEFAULT_ID; @@ -4229,9 +4229,10 @@ void ImGui::Initialize(ImGuiContext* context) g.Viewports.push_back(viewport); g.PlatformIO.Viewports.push_back(g.Viewports[0]); - // Extensions +#ifdef IMGUI_HAS_DOCK + // Initialize Docking DockContextInitialize(&g); -#endif // #ifdef IMGUI_HAS_DOCK +#endif g.Initialized = true; } @@ -4691,8 +4692,9 @@ void ImGui::Render() AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetForegroundDrawList(viewport)); SetupViewportDrawData(viewport, &viewport->DrawDataBuilder.Layers[0]); - g.IO.MetricsRenderVertices += viewport->DrawData->TotalVtxCount; - g.IO.MetricsRenderIndices += viewport->DrawData->TotalIdxCount; + ImDrawData* draw_data = viewport->DrawData; + g.IO.MetricsRenderVertices += draw_data->TotalVtxCount; + g.IO.MetricsRenderIndices += draw_data->TotalIdxCount; } CallContextHooks(&g, ImGuiContextHookType_RenderPost); @@ -15804,7 +15806,7 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) #ifndef IMGUI_DISABLE_METRICS_WINDOW -static void RenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb) +void ImGui::DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -15823,18 +15825,17 @@ static void RenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewp ImRect thumb_r = thumb_window->Rect(); ImRect title_r = thumb_window->TitleBarRect(); - ImRect thumb_r_scaled = ImRect(ImFloor(off + thumb_r.Min * scale), ImFloor(off + thumb_r.Max * scale)); - ImRect title_r_scaled = ImRect(ImFloor(off + title_r.Min * scale), ImFloor(off + ImVec2(title_r.Max.x, title_r.Min.y) * scale) + ImVec2(0,5)); // Exaggerate title bar height - thumb_r_scaled.ClipWithFull(bb); - title_r_scaled.ClipWithFull(bb); + thumb_r = ImRect(ImFloor(off + thumb_r.Min * scale), ImFloor(off + thumb_r.Max * scale)); + title_r = ImRect(ImFloor(off + title_r.Min * scale), ImFloor(off + ImVec2(title_r.Max.x, title_r.Min.y) * scale) + ImVec2(0,5)); // Exaggerate title bar height + thumb_r.ClipWithFull(bb); + title_r.ClipWithFull(bb); const bool window_is_focused = (g.NavWindow && thumb_window->RootWindowForTitleBarHighlight == g.NavWindow->RootWindowForTitleBarHighlight); - window->DrawList->AddRectFilled(thumb_r_scaled.Min, thumb_r_scaled.Max, ImGui::GetColorU32(ImGuiCol_WindowBg, alpha_mul)); - window->DrawList->AddRectFilled(title_r_scaled.Min, title_r_scaled.Max, ImGui::GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg, alpha_mul)); - window->DrawList->AddRect(thumb_r_scaled.Min, thumb_r_scaled.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul)); - if (ImGuiWindow* window_for_title = GetWindowForTitleDisplay(thumb_window)) - window->DrawList->AddText(g.Font, g.FontSize * 1.0f, title_r_scaled.Min, ImGui::GetColorU32(ImGuiCol_Text, alpha_mul), window_for_title->Name, ImGui::FindRenderedTextEnd(window_for_title->Name)); + window->DrawList->AddRectFilled(thumb_r.Min, thumb_r.Max, GetColorU32(ImGuiCol_WindowBg, alpha_mul)); + window->DrawList->AddRectFilled(title_r.Min, title_r.Max, GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg, alpha_mul)); + window->DrawList->AddRect(thumb_r.Min, thumb_r.Max, GetColorU32(ImGuiCol_Border, alpha_mul)); + window->DrawList->AddText(g.Font, g.FontSize * 1.0f, title_r.Min, GetColorU32(ImGuiCol_Text, alpha_mul), thumb_window->Name, FindRenderedTextEnd(thumb_window->Name)); } - draw_list->AddRect(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul)); + draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_Border, alpha_mul)); } static void RenderViewportsThumbnails() @@ -15844,7 +15845,7 @@ static void RenderViewportsThumbnails() // We don't display full monitor bounds (we could, but it often looks awkward), instead we display just enough to cover all of our viewports. float SCALE = 1.0f / 8.0f; - ImRect bb_full; + ImRect bb_full(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX); for (int n = 0; n < g.Viewports.Size; n++) bb_full.Add(g.Viewports[n]->GetMainRect()); ImVec2 p = window->DC.CursorPos; @@ -15853,7 +15854,7 @@ static void RenderViewportsThumbnails() { ImGuiViewportP* viewport = g.Viewports[n]; ImRect viewport_draw_bb(off + (viewport->Pos) * SCALE, off + (viewport->Pos + viewport->Size) * SCALE); - RenderViewportThumbnail(window->DrawList, viewport, viewport_draw_bb); + ImGui::DebugRenderViewportThumbnail(window->DrawList, viewport, viewport_draw_bb); } ImGui::Dummy(bb_full.GetSize() * SCALE); } @@ -16582,7 +16583,10 @@ void ImGui::DebugNodeViewport(ImGuiViewportP* viewport) viewport->WorkOffsetMin.x, viewport->WorkOffsetMin.y, viewport->WorkOffsetMax.x, viewport->WorkOffsetMax.y, viewport->PlatformMonitor, viewport->DpiScale * 100.0f); if (viewport->Idx > 0) { SameLine(); if (SmallButton("Reset Pos")) { viewport->Pos = ImVec2(200, 200); viewport->UpdateWorkRect(); if (viewport->Window) viewport->Window->Pos = viewport->Pos; } } - BulletText("Flags: 0x%04X =%s%s%s%s%s%s%s%s%s%s", viewport->Flags, + BulletText("Flags: 0x%04X =%s%s%s%s%s%s%s%s%s%s%s%s%s", viewport->Flags, + (flags & ImGuiViewportFlags_IsPlatformWindow) ? " IsPlatformWindow" : "", + (flags & ImGuiViewportFlags_IsPlatformMonitor) ? " IsPlatformMonitor" : "", + (flags & ImGuiViewportFlags_OwnedByApp) ? " OwnedByApp" : "", (flags & ImGuiViewportFlags_NoDecoration) ? " NoDecoration" : "", (flags & ImGuiViewportFlags_NoTaskBarIcon) ? " NoTaskBarIcon" : "", (flags & ImGuiViewportFlags_NoFocusOnAppearing) ? " NoFocusOnAppearing" : "", diff --git a/imgui.h b/imgui.h index 3345249bccd0..74cd737828ca 100644 --- a/imgui.h +++ b/imgui.h @@ -61,7 +61,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.81 WIP" -#define IMGUI_VERSION_NUM 18003 +#define IMGUI_VERSION_NUM 18004 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_HAS_TABLE #define IMGUI_HAS_VIEWPORT // Viewport WIP branch @@ -149,7 +149,7 @@ struct ImGuiTableSortSpecs; // Sorting specifications for a table (often struct ImGuiTableColumnSortSpecs; // Sorting specification for one column of a table struct ImGuiTextBuffer; // Helper to hold and append into a text buffer (~string builder) struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbbb][,ccccc]") -struct ImGuiViewport; // Viewport (generally ~1 per window to output to at the OS level. Need per-platform support to use multiple viewports) +struct ImGuiViewport; // A Platform Window (always 1 unless multi-viewport are enabled. One per platform window to output to). In the future may represent Platform Monitor struct ImGuiWindowClass; // Window class (rare/advanced uses: provide hints to the platform backend via altered viewport flags and parent/child info) // Enums/Flags (declared as int for compatibility with old C++, to allow using as flags and to not pollute the top of this file) @@ -816,6 +816,12 @@ namespace ImGui IMGUI_API ImVec2 GetItemRectSize(); // get size of last item IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. + // Viewports + // - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows. + // - In 'docking' branch with multi-viewport enabled, we extend this concept to have multiple active viewports. + // - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode. + IMGUI_API ImGuiViewport* GetMainViewport(); // return primary/default viewport. + // Miscellaneous Utilities IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. @@ -1812,7 +1818,7 @@ struct ImGuiIO ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc. ImGuiBackendFlags BackendFlags; // = 0 // See ImGuiBackendFlags_ enum. Set by backend (imgui_impl_xxx files or custom backend) to communicate features supported by the backend. - ImVec2 DisplaySize; // // Main display size, in pixels. This is for the default viewport. + ImVec2 DisplaySize; // // Main display size, in pixels (generally == GetMainViewport()->Size) float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds. const char* IniFilename; // = "imgui.ini" // Path to .ini file. Set NULL to disable automatic .ini loading/saving, if e.g. you want to manually load/save from memory. @@ -2440,7 +2446,8 @@ enum ImDrawListFlags_ // Each dear imgui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to // access the current window draw list and draw custom primitives. // You can interleave normal ImGui:: calls and adding primitives to the current draw list. -// All positions are generally in pixel coordinates (generally top-left at 0,0, bottom-right at io.DisplaySize, unless multiple viewports are used), but you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well) +// In single viewport mode, top-left is == GetMainViewport()->Pos (generally 0,0), bottom-right is == GetMainViewport()->Pos+Size (generally io.DisplaySize). +// You are totally free to apply whatever transformation matrix to want to the data (depending on the use of the transformation you may want to apply it to ClipRect as well!) // Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects. struct ImDrawList { @@ -2571,8 +2578,8 @@ struct ImDrawData int TotalIdxCount; // For convenience, sum of all ImDrawList's IdxBuffer.Size int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size ImDrawList** CmdLists; // Array of ImDrawList* to render. The ImDrawList are owned by ImGuiContext and only pointed to from here. - ImVec2 DisplayPos; // Upper-left position of the viewport to render (== upper-left of the orthogonal projection matrix to use) - ImVec2 DisplaySize; // Size of the viewport to render (== io.DisplaySize for the main viewport) (DisplayPos + DisplaySize == lower-right of the orthogonal projection matrix to use) + ImVec2 DisplayPos; // Top-left position of the viewport to render (== top-left of the orthogonal projection matrix to use) (== GetMainViewport()->Pos for the main viewport, == (0.0) in most single-viewport applications) + ImVec2 DisplaySize; // Size of the viewport to render (== GetMainViewport()->Size for the main viewport, == io.DisplaySize in most single-viewport applications) ImVec2 FramebufferScale; // Amount of pixels for each unit of DisplaySize. Based on io.DisplayFramebufferScale. Generally (1,1) on normal display, (2,2) on OSX with Retina display. ImGuiViewport* OwnerViewport; // Viewport carrying the ImDrawData instance, might be of use to the renderer (generally not). @@ -2839,21 +2846,28 @@ struct ImFont enum ImGuiViewportFlags_ { ImGuiViewportFlags_None = 0, - ImGuiViewportFlags_NoDecoration = 1 << 0, // Platform Window: Disable platform decorations: title bar, borders, etc. (generally set all windows, but if ImGuiConfigFlags_ViewportsDecoration is set we only set this on popups/tooltips) - ImGuiViewportFlags_NoTaskBarIcon = 1 << 1, // Platform Window: Disable platform task bar icon (generally set on popups/tooltips, or all windows if ImGuiConfigFlags_ViewportsNoTaskBarIcon is set) - ImGuiViewportFlags_NoFocusOnAppearing = 1 << 2, // Platform Window: Don't take focus when created. - ImGuiViewportFlags_NoFocusOnClick = 1 << 3, // Platform Window: Don't take focus when clicked on. - ImGuiViewportFlags_NoInputs = 1 << 4, // Platform Window: Make mouse pass through so we can drag this window while peaking behind it. - ImGuiViewportFlags_NoRendererClear = 1 << 5, // Platform Window: Renderer doesn't need to clear the framebuffer ahead (because we will fill it entirely). - ImGuiViewportFlags_TopMost = 1 << 6, // Platform Window: Display on top (for tooltips only). - ImGuiViewportFlags_Minimized = 1 << 7, // Platform Window: Window is minimized, can skip render. When minimized we tend to avoid using the viewport pos/size for clipping window or testing if they are contained in the viewport. - ImGuiViewportFlags_NoAutoMerge = 1 << 8, // Platform Window: Avoid merging this window into another host window. This can only be set via ImGuiWindowClass viewport flags override (because we need to now ahead if we are going to create a viewport in the first place!). - ImGuiViewportFlags_CanHostOtherWindows = 1 << 9 // Main viewport: can host multiple imgui windows (secondary viewports are associated to a single window). -}; - -// The viewports created and managed by Dear ImGui. The role of the platform backend is to create the platform/OS windows corresponding to each viewport. -// - Main Area = entire viewport. -// - Work Area = entire viewport minus sections optionally used by menu bars, status bars. Windows are generally trying to stay within this area. + ImGuiViewportFlags_IsPlatformWindow = 1 << 0, // Represent a Platform Window + ImGuiViewportFlags_IsPlatformMonitor = 1 << 1, // Represent a Platform Monitor (unused yet) + ImGuiViewportFlags_OwnedByApp = 1 << 2, // Platform Window: is created/managed by the application (rather than a dear imgui backend) + ImGuiViewportFlags_NoDecoration = 1 << 3, // Platform Window: Disable platform decorations: title bar, borders, etc. (generally set all windows, but if ImGuiConfigFlags_ViewportsDecoration is set we only set this on popups/tooltips) + ImGuiViewportFlags_NoTaskBarIcon = 1 << 4, // Platform Window: Disable platform task bar icon (generally set on popups/tooltips, or all windows if ImGuiConfigFlags_ViewportsNoTaskBarIcon is set) + ImGuiViewportFlags_NoFocusOnAppearing = 1 << 5, // Platform Window: Don't take focus when created. + ImGuiViewportFlags_NoFocusOnClick = 1 << 6, // Platform Window: Don't take focus when clicked on. + ImGuiViewportFlags_NoInputs = 1 << 7, // Platform Window: Make mouse pass through so we can drag this window while peaking behind it. + ImGuiViewportFlags_NoRendererClear = 1 << 8, // Platform Window: Renderer doesn't need to clear the framebuffer ahead (because we will fill it entirely). + ImGuiViewportFlags_TopMost = 1 << 9, // Platform Window: Display on top (for tooltips only). + ImGuiViewportFlags_Minimized = 1 << 10, // Platform Window: Window is minimized, can skip render. When minimized we tend to avoid using the viewport pos/size for clipping window or testing if they are contained in the viewport. + ImGuiViewportFlags_NoAutoMerge = 1 << 11, // Platform Window: Avoid merging this window into another host window. This can only be set via ImGuiWindowClass viewport flags override (because we need to now ahead if we are going to create a viewport in the first place!). + ImGuiViewportFlags_CanHostOtherWindows = 1 << 12 // Main viewport: can host multiple imgui windows (secondary viewports are associated to a single window). +}; + +// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows. +// - With multi-viewport enabled, we extend this concept to have multiple active viewports. +// - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode. +// - About Main Area vs Work Area: +// - Main Area = entire viewport. +// - Work Area = entire viewport minus sections used by main menu bars (for platform windows), or by task bar (for platform monitor). +// - Windows are generally trying to stay within the Work Area of their host viewport. struct ImGuiViewport { ImGuiID ID; // Unique identifier for the viewport @@ -3008,6 +3022,8 @@ struct ImGuiPlatformMonitor ImGuiPlatformMonitor() { MainPos = MainSize = WorkPos = WorkSize = ImVec2(0, 0); DpiScale = 1.0f; } }; +//----------------------------------------------------------------------------- + #if defined(__clang__) #pragma clang diagnostic pop #elif defined(__GNUC__) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 54a4e8803fd7..d4dcbe6da62b 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -7113,14 +7113,21 @@ static void ShowExampleAppSimpleOverlay(bool* p_open) // Demonstrate creating a window covering the entire screen/viewport static void ShowExampleAppFullscreen(bool* p_open) { - // May use viewport->WorkPos and viewport->WorkSize to avoid menu-bar/task-bar + static bool use_work_area = true; + static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; + + // We demonstrate using the full viewport area or the work area (without menu-bars, task-bars etc.) + // Based on your use case you may want one of the other. const ImGuiViewport* viewport = ImGui::GetMainViewport(); - ImGui::SetNextWindowPos(viewport->Pos); - ImGui::SetNextWindowSize(viewport->Size); + ImGui::SetNextWindowPos(use_work_area ? viewport->WorkPos : viewport->Pos); + ImGui::SetNextWindowSize(use_work_area ? viewport->WorkSize : viewport->Size); - static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; if (ImGui::Begin("Example: Fullscreen window", p_open, flags)) { + ImGui::Checkbox("Use work area instead of main area", &use_work_area); + ImGui::SameLine(); + HelpMarker("Main Area = entire viewport,\nWork Area = entire viewport minus sections used by the main menu bars, task bars etc.\n\nEnable the main-menu bar in Examples menu to see the difference."); + ImGui::CheckboxFlags("ImGuiWindowFlags_NoBackground", &flags, ImGuiWindowFlags_NoBackground); ImGui::CheckboxFlags("ImGuiWindowFlags_NoDecoration", &flags, ImGuiWindowFlags_NoDecoration); ImGui::Indent(); @@ -7128,6 +7135,9 @@ static void ShowExampleAppFullscreen(bool* p_open) ImGui::CheckboxFlags("ImGuiWindowFlags_NoCollapse", &flags, ImGuiWindowFlags_NoCollapse); ImGui::CheckboxFlags("ImGuiWindowFlags_NoScrollbar", &flags, ImGuiWindowFlags_NoScrollbar); ImGui::Unindent(); + + if (p_open && ImGui::Button("Close this window")) + *p_open = false; } ImGui::End(); } @@ -7141,8 +7151,8 @@ static void ShowExampleAppFullscreen(bool* p_open) // Read FAQ section "How can I have multiple widgets with the same label?" for details. static void ShowExampleAppWindowTitles(bool*) { - ImGuiViewport* viewport = ImGui::GetMainViewport(); - ImVec2 base_pos = viewport->WorkPos; + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + const ImVec2 base_pos = viewport->Pos; // By default, Windows are uniquely identified by their title. // You can use the "##" and "###" markers to manipulate the display/ID. diff --git a/imgui_internal.h b/imgui_internal.h index 2100b1f622a1..dfc1f76c8a7e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1293,8 +1293,6 @@ struct ImGuiDockContext // [SECTION] Viewport support //----------------------------------------------------------------------------- -#ifdef IMGUI_HAS_VIEWPORT - // ImGuiViewport Private/Internals fields (cardinal sin: we are using inheritance!) // Every instance of ImGuiViewport is in fact a ImGuiViewportP. struct ImGuiViewportP : public ImGuiViewport @@ -1329,8 +1327,6 @@ struct ImGuiViewportP : public ImGuiViewport void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; } }; -#endif // #ifdef IMGUI_HAS_VIEWPORT - //----------------------------------------------------------------------------- // [SECTION] Settings support //----------------------------------------------------------------------------- @@ -2790,6 +2786,7 @@ namespace ImGui IMGUI_API void DebugNodeWindowSettings(ImGuiWindowSettings* settings); IMGUI_API void DebugNodeWindowsList(ImVector* windows, const char* label); IMGUI_API void DebugNodeViewport(ImGuiViewportP* viewport); + IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb); } // namespace ImGui