diff --git a/3rdparty/ocornut-imgui/imgui.cpp b/3rdparty/ocornut-imgui/imgui.cpp index 9e207b68..95850723 100644 --- a/3rdparty/ocornut-imgui/imgui.cpp +++ b/3rdparty/ocornut-imgui/imgui.cpp @@ -1,5 +1,5 @@ -// ImGui library v1.47 WIP -// Main code & documentation +// dear imgui, v1.47 WIP +// (main code and documentation) // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. // Newcomers, read 'Programmer guide' below for notes on how to setup ImGui in your codebase. @@ -599,9 +599,7 @@ static void LoadSettings(); static void SaveSettings(); static void MarkSettingsDirty(); -static void PushClipRect(const ImRect& clip_rect, bool clipped_by_current = true); static void PushColumnClipRect(int column_index = -1); -static void PopClipRect(); static ImRect GetVisibleRect(); static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags); @@ -2304,12 +2302,12 @@ static void AddWindowToRenderList(ImVector& out_render_list, ImGuiW } } -static void PushClipRect(const ImRect& clip_rect, bool clipped) +void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect) { - ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindow(); - ImRect cr = clip_rect; - if (clipped) + ImRect cr(clip_rect_min, clip_rect_max); + if (intersect_with_existing_clip_rect) { // Clip our argument with the current clip rect cr.Clip(window->ClipRect); @@ -2322,9 +2320,9 @@ static void PushClipRect(const ImRect& clip_rect, bool clipped) window->DrawList->PushClipRect(ImVec4(cr.Min.x, cr.Min.y, cr.Max.x, cr.Max.y)); } -static void PopClipRect() +void ImGui::PopClipRect() { - ImGuiWindow* window = ImGui::GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindow(); window->DrawList->PopClipRect(); window->ClipRect = window->DrawList->_ClipRectStack.back(); } @@ -2595,10 +2593,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool const int text_len = (int)(text_display_end - text); if (text_len > 0) { - // Render window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); - - // Log as text if (g.LogEnabled) LogRenderedText(pos, text, text_display_end); } @@ -3111,10 +3106,11 @@ static bool IsPopupOpen(ImGuiID id) return opened; } -// Mark popup as open. Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. +// Mark popup as open (toggle toward open state). +// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. // Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). // One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL) -void ImGui::OpenPopup(const char* str_id) +void ImGui::OpenPopupEx(const char* str_id, bool reopen_existing) { ImGuiState& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -3123,13 +3119,18 @@ void ImGui::OpenPopup(const char* str_id) ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here) if (g.OpenedPopupStack.Size < current_stack_size + 1) g.OpenedPopupStack.push_back(popup_ref); - else if (g.OpenedPopupStack[current_stack_size].PopupID != id) + else if (reopen_existing || g.OpenedPopupStack[current_stack_size].PopupID != id) { g.OpenedPopupStack.resize(current_stack_size+1); g.OpenedPopupStack[current_stack_size] = popup_ref; } } +void ImGui::OpenPopup(const char* str_id) +{ + ImGui::OpenPopupEx(str_id, false); +} + static void CloseInactivePopups() { ImGuiState& g = *GImGui; @@ -3201,7 +3202,7 @@ void ImGui::CloseCurrentPopup() ClosePopupToLevel(popup_idx); } -static void ClearSetNextWindowData() +static inline void ClearSetNextWindowData() { ImGuiState& g = *GImGui; g.SetNextWindowPosCond = g.SetNextWindowSizeCond = g.SetNextWindowContentSizeCond = g.SetNextWindowCollapsedCond = g.SetNextWindowFocus = 0; @@ -3276,10 +3277,18 @@ void ImGui::EndPopup() ImGui::PopStyleVar(); } +// This is a helper to handle the most simple case of associating one named popup to one given widget. +// 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling +// this yourself so you can store data relative to the widget that opened the popup instead of choosing different popup identifiers. +// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemHoveredRect() +// and passing true to the OpenPopupEx(). +// Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that +// the item isn't interactable (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu +// driven by click position. bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) { if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(mouse_button)) - ImGui::OpenPopup(str_id); + ImGui::OpenPopupEx(str_id, false); return ImGui::BeginPopup(str_id); } @@ -3288,7 +3297,7 @@ bool ImGui::BeginPopupContextWindow(bool also_over_items, const char* str_id, in if (!str_id) str_id = "window_context_menu"; if (ImGui::IsMouseHoveringWindow() && ImGui::IsMouseClicked(mouse_button)) if (also_over_items || !ImGui::IsAnyItemHovered()) - ImGui::OpenPopup(str_id); + ImGui::OpenPopupEx(str_id, true); return ImGui::BeginPopup(str_id); } @@ -3296,7 +3305,7 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) { if (!str_id) str_id = "void_context_menu"; if (!ImGui::IsMouseHoveringAnyWindow() && ImGui::IsMouseClicked(mouse_button)) - ImGui::OpenPopup(str_id); + ImGui::OpenPopupEx(str_id, true); return ImGui::BeginPopup(str_id); } @@ -3407,9 +3416,10 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, { const ImGuiStyle& style = GImGui->Style; - // Clamp into visible area while not overlapping the cursor + // Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it. + ImVec2 safe_padding = style.DisplaySafeAreaPadding; ImRect r_outer(GetVisibleRect()); - r_outer.Reduce(style.DisplaySafeAreaPadding); + r_outer.Reduce(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? safe_padding.y : 0.0f)); ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size); for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Right, down, up, left. Favor last used direction. @@ -3504,7 +3514,10 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0); } - g.Windows.push_back(window); + if (flags & ImGuiWindowFlags_NoBringToFrontOnFocus) + g.Windows.insert(g.Windows.begin(), window); // Quite slow but rare and only once + else + g.Windows.push_back(window); return window; } @@ -3643,10 +3656,13 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ // Setup texture, outer clipping rectangle window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_ComboBox|ImGuiWindowFlags_Popup))) - PushClipRect(parent_window->ClipRect); - else - PushClipRect(GetVisibleRect()); + { + ImRect fullscreen_rect(GetVisibleRect()); + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_ComboBox|ImGuiWindowFlags_Popup))) + PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); + else + PushClipRect(fullscreen_rect.Min, fullscreen_rect.Max, true); + } // New windows appears in front if (!window_was_active) @@ -3712,7 +3728,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ } else { - size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - window->WindowPadding)); + size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); // Handling case of auto fit window not fitting in screen on one axis, we are growing auto fit size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. if (size_auto_fit.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) @@ -3868,7 +3884,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ // Modal window darkens what is behind them if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) { - ImRect fullscreen_rect = GetVisibleRect(); + ImRect fullscreen_rect(GetVisibleRect()); window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); } @@ -4060,7 +4076,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ clip_rect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, window->WindowPadding.x*0.5f); clip_rect.Max.y = window->Pos.y + window->Size.y - border_size - window->ScrollbarSizes.y; - PushClipRect(clip_rect); + PushClipRect(clip_rect.Min, clip_rect.Max, true); // Clear 'accessed' flag last thing if (first_begin_of_the_frame) @@ -8315,7 +8331,7 @@ bool ImGui::BeginMenuBar() ImGui::PushID("##menubar"); ImRect rect = window->MenuBarRect(); float border_size = (window->Flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f; - PushClipRect(ImVec4(rect.Min.x+0.5f, rect.Min.y-0.5f+border_size, rect.Max.x+0.5f, rect.Max.y-0.5f), false); + PushClipRect(ImVec2(rect.Min.x+0.5f, rect.Min.y-0.5f+border_size), ImVec2(rect.Max.x+0.5f, rect.Max.y-0.5f), false); window->DC.CursorPos = ImVec2(rect.Min.x + window->DC.MenuBarOffsetX, rect.Min.y);// + g.Style.FramePadding.y); window->DC.LayoutType = ImGuiLayoutType_Horizontal; window->DC.MenuBarAppending = true; @@ -8891,7 +8907,7 @@ static void PushColumnClipRect(int column_index) const float x1 = window->Pos.x + ImGui::GetColumnOffset(column_index) - 1; const float x2 = window->Pos.x + ImGui::GetColumnOffset(column_index+1) - 1; - PushClipRect(ImVec4(x1,-FLT_MAX,x2,+FLT_MAX)); + ImGui::PushClipRect(ImVec2(x1,-FLT_MAX), ImVec2(x2,+FLT_MAX), true); } void ImGui::Columns(int columns_count, const char* id, bool border) @@ -9225,7 +9241,7 @@ void ImGui::ShowMetricsWindow(bool* opened) ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); continue; } - ImGui::BulletText("Draw %d %s vtx, tex = %p, clip_rect = (%.0f,%.0f)..(%.0f,%.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); + ImGui::BulletText("Draw %-4d %s vtx, tex = %p, clip_rect = (%.0f,%.0f)..(%.0f,%.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); if (show_clip_rects && ImGui::IsItemHovered()) { ImRect clip_rect = pcmd->ClipRect; @@ -9297,8 +9313,8 @@ void ImGui::ShowMetricsWindow(bool* opened) //----------------------------------------------------------------------------- -//---- Include imgui_user.inl at the end of imgui.cpp -//---- So you can include code that extends ImGui using its private data/functions. +// Include imgui_user.inl at the end of imgui.cpp to access private data/functions that aren't exposed. +// Prefer just including imgui_internal.h from your code rather than using this define. If a declaration is missing from imgui_internal.h add it or request it on the github. #ifdef IMGUI_INCLUDE_IMGUI_USER_INL #include "imgui_user.inl" #endif diff --git a/3rdparty/ocornut-imgui/imgui.h b/3rdparty/ocornut-imgui/imgui.h index 62ccd433..f8ff68a9 100644 --- a/3rdparty/ocornut-imgui/imgui.h +++ b/3rdparty/ocornut-imgui/imgui.h @@ -1,5 +1,5 @@ -// ImGui library v1.47 WIP -// Headers +// dear imgui, v1.47 WIP +// (headers) // See imgui.cpp file for documentation. // See ImGui::ShowTestWindow() in imgui_demo.cpp for demo code. @@ -219,7 +219,7 @@ namespace ImGui // ID scopes // If you are creating widgets in a loop you most likely want to push a unique identifier so ImGui can differentiate them. - // You can also use "##extra" within your widget name to distinguish them from each others. Read the FAQ for more details. + // You can also use the "##foobar" syntax within widget label to distinguish them from each others. Read "A primer on the use of labels/IDs" in the FAQ for more details. IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the *entire* stack! IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); IMGUI_API void PushID(const void* ptr_id); @@ -352,9 +352,9 @@ namespace ImGui IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API bool BeginPopup(const char* str_id); // return true if popup if opened and start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopupModal(const char* name, bool* p_opened = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (can't close them by clicking outside) - IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item - IMGUI_API bool BeginPopupContextWindow(bool also_over_items = true, const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on current window - IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window) + IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp! + IMGUI_API bool BeginPopupContextWindow(bool also_over_items = true, const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on current window. + IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window). IMGUI_API void EndPopup(); IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. @@ -368,7 +368,7 @@ namespace ImGui // Utilities IMGUI_API bool IsItemHovered(); // was the last item hovered by mouse? - IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active while we are hovering this + IMGUI_API bool IsItemHoveredRect(); // was the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this IMGUI_API bool IsItemActive(); // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) IMGUI_API bool IsItemVisible(); // was the last item visible? (aka not out of sight due to clipping/scrolling.) IMGUI_API bool IsAnyItemHovered(); diff --git a/3rdparty/ocornut-imgui/imgui_demo.cpp b/3rdparty/ocornut-imgui/imgui_demo.cpp index ba271e31..743c05b5 100644 --- a/3rdparty/ocornut-imgui/imgui_demo.cpp +++ b/3rdparty/ocornut-imgui/imgui_demo.cpp @@ -1,5 +1,5 @@ -// ImGui library v1.47 WIP -// Demo code +// dear imgui, v1.47 WIP +// (demo code) // Don't remove this file from your project! It is useful reference code that you can execute. // You can call ImGui::ShowTestWindow() in your code to learn about various features of ImGui. @@ -125,7 +125,7 @@ void ImGui::ShowTestWindow(bool* p_opened) if (show_app_about) { ImGui::Begin("About ImGui", &show_app_about, ImGuiWindowFlags_AlwaysAutoResize); - ImGui::Text("ImGui %s", ImGui::GetVersion()); + ImGui::Text("dear imgui, %s", ImGui::GetVersion()); ImGui::Separator(); ImGui::Text("By Omar Cornut and all github contributors."); ImGui::Text("ImGui is licensed under the MIT License, see LICENSE for more information."); @@ -160,7 +160,7 @@ void ImGui::ShowTestWindow(bool* p_opened) //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); // 2/3 of the space for widget and 1/3 for labels ImGui::PushItemWidth(-140); // Right align, keep 140 pixels for labels - ImGui::Text("ImGui says hello."); + ImGui::Text("Dear ImGui says hello."); // Menu if (ImGui::BeginMenuBar()) diff --git a/3rdparty/ocornut-imgui/imgui_draw.cpp b/3rdparty/ocornut-imgui/imgui_draw.cpp index fd09f864..fb4faef1 100644 --- a/3rdparty/ocornut-imgui/imgui_draw.cpp +++ b/3rdparty/ocornut-imgui/imgui_draw.cpp @@ -1,5 +1,5 @@ -// ImGui library v1.47 WIP -// Drawing and font code +// dear imgui, v1.47 WIP +// (drawing and font code) // Contains implementation for // - ImDrawList @@ -94,7 +94,7 @@ using namespace IMGUI_STB_NAMESPACE; // ImDrawList //----------------------------------------------------------------------------- -static ImVec4 GNullClipRect(-8192.0f, -8192.0f, +8192.0f, +8192.0f); // Large values that are easy to encode in a few bits+shift +static const ImVec4 GNullClipRect(-8192.0f, -8192.0f, +8192.0f, +8192.0f); // Large values that are easy to encode in a few bits+shift void ImDrawList::Clear() { @@ -134,11 +134,15 @@ void ImDrawList::ClearFreeMemory() _Channels.clear(); } +// Use macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug mode +#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : GNullClipRect) +#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL) + void ImDrawList::AddDrawCmd() { ImDrawCmd draw_cmd; - draw_cmd.ClipRect = _ClipRectStack.Size ? _ClipRectStack.back() : GNullClipRect; - draw_cmd.TextureId = _TextureIdStack.Size ? _TextureIdStack.back() : NULL; + draw_cmd.ClipRect = GetCurrentClipRect(); + draw_cmd.TextureId = GetCurrentTextureId(); draw_cmd.ViewId = (unsigned char)(GImGui->Style.ViewId); IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w); @@ -156,27 +160,52 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) current_cmd->UserCallback = callback; current_cmd->UserCallbackData = callback_data; - // Force a new command after us (we function this way so that the most common calls AddLine, AddRect, etc. always have a command to add to without doing any check). - AddDrawCmd(); + AddDrawCmd(); // Force a new command after us (see comment below) } +// Our scheme may appears a bit unusual, basically we want the most-common calls AddLine AddRect etc. to not have to perform any check so we always have a command ready in the stack. +// The cost of figuring out if a new command has to be added or if we can merge is paid in those Update** functions only. void ImDrawList::UpdateClipRect() { - ImDrawCmd* current_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; - if (!current_cmd || (current_cmd->ElemCount != 0) || current_cmd->UserCallback != NULL) + // If current command is used with different settings we need to add a new command + const ImVec4 curr_clip_rect = GetCurrentClipRect(); + ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size-1] : NULL; + if (!curr_cmd || (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) != 0) || curr_cmd->UserCallback != NULL) { AddDrawCmd(); + return; } + + // Try to merge with previous command if it matches, else use current command + ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; + if (prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL) + CmdBuffer.pop_back(); else - { - ImVec4 current_clip_rect = _ClipRectStack.Size ? _ClipRectStack.back() : GNullClipRect; - if (CmdBuffer.Size >= 2 && ImLengthSqr(CmdBuffer.Data[CmdBuffer.Size-2].ClipRect - current_clip_rect) < 0.00001f) - CmdBuffer.pop_back(); - else - current_cmd->ClipRect = current_clip_rect; - } + curr_cmd->ClipRect = curr_clip_rect; } +void ImDrawList::UpdateTextureID() +{ + // If current command is used with different settings we need to add a new command + const ImTextureID curr_texture_id = GetCurrentTextureId(); + ImDrawCmd* curr_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; + if (!curr_cmd || (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != curr_texture_id) || curr_cmd->UserCallback != NULL) + { + AddDrawCmd(); + return; + } + + // Try to merge with previous command if it matches, else use current command + ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; + if (prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL) + CmdBuffer.pop_back(); + else + curr_cmd->TextureId = curr_texture_id; +} + +#undef GetCurrentClipRect +#undef GetCurrentTextureId + // Scissoring. The values in clip_rect are x1, y1, x2, y2. void ImDrawList::PushClipRect(const ImVec4& clip_rect) { @@ -200,16 +229,6 @@ void ImDrawList::PopClipRect() UpdateClipRect(); } -void ImDrawList::UpdateTextureID() -{ - ImDrawCmd* current_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; - const ImTextureID texture_id = _TextureIdStack.Size ? _TextureIdStack.back() : NULL; - if (!current_cmd || (current_cmd->ElemCount != 0 && current_cmd->TextureId != texture_id) || current_cmd->UserCallback != NULL) - AddDrawCmd(); - else - current_cmd->TextureId = texture_id; -} - void ImDrawList::PushTextureID(const ImTextureID& texture_id) { _TextureIdStack.push_back(texture_id); diff --git a/3rdparty/ocornut-imgui/imgui_internal.h b/3rdparty/ocornut-imgui/imgui_internal.h index ebb3db8c..e1a5244b 100644 --- a/3rdparty/ocornut-imgui/imgui_internal.h +++ b/3rdparty/ocornut-imgui/imgui_internal.h @@ -1,7 +1,7 @@ -// ImGui library v1.47 WIP -// Internals -// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! +// dear imgui, v1.47 WIP +// (internals) +// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // Implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators) // #define IMGUI_DEFINE_MATH_OPERATORS @@ -512,8 +512,8 @@ struct IMGUI_API ImGuiDrawContext int TreeDepth; ImGuiID LastItemID; ImRect LastItemRect; - bool LastItemHoveredAndUsable; - bool LastItemHoveredRect; + bool LastItemHoveredAndUsable; // Item rectangle is hovered, and its window is currently interactable with (not blocked by a popup preventing access to the window) + bool LastItemHoveredRect; // Item rectangle is hovered, but its window may or not be currently interactable with (might be blocked by a popup preventing access to the window) bool MenuBarAppending; float MenuBarOffsetX; ImVector ChildWindows; @@ -683,10 +683,13 @@ namespace ImGui IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API void SetItemAllowOverlap(); // Allow last item to be overlapped by a subsequent item + IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); + inline IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul) { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * alpha_mul; return ImGui::ColorConvertFloat4ToU32(c); } inline IMGUI_API ImU32 GetColorU32(const ImVec4& col) { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); } // NB: All position are in absolute pixels coordinates (not window coordinates) + // FIXME: Refactor all RenderText* functions into one. IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL); @@ -694,6 +697,9 @@ namespace ImGui IMGUI_API void RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale = 1.0f, bool shadow = false); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); + IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_existing_clip_rect = true); + IMGUI_API void PopClipRect(); + IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0); diff --git a/3rdparty/remotery/lib/Remotery.c b/3rdparty/remotery/lib/Remotery.c index d4e844bc..d8af75bb 100644 --- a/3rdparty/remotery/lib/Remotery.c +++ b/3rdparty/remotery/lib/Remotery.c @@ -189,7 +189,7 @@ void* rmtLoadLibrary(const char* path) static void rmtFreeLibrary(void* handle) { #if defined(RMT_PLATFORM_WINDOWS) - FreeLibrary(handle); + FreeLibrary((HMODULE)handle); #elif defined(RMT_PLATFORM_POSIX) dlclose(handle); #endif