mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-03 22:51:06 +01:00 
			
		
		
		
	Merge branch 'master' into docking
# Conflicts: # imgui.cpp # imgui_internal.h
This commit is contained in:
		
							
								
								
									
										118
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -382,6 +382,7 @@ CODE
 | 
			
		||||
 - 2020/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 - 2020/11/18 (1.80) - renamed undocumented/internals ImGuiColumnsFlags_* to ImGuiOldColumnFlags_* in prevision of incoming Tables API.
 | 
			
		||||
 - 2020/11/03 (1.80) - renamed io.ConfigWindowsMemoryCompactTimer to io.ConfigMemoryCompactTimer as the feature will apply to other data structures
 | 
			
		||||
 - 2020/10/14 (1.80) - backends: moved all backends files (imgui_impl_XXXX.cpp, imgui_impl_XXXX.h) from examples/ to backends/.
 | 
			
		||||
 - 2020/10/12 (1.80) - removed redirecting functions/enums that were marked obsolete in 1.60 (April 2018):
 | 
			
		||||
@@ -1469,7 +1470,7 @@ static const ImU32 GCrc32LookupTable[256] =
 | 
			
		||||
// Known size hash
 | 
			
		||||
// It is ok to call ImHashData on a string with known length but the ### operator won't be supported.
 | 
			
		||||
// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
 | 
			
		||||
ImU32 ImHashData(const void* data_p, size_t data_size, ImU32 seed)
 | 
			
		||||
ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed)
 | 
			
		||||
{
 | 
			
		||||
    ImU32 crc = ~seed;
 | 
			
		||||
    const unsigned char* data = (const unsigned char*)data_p;
 | 
			
		||||
@@ -1485,7 +1486,7 @@ ImU32 ImHashData(const void* data_p, size_t data_size, ImU32 seed)
 | 
			
		||||
// - If we reach ### in the string we discard the hash so far and reset to the seed.
 | 
			
		||||
// - We don't do 'current += 2; continue;' after handling ### to keep the code smaller/faster (measured ~10% diff in Debug build)
 | 
			
		||||
// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
 | 
			
		||||
ImU32 ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
 | 
			
		||||
ImGuiID ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
 | 
			
		||||
{
 | 
			
		||||
    seed = ~seed;
 | 
			
		||||
    ImU32 crc = seed;
 | 
			
		||||
@@ -2224,7 +2225,7 @@ static void SetCursorPosYAndSetupForPrevLine(float pos_y, float line_height)
 | 
			
		||||
    window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y);
 | 
			
		||||
    window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height;  // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
 | 
			
		||||
    window->DC.PrevLineSize.y = (line_height - g.Style.ItemSpacing.y);      // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
 | 
			
		||||
    if (ImGuiColumns* columns = window->DC.CurrentColumns)
 | 
			
		||||
    if (ImGuiOldColumns* columns = window->DC.CurrentColumns)
 | 
			
		||||
        columns->LineMinY = window->DC.CursorPos.y;                         // Setting this so that cell Y position are set properly
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2844,7 +2845,7 @@ ImGuiWindow::~ImGuiWindow()
 | 
			
		||||
    IM_ASSERT(DrawList == &DrawListInst);
 | 
			
		||||
    IM_DELETE(Name);
 | 
			
		||||
    for (int i = 0; i != ColumnsStorage.Size; i++)
 | 
			
		||||
        ColumnsStorage[i].~ImGuiColumns();
 | 
			
		||||
        ColumnsStorage[i].~ImGuiOldColumns();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
 | 
			
		||||
@@ -3544,7 +3545,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
 | 
			
		||||
 | 
			
		||||
        if (root_window != NULL && !is_closed_popup)
 | 
			
		||||
        {
 | 
			
		||||
            StartMouseMovingWindow(g.HoveredWindow);
 | 
			
		||||
            StartMouseMovingWindow(g.HoveredWindow); //-V595
 | 
			
		||||
 | 
			
		||||
            // Cancel moving if clicked outside of title bar
 | 
			
		||||
            if (g.IO.ConfigWindowsMoveFromTitleBarOnly)
 | 
			
		||||
@@ -6651,10 +6652,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
 | 
			
		||||
        {
 | 
			
		||||
            // Child window can be out of sight and have "negative" clip windows.
 | 
			
		||||
            // Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar).
 | 
			
		||||
            IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive));
 | 
			
		||||
            if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
 | 
			
		||||
                if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
 | 
			
		||||
                    window->HiddenFramesCanSkipItems = 1;
 | 
			
		||||
            IM_ASSERT((flags& ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive));
 | 
			
		||||
            if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) // FIXME: Doesn't make sense for ChildWindow??
 | 
			
		||||
                if (!g.LogEnabled)
 | 
			
		||||
                    if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
 | 
			
		||||
                        window->HiddenFramesCanSkipItems = 1;
 | 
			
		||||
 | 
			
		||||
            // Hide along with parent or if parent is collapsed
 | 
			
		||||
            if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0))
 | 
			
		||||
@@ -7045,7 +7047,7 @@ bool ImGui::IsWindowDocked()
 | 
			
		||||
// If you want a window to never be focused, you may use the e.g. NoInputs flag.
 | 
			
		||||
bool ImGui::IsWindowNavFocusable(ImGuiWindow* window)
 | 
			
		||||
{
 | 
			
		||||
    return window->Active && window == window->RootWindowDockStop && !(window->Flags & ImGuiWindowFlags_NoNavFocus);
 | 
			
		||||
    return window->WasActive && window == window->RootWindowDockStop && !(window->Flags & ImGuiWindowFlags_NoNavFocus);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float ImGui::GetWindowWidth()
 | 
			
		||||
@@ -7523,8 +7525,8 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
 | 
			
		||||
    // (IF YOU GET A WARNING OR COMPILE ERROR HERE: it means you assert macro is incorrectly defined!
 | 
			
		||||
    //  If your macro uses multiple statements, it NEEDS to be surrounded by a 'do { ... } while (0)' block.
 | 
			
		||||
    //  This is a common C/C++ idiom to allow multiple statements macros to be used in control flow blocks.)
 | 
			
		||||
    // #define IM_ASSERT(EXPR)   SomeCode(EXPR); SomeMoreCode();                    // Wrong!
 | 
			
		||||
    // #define IM_ASSERT(EXPR)   do { SomeCode(EXPR); SomeMoreCode(); } while (0)   // Correct!
 | 
			
		||||
    // #define IM_ASSERT(EXPR)   if (SomeCode(EXPR)) SomeMoreCode();                    // Wrong!
 | 
			
		||||
    // #define IM_ASSERT(EXPR)   do { if (SomeCode(EXPR)) SomeMoreCode(); } while (0)   // Correct!
 | 
			
		||||
    if (true) IM_ASSERT(1); else IM_ASSERT(0);
 | 
			
		||||
 | 
			
		||||
    // Check user data
 | 
			
		||||
@@ -7533,21 +7535,21 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
 | 
			
		||||
    IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0)              && "Need a positive DeltaTime!");
 | 
			
		||||
    IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount)  && "Forgot to call Render() or EndFrame() at the end of the previous frame?");
 | 
			
		||||
    IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f  && "Invalid DisplaySize value!");
 | 
			
		||||
    IM_ASSERT(g.IO.Fonts->Fonts.Size > 0                                && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
 | 
			
		||||
    IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded()                          && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
 | 
			
		||||
    IM_ASSERT(g.IO.Fonts->Fonts.Size > 0                                && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()?");
 | 
			
		||||
    IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded()                          && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()?");
 | 
			
		||||
    IM_ASSERT(g.Style.CurveTessellationTol > 0.0f                       && "Invalid style setting!");
 | 
			
		||||
    IM_ASSERT(g.Style.CircleSegmentMaxError > 0.0f                      && "Invalid style setting!");
 | 
			
		||||
    IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f            && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)!");
 | 
			
		||||
    IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f            && "Invalid style setting!"); // Allows us to avoid a few clamps in color computations
 | 
			
		||||
    IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting.");
 | 
			
		||||
    IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right);
 | 
			
		||||
    for (int n = 0; n < ImGuiKey_COUNT; n++)
 | 
			
		||||
        IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)");
 | 
			
		||||
 | 
			
		||||
    // Perform simple check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only recently added in 1.60 WIP)
 | 
			
		||||
    // Check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only added in 1.60 WIP)
 | 
			
		||||
    if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard)
 | 
			
		||||
        IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation.");
 | 
			
		||||
 | 
			
		||||
    // Perform simple check: the beta io.ConfigWindowsResizeFromEdges option requires backend to honor mouse cursor changes and set the ImGuiBackendFlags_HasMouseCursors flag accordingly.
 | 
			
		||||
    // Check: the io.ConfigWindowsResizeFromEdges option requires backend to honor mouse cursor changes and set the ImGuiBackendFlags_HasMouseCursors flag accordingly.
 | 
			
		||||
    if (g.IO.ConfigWindowsResizeFromEdges && !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseCursors))
 | 
			
		||||
        g.IO.ConfigWindowsResizeFromEdges = false;
 | 
			
		||||
 | 
			
		||||
@@ -7605,6 +7607,9 @@ static void ImGui::ErrorCheckEndFrameSanityChecks()
 | 
			
		||||
    IM_ASSERT((key_mod_flags == 0 || g.IO.KeyMods == key_mod_flags) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods");
 | 
			
		||||
    IM_UNUSED(key_mod_flags);
 | 
			
		||||
 | 
			
		||||
    // Recover from errors
 | 
			
		||||
    //ErrorCheckEndFrameRecover();
 | 
			
		||||
 | 
			
		||||
    // Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you
 | 
			
		||||
    // to always call End/EndChild even if Begin/BeginChild returns false! (this is unfortunately inconsistent with most other Begin* API).
 | 
			
		||||
    if (g.CurrentWindowStack.Size != 1)
 | 
			
		||||
@@ -7624,6 +7629,80 @@ static void ImGui::ErrorCheckEndFrameSanityChecks()
 | 
			
		||||
    IM_ASSERT_USER_ERROR(g.GroupStack.Size == 0, "Missing EndGroup call!");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Experimental recovery from incorrect usage of BeginXXX/EndXXX/PushXXX/PopXXX calls.
 | 
			
		||||
// Must be called during or before EndFrame().
 | 
			
		||||
// This is generally flawed as we are not necessarily End/Popping things in the right order.
 | 
			
		||||
// FIXME: Can't recover from inside BeginTabItem/EndTabItem yet.
 | 
			
		||||
// FIXME: Can't recover from interleaved BeginTabBar/Begin
 | 
			
		||||
void    ImGui::ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data)
 | 
			
		||||
{
 | 
			
		||||
    // PVS-Studio V1044 is "Loop break conditions do not depend on the number of iterations"
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    while (g.CurrentWindowStack.Size > 0)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef IMGUI_HAS_TABLE
 | 
			
		||||
        while (g.CurrentTable && (g.CurrentTable->OuterWindow == g.CurrentWindow || g.CurrentTable->InnerWindow == g.CurrentWindow))
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing EndTable() in '%s'", g.CurrentTable->OuterWindow->Name);
 | 
			
		||||
            EndTable();
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        ImGuiWindow* window = g.CurrentWindow;
 | 
			
		||||
        IM_ASSERT(window != NULL);
 | 
			
		||||
        while (g.CurrentTabBar != NULL) //-V1044
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing EndTabBar() in '%s'", window->Name);
 | 
			
		||||
            EndTabBar();
 | 
			
		||||
        }
 | 
			
		||||
        while (window->DC.TreeDepth > 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing TreePop() in '%s'", window->Name);
 | 
			
		||||
            TreePop();
 | 
			
		||||
        }
 | 
			
		||||
        while (g.GroupStack.Size > window->DC.StackSizesOnBegin.SizeOfGroupStack)
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing EndGroup() in '%s'", window->Name);
 | 
			
		||||
            EndGroup();
 | 
			
		||||
        }
 | 
			
		||||
        while (window->IDStack.Size > 1)
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing PopID() in '%s'", window->Name);
 | 
			
		||||
            PopID();
 | 
			
		||||
        }
 | 
			
		||||
        while (g.ColorStack.Size > window->DC.StackSizesOnBegin.SizeOfColorStack)
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing PopStyleColor() in '%s' for ImGuiCol_%s", window->Name, GetStyleColorName(g.ColorStack.back().Col));
 | 
			
		||||
            PopStyleColor();
 | 
			
		||||
        }
 | 
			
		||||
        while (g.StyleVarStack.Size > window->DC.StackSizesOnBegin.SizeOfStyleVarStack)
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing PopStyleVar() in '%s'", window->Name);
 | 
			
		||||
            PopStyleVar();
 | 
			
		||||
        }
 | 
			
		||||
        while (g.FocusScopeStack.Size > window->DC.StackSizesOnBegin.SizeOfFocusScopeStack)
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing PopFocusScope() in '%s'", window->Name);
 | 
			
		||||
            PopFocusScope();
 | 
			
		||||
        }
 | 
			
		||||
        if (g.CurrentWindowStack.Size == 1)
 | 
			
		||||
        {
 | 
			
		||||
            IM_ASSERT(g.CurrentWindow->IsFallbackWindow);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        IM_ASSERT(window == g.CurrentWindow);
 | 
			
		||||
        if (window->Flags & ImGuiWindowFlags_ChildWindow)
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing EndChild() for '%s'", window->Name);
 | 
			
		||||
            EndChild();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (log_callback) log_callback(user_data, "Recovered from missing End() for '%s'", window->Name);
 | 
			
		||||
            End();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Save current stack sizes for later compare
 | 
			
		||||
void ImGuiStackSizes::SetToCurrentState()
 | 
			
		||||
{
 | 
			
		||||
@@ -7643,6 +7722,7 @@ void ImGuiStackSizes::CompareWithCurrentState()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    ImGuiWindow* window = g.CurrentWindow;
 | 
			
		||||
    IM_UNUSED(window);
 | 
			
		||||
 | 
			
		||||
    // Window stacks
 | 
			
		||||
    // NOT checking: DC.ItemWidth, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
 | 
			
		||||
@@ -15863,7 +15943,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// [DEBUG] Display contents of Columns
 | 
			
		||||
void ImGui::DebugNodeColumns(ImGuiColumns* columns)
 | 
			
		||||
void ImGui::DebugNodeColumns(ImGuiOldColumns* columns)
 | 
			
		||||
{
 | 
			
		||||
    if (!TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags))
 | 
			
		||||
        return;
 | 
			
		||||
@@ -16212,7 +16292,7 @@ void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* la
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
void ImGui::ShowMetricsWindow(bool*) {}
 | 
			
		||||
void ImGui::DebugNodeColumns(ImGuiColumns*) {}
 | 
			
		||||
void ImGui::DebugNodeColumns(ImGuiOldColumns*) {}
 | 
			
		||||
void ImGui::DebugNodeDrawList(ImGuiWindow*, ImGuiViewportP*, const ImDrawList*, const char*) {}
 | 
			
		||||
void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList*, const ImDrawList*, const ImDrawCmd*, bool, bool) {}
 | 
			
		||||
void ImGui::DebugNodeStorage(ImGuiStorage*, const char*) {}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user