From fe09ebbe0a1c8bb5f39f326658faa6bde75bb568 Mon Sep 17 00:00:00 2001 From: Cyao <94928179+cheyao@users.noreply.github.com> Date: Mon, 22 Jul 2024 21:10:35 +0200 Subject: [PATCH 01/15] Backends: OpenGL3: Fixed unsupported option warning with apple clang (#7810) --- backends/imgui_impl_opengl3.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp index bbe96c420..7087a7c57 100644 --- a/backends/imgui_impl_opengl3.cpp +++ b/backends/imgui_impl_opengl3.cpp @@ -124,6 +124,7 @@ // Clang/GCC warnings with -Weverything #if defined(__clang__) #pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: ignore unknown flags #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness #pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used From 4d8c56c8133511b467bcba6483bc75b5a63ab985 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Jul 2024 13:40:23 +0200 Subject: [PATCH 02/15] Internals, TreeNode: indent all render block into its own scope (aim is to add a is_visible test there later) --- imgui.cpp | 1 + imgui_widgets.cpp | 99 ++++++++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c7b83d849..52fa2f16f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12048,6 +12048,7 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM { ImGuiContext& g = *GImGui; IM_ASSERT(g.NavWindow != NULL); + //IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestSubmit: dir %c, window \"%s\"\n", "-WENS"[move_dir + 1], g.NavWindow->Name); if (move_flags & ImGuiNavMoveFlags_IsTabbing) move_flags |= ImGuiNavMoveFlags_AllowCurrentNavId; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 9a63a59bf..70ff174c2 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6410,6 +6410,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags if ((flags & (ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanTextWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0) interact_bb.Max.x = frame_bb.Min.x + text_width + (label_size.x > 0.0f ? style.ItemSpacing.x * 2.0f : 0.0f); + // Compute open and multi-select states before ItemAdd() as it clear NextItem data. + bool is_open = TreeNodeUpdateNextOpen(storage_id, flags); + // Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable.. const float backup_clip_rect_min_x = window->ClipRect.Min.x; const float backup_clip_rect_max_x = window->ClipRect.Max.x; @@ -6418,18 +6421,14 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags window->ClipRect.Min.x = window->ParentWorkRect.Min.x; window->ClipRect.Max.x = window->ParentWorkRect.Max.x; } - - // Compute open and multi-select states before ItemAdd() as it clear NextItem data. - bool is_open = TreeNodeUpdateNextOpen(storage_id, flags); - bool item_add = ItemAdd(interact_bb, id); - g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDisplayRect; - g.LastItemData.DisplayRect = frame_bb; - + const bool is_visible = ItemAdd(interact_bb, id); if (span_all_columns) { window->ClipRect.Min.x = backup_clip_rect_min_x; window->ClipRect.Max.x = backup_clip_rect_max_x; } + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDisplayRect; + g.LastItemData.DisplayRect = frame_bb; // If a NavLeft request is happening and ImGuiTreeNodeFlags_NavLeftJumpsBackHere enabled: // Store data for the current depth to allow returning to this node from any child item. @@ -6444,7 +6443,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags } const bool is_leaf = (flags & ImGuiTreeNodeFlags_Leaf) != 0; - if (!item_add) + if (!is_visible) { if (store_tree_node_stack_data && is_open) TreeNodeStoreStackData(flags); // Call before TreePushOverrideID() @@ -6566,53 +6565,55 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection; // Render - const ImU32 text_col = GetColorU32(ImGuiCol_Text); - ImGuiNavHighlightFlags nav_highlight_flags = ImGuiNavHighlightFlags_Compact; - if (is_multi_select) - nav_highlight_flags |= ImGuiNavHighlightFlags_AlwaysDraw; // Always show the nav rectangle - if (display_frame) { - // Framed type - const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); - RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, true, style.FrameRounding); - RenderNavHighlight(frame_bb, id, nav_highlight_flags); - if (flags & ImGuiTreeNodeFlags_Bullet) - RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.60f, text_pos.y + g.FontSize * 0.5f), text_col); - else if (!is_leaf) - RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 1.0f); - else // Leaf without bullet, left-adjusted text - text_pos.x -= text_offset_x -padding.x; - if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton) - frame_bb.Max.x -= g.FontSize + style.FramePadding.x; - if (g.LogEnabled) - LogSetNextTextDecoration("###", "###"); - } - else - { - // Unframed typed for tree nodes - if (hovered || selected) + const ImU32 text_col = GetColorU32(ImGuiCol_Text); + ImGuiNavHighlightFlags nav_highlight_flags = ImGuiNavHighlightFlags_Compact; + if (is_multi_select) + nav_highlight_flags |= ImGuiNavHighlightFlags_AlwaysDraw; // Always show the nav rectangle + if (display_frame) { + // Framed type const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); - RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, false); + RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, true, style.FrameRounding); + RenderNavHighlight(frame_bb, id, nav_highlight_flags); + if (flags & ImGuiTreeNodeFlags_Bullet) + RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.60f, text_pos.y + g.FontSize * 0.5f), text_col); + else if (!is_leaf) + RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 1.0f); + else // Leaf without bullet, left-adjusted text + text_pos.x -= text_offset_x - padding.x; + if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton) + frame_bb.Max.x -= g.FontSize + style.FramePadding.x; + if (g.LogEnabled) + LogSetNextTextDecoration("###", "###"); } - RenderNavHighlight(frame_bb, id, nav_highlight_flags); - if (flags & ImGuiTreeNodeFlags_Bullet) - RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.5f, text_pos.y + g.FontSize * 0.5f), text_col); - else if (!is_leaf) - RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 0.70f); - if (g.LogEnabled) - LogSetNextTextDecoration(">", NULL); + else + { + // Unframed typed for tree nodes + if (hovered || selected) + { + const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, false); + } + RenderNavHighlight(frame_bb, id, nav_highlight_flags); + if (flags & ImGuiTreeNodeFlags_Bullet) + RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.5f, text_pos.y + g.FontSize * 0.5f), text_col); + else if (!is_leaf) + RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 0.70f); + if (g.LogEnabled) + LogSetNextTextDecoration(">", NULL); + } + + if (span_all_columns) + TablePopBackgroundChannel(); + + // Label + if (display_frame) + RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size); + else + RenderText(text_pos, label, label_end, false); } - if (span_all_columns) - TablePopBackgroundChannel(); - - // Label - if (display_frame) - RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size); - else - RenderText(text_pos, label, label_end, false); - if (store_tree_node_stack_data && is_open) TreeNodeStoreStackData(flags); // Call before TreePushOverrideID() if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) From 1230b4410cd0e0111dd85f7c20e2606208dc1a99 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Jul 2024 14:11:26 +0200 Subject: [PATCH 03/15] Internals, TreeNode, Selectable: tweak span_all_columns paths for clarity. --- imgui_widgets.cpp | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 70ff174c2..c01a89460 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6413,20 +6413,22 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags // Compute open and multi-select states before ItemAdd() as it clear NextItem data. bool is_open = TreeNodeUpdateNextOpen(storage_id, flags); - // Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable.. - const float backup_clip_rect_min_x = window->ClipRect.Min.x; - const float backup_clip_rect_max_x = window->ClipRect.Max.x; + bool is_visible; if (span_all_columns) { + // Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable.. + const float backup_clip_rect_min_x = window->ClipRect.Min.x; + const float backup_clip_rect_max_x = window->ClipRect.Max.x; window->ClipRect.Min.x = window->ParentWorkRect.Min.x; window->ClipRect.Max.x = window->ParentWorkRect.Max.x; - } - const bool is_visible = ItemAdd(interact_bb, id); - if (span_all_columns) - { + is_visible = ItemAdd(interact_bb, id); window->ClipRect.Min.x = backup_clip_rect_min_x; window->ClipRect.Max.x = backup_clip_rect_max_x; } + else + { + is_visible = ItemAdd(interact_bb, id); + } g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDisplayRect; g.LastItemData.DisplayRect = frame_bb; @@ -6796,23 +6798,24 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl } //if (g.IO.KeyCtrl) { GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(0, 255, 0, 255)); } - // Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable.. - const float backup_clip_rect_min_x = window->ClipRect.Min.x; - const float backup_clip_rect_max_x = window->ClipRect.Max.x; + const bool disabled_item = (flags & ImGuiSelectableFlags_Disabled) != 0; + const ImGuiItemFlags extra_item_flags = disabled_item ? (ImGuiItemFlags)ImGuiItemFlags_Disabled : ImGuiItemFlags_None; + bool is_visible; if (span_all_columns) { + // Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable.. + const float backup_clip_rect_min_x = window->ClipRect.Min.x; + const float backup_clip_rect_max_x = window->ClipRect.Max.x; window->ClipRect.Min.x = window->ParentWorkRect.Min.x; window->ClipRect.Max.x = window->ParentWorkRect.Max.x; - } - - const bool disabled_item = (flags & ImGuiSelectableFlags_Disabled) != 0; - const bool is_visible = ItemAdd(bb, id, NULL, disabled_item ? (ImGuiItemFlags)ImGuiItemFlags_Disabled : ImGuiItemFlags_None); - - if (span_all_columns) - { + is_visible = ItemAdd(bb, id, NULL, extra_item_flags); window->ClipRect.Min.x = backup_clip_rect_min_x; window->ClipRect.Max.x = backup_clip_rect_max_x; } + else + { + is_visible = ItemAdd(bb, id, NULL, extra_item_flags); + } const bool is_multi_select = (g.LastItemData.InFlags & ImGuiItemFlags_IsMultiSelect) != 0; if (!is_visible) From 97c6f4047ccc01367e29f6852e9cecf1e157d26b Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Jul 2024 14:16:41 +0200 Subject: [PATCH 04/15] CollapsingHeader: left-side outer extend matches right-side one (moved left by one pixel) Amend c3a348aa2 --- imgui_widgets.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index c01a89460..068337e9c 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6396,10 +6396,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags frame_bb.Max.y = window->DC.CursorPos.y + frame_height; if (display_frame) { - // Framed header expand a little outside the default padding, to the edge of InnerClipRect - // (FIXME: May remove this at some point and make InnerClipRect align with WindowPadding.x instead of WindowPadding.x*0.5f) - frame_bb.Min.x -= IM_TRUNC(window->WindowPadding.x * 0.5f - 1.0f); - frame_bb.Max.x += IM_TRUNC(window->WindowPadding.x * 0.5f); + const float outer_extend = IM_TRUNC(window->WindowPadding.x * 0.5f); // Framed header expand a little outside of current limits + frame_bb.Min.x -= outer_extend; + frame_bb.Max.x += outer_extend; } ImVec2 text_pos(window->DC.CursorPos.x + text_offset_x, window->DC.CursorPos.y + text_offset_y); @@ -6783,7 +6782,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl const ImVec2 text_max(min_x + size.x, pos.y + size.y); // Selectables are meant to be tightly packed together with no click-gap, so we extend their box to cover spacing between selectable. - // FIXME: Not part of layout so not included in clipper calculation, but ItemSize currenty doesn't allow offsetting CursorPos. + // FIXME: Not part of layout so not included in clipper calculation, but ItemSize currently doesn't allow offsetting CursorPos. ImRect bb(min_x, pos.y, text_max.x, text_max.y); if ((flags & ImGuiSelectableFlags_NoPadWithHalfSpacing) == 0) { From b67b375ae693072ba23963f7897057e76f3a7327 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Jul 2024 15:28:03 +0200 Subject: [PATCH 05/15] Debug Log: fixed incorrect checkbox layout when partially clipped., doesn't parse 64-bits hex value as ImGuiID lookups. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 4 ++-- imgui_internal.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 150c2b609..1247ef94a 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -147,6 +147,7 @@ Other changes: Debug log entries add a imgui frame counter prefix + are redirected to ShowDebugLogWindow() and other configurable locations. Always call IMGUI_DEBUG_LOG() for maximum stripping in caller code. - Debug Tools: Debug Log: Added "Configure Outputs.." button. (#5855) +- Debug Tools: Debug Log: Fixed incorrect checkbox layout when partially clipped. - Demo: Reworked "Property Editor" demo in a manner that more ressemble the tree data and struct description data that a real application would want to use. - Backends: Win32: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. diff --git a/imgui.cpp b/imgui.cpp index 52fa2f16f..7b922fdd7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -15827,7 +15827,7 @@ static void SameLineOrWrap(const ImVec2& size) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; ImVec2 pos(window->DC.CursorPosPrevLine.x + g.Style.ItemSpacing.x, window->DC.CursorPosPrevLine.y); - if (window->ClipRect.Contains(ImRect(pos, pos + size))) + if (window->WorkRect.Contains(ImRect(pos, pos + size))) ImGui::SameLine(); } @@ -15921,7 +15921,7 @@ void ImGui::DebugTextUnformattedWithLocateItem(const char* line_begin, const cha for (const char* p = line_begin; p <= line_end - 10; p++) { ImGuiID id = 0; - if (p[0] != '0' || (p[1] != 'x' && p[1] != 'X') || sscanf(p + 2, "%X", &id) != 1) + if (p[0] != '0' || (p[1] != 'x' && p[1] != 'X') || sscanf(p + 2, "%X", &id) != 1 || ImCharIsXdigitA(p[10])) continue; ImVec2 p0 = CalcTextSize(line_begin, p); ImVec2 p1 = CalcTextSize(p, p + 10); diff --git a/imgui_internal.h b/imgui_internal.h index f2c5312ea..b307adcde 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -388,6 +388,7 @@ IM_MSVC_RUNTIME_CHECKS_OFF static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; } static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; } static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } +static inline bool ImCharIsXdigitA(char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); } IM_MSVC_RUNTIME_CHECKS_RESTORE // Helpers: Formatting From e3da939b86f8cbf30a4d3e39b0cab2413c67dd03 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Jul 2024 18:41:51 +0200 Subject: [PATCH 06/15] Groups, Tables: fixed EndGroup() failing to correctly capture current table occupied size. (#7543) See "layout_group_endtable" test. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 8 ++++---- imgui.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 1247ef94a..fde5c5144 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -140,6 +140,7 @@ Other changes: can use the clipper without knowing the amount of items beforehand. (#1311) In this situation, call ImGuiListClipper::SeekCursorForItem(items_count) as the end of your iteration loop to position the layout cursor correctly. This is done automatically if provided a count to Begin(). +- Groups, Tables: fixed EndGroup() failing to correctly capture current table occupied size. (#7543) - TabBar, Style: added style.TabBarOverlineSize / ImGuiStyleVar_TabBarOverlineSize to manipulate thickness of the horizontal line over selectable tabs. [@DctrNoob] - Style: close button and collapse/window-menu button hover highlight made rectangular instead of round. diff --git a/imgui.cpp b/imgui.cpp index 7b922fdd7..31f65a9d4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10686,11 +10686,11 @@ void ImGui::EndGroup() if (window->DC.IsSetPos) ErrorCheckUsingSetCursorPosToExtendParentBoundaries(); - ImRect group_bb(group_data.BackupCursorPos, ImMax(window->DC.CursorMaxPos, group_data.BackupCursorPos)); - + // Include LastItemData.Rect.Max as a workaround for e.g. EndTable() undershooting with CursorMaxPos report. (#7543) + ImRect group_bb(group_data.BackupCursorPos, ImMax(ImMax(window->DC.CursorMaxPos, g.LastItemData.Rect.Max), group_data.BackupCursorPos)); window->DC.CursorPos = group_data.BackupCursorPos; window->DC.CursorPosPrevLine = group_data.BackupCursorPosPrevLine; - window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); + window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, group_bb.Max); window->DC.Indent = group_data.BackupIndent; window->DC.GroupOffset = group_data.BackupGroupOffset; window->DC.CurrLineSize = group_data.BackupCurrLineSize; @@ -10705,7 +10705,7 @@ void ImGui::EndGroup() return; } - window->DC.CurrLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now. + window->DC.CurrLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now. ItemSize(group_bb.GetSize()); ItemAdd(group_bb, 0, NULL, ImGuiItemFlags_NoTabStop); diff --git a/imgui.h b/imgui.h index fd0768a22..47626ad6f 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.91.0 WIP" -#define IMGUI_VERSION_NUM 19098 +#define IMGUI_VERSION_NUM 19099 #define IMGUI_HAS_TABLE /* From 79b77d91c98e36c1dd487516564cec716ddd94f1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Jul 2024 18:43:54 +0200 Subject: [PATCH 07/15] MultiSelect: sequential SetRange merging not generally handled by box-select path, useful for others. --- imgui_internal.h | 3 ++- imgui_widgets.cpp | 35 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index b307adcde..85aaa19bc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1751,6 +1751,7 @@ struct IMGUI_API ImGuiMultiSelectTempData ImGuiMultiSelectFlags Flags; ImVec2 ScopeRectMin; ImVec2 BackupCursorMaxPos; + ImGuiSelectionUserData LastSubmittedItem; // Copy of last submitted item data, used to merge output ranges. ImGuiID BoxSelectId; ImGuiKeyChord KeyMods; ImS8 LoopRequestSetAll; // -1: no operation, 0: clear all, 1: select all. @@ -1760,7 +1761,6 @@ struct IMGUI_API ImGuiMultiSelectTempData bool NavIdPassedBy; bool RangeSrcPassedBy; // Set by the item that matches RangeSrcItem. bool RangeDstPassedBy; // Set by the item that matches NavJustMovedToId when IsSetRange is set. - ImGuiSelectionUserData BoxSelectLastitem; // Copy of last submitted item data, used to merge output ranges. ImGuiMultiSelectTempData() { Clear(); } void Clear() { size_t io_sz = sizeof(IO); ClearIO(); memset((void*)(&IO + 1), 0, sizeof(*this) - io_sz); } // Zero-clear except IO as we preserve IO.Requests[] buffer allocation. @@ -3408,6 +3408,7 @@ namespace ImGui // Multi-Select API IMGUI_API void MultiSelectItemHeader(ImGuiID id, bool* p_selected, ImGuiButtonFlags* p_button_flags); IMGUI_API void MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed); + IMGUI_API void MultiSelectAddSetRange(ImGuiMultiSelectTempData* ms, bool selected, int range_dir, ImGuiSelectionUserData first_item, ImGuiSelectionUserData last_item); inline ImGuiBoxSelectState* GetBoxSelectState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.BoxSelectState.ID == id && g.BoxSelectState.IsActive) ? &g.BoxSelectState : NULL; } inline ImGuiMultiSelectState* GetMultiSelectState(ImGuiID id) { ImGuiContext& g = *GImGui; return g.MultiSelectStorage.GetByKey(id); } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 068337e9c..183c7fbe2 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7069,7 +7069,7 @@ static int ImStrimatchlen(const char* s1, const char* s1_end, const char* s2) // When SingleCharMode is set: // - it is better to NOT display a tooltip of other on-screen display indicator. // - the index of the currently focused item is required. -// if your SetNextItemSelectionData() values are indices, you can obtain it from ImGuiMultiSelectIO::NavIdItem, otherwise from g.NavLastValidSelectionUserData. +// if your SetNextItemSelectionUserData() values are indices, you can obtain it from ImGuiMultiSelectIO::NavIdItem, otherwise from g.NavLastValidSelectionUserData. int ImGui::TypingSelectFindMatch(ImGuiTypingSelectRequest* req, int items_count, const char* (*get_item_name_func)(void*, int), void* user_data, int nav_item_idx) { if (req == NULL || req->SelectRequest == false) // Support NULL parameter so both calls can be done from same spot. @@ -7397,7 +7397,6 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel if (flags & (ImGuiMultiSelectFlags_BoxSelect1d | ImGuiMultiSelectFlags_BoxSelect2d)) { ms->BoxSelectId = GetID("##BoxSelect"); - ms->BoxSelectLastitem = ImGuiSelectionUserData_Invalid; if (BeginBoxSelect(window, ms->BoxSelectId, flags)) request_clear |= bs->RequestClear; } @@ -7432,6 +7431,7 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel ms->IO.Requests.push_back(req); } ms->LoopRequestSetAll = request_select_all ? 1 : request_clear ? 0 : -1; + ms->LastSubmittedItem = ImGuiSelectionUserData_Invalid; if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection) DebugLogMultiSelectRequests("BeginMultiSelect", &ms->IO); @@ -7694,17 +7694,10 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) else { selected = !selected; - ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetRange, selected, +1, item_data, item_data }; - // Merge continuous ranges (unless NoRangeSelect is set) - ImGuiSelectionRequest* prev = ms->IO.Requests.Size > 0 ? &ms->IO.Requests.Data[ms->IO.Requests.Size - 1] : NULL; - if (prev && prev->Type == ImGuiSelectionRequestType_SetRange && prev->RangeLastItem == ms->BoxSelectLastitem && prev->Selected == selected && (ms->Flags & ImGuiMultiSelectFlags_NoRangeSelect) == 0) - prev->RangeLastItem = item_data; // Merge span into same request - else - ms->IO.Requests.push_back(req); + MultiSelectAddSetRange(ms, selected, +1, item_data, item_data); } storage->LastSelectionSize = ImMax(storage->LastSelectionSize + 1, 1); } - ms->BoxSelectLastitem = item_data; } // Right-click handling. @@ -7804,9 +7797,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) range_selected = selected; range_direction = +1; } - ImGuiSelectionUserData range_dst_item = item_data; - ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetRange, range_selected, (ImS8)range_direction, (range_direction > 0) ? storage->RangeSrcItem : range_dst_item, (range_direction > 0) ? range_dst_item : storage->RangeSrcItem }; - ms->IO.Requests.push_back(req); + MultiSelectAddSetRange(ms, range_selected, range_direction, storage->RangeSrcItem, item_data); } // Update/store the selection state of the Source item (used by CTRL+SHIFT, when Source is unselected we perform a range unselect) @@ -7821,11 +7812,29 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) } if (storage->NavIdItem == item_data) ms->NavIdPassedBy = true; + ms->LastSubmittedItem = item_data; *p_selected = selected; *p_pressed = pressed; } +void ImGui::MultiSelectAddSetRange(ImGuiMultiSelectTempData* ms, bool selected, int range_dir, ImGuiSelectionUserData first_item, ImGuiSelectionUserData last_item) +{ + // Merge contiguous spans into same request (unless NoRangeSelect is set which guarantees single-item ranges) + if (ms->IO.Requests.Size > 0 && first_item == last_item && (ms->Flags & ImGuiMultiSelectFlags_NoRangeSelect) == 0) + { + ImGuiSelectionRequest* prev = &ms->IO.Requests.Data[ms->IO.Requests.Size - 1]; + if (prev->Type == ImGuiSelectionRequestType_SetRange && prev->RangeLastItem == ms->LastSubmittedItem && prev->Selected == selected) + { + prev->RangeLastItem = last_item; + return; + } + } + + ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetRange, selected, (ImS8)range_dir, (range_dir > 0) ? first_item : last_item, (range_dir > 0) ? last_item : first_item }; + ms->IO.Requests.push_back(req); // Add new request +} + void ImGui::DebugNodeMultiSelectState(ImGuiMultiSelectState* storage) { #ifndef IMGUI_DISABLE_DEBUG_TOOLS From a285835ac4a293831852b0d5dd671401fd2c7412 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Jul 2024 19:00:09 +0200 Subject: [PATCH 08/15] MultiSelect: add internal MultiSelectAddSetAll() helper. --- imgui_internal.h | 1 + imgui_widgets.cpp | 28 ++++++++++++---------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 85aaa19bc..3bcca8500 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3408,6 +3408,7 @@ namespace ImGui // Multi-Select API IMGUI_API void MultiSelectItemHeader(ImGuiID id, bool* p_selected, ImGuiButtonFlags* p_button_flags); IMGUI_API void MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed); + IMGUI_API void MultiSelectAddSetAll(ImGuiMultiSelectTempData* ms, bool selected); IMGUI_API void MultiSelectAddSetRange(ImGuiMultiSelectTempData* ms, bool selected, int range_dir, ImGuiSelectionUserData first_item, ImGuiSelectionUserData last_item); inline ImGuiBoxSelectState* GetBoxSelectState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.BoxSelectState.ID == id && g.BoxSelectState.IsActive) ? &g.BoxSelectState : NULL; } inline ImGuiMultiSelectState* GetMultiSelectState(ImGuiID id) { ImGuiContext& g = *GImGui; return g.MultiSelectStorage.GetByKey(id); } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 183c7fbe2..e9cf6f0f7 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7424,12 +7424,7 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel } if (request_clear || request_select_all) - { - ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetAll, request_select_all, 0, ImGuiSelectionUserData_Invalid, ImGuiSelectionUserData_Invalid }; - if (!request_select_all) - storage->LastSelectionSize = 0; - ms->IO.Requests.push_back(req); - } + MultiSelectAddSetAll(ms, request_select_all); ms->LoopRequestSetAll = request_select_all ? 1 : request_clear ? 0 : -1; ms->LastSubmittedItem = ImGuiSelectionUserData_Invalid; @@ -7496,11 +7491,7 @@ ImGuiMultiSelectIO* ImGui::EndMultiSelect() if (ms->Flags & ImGuiMultiSelectFlags_ClearOnClickVoid) if (IsMouseReleased(0) && IsMouseDragPastThreshold(0) == false && g.IO.KeyMods == ImGuiMod_None) - { - ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetAll, false, 0, ImGuiSelectionUserData_Invalid, ImGuiSelectionUserData_Invalid }; - ms->IO.Requests.resize(0); - ms->IO.Requests.push_back(req); - } + MultiSelectAddSetAll(ms, false); } // Courtesy nav wrapping helper flag @@ -7755,11 +7746,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) else if ((input_source == ImGuiInputSource_Keyboard || input_source == ImGuiInputSource_Gamepad) && is_shift && !is_ctrl) request_clear = true; // With is_shift==false the RequestClear was done in BeginIO, not necessary to do again. if (request_clear) - { - ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetAll, false, 0, ImGuiSelectionUserData_Invalid, ImGuiSelectionUserData_Invalid }; - ms->IO.Requests.resize(0); - ms->IO.Requests.push_back(req); - } + MultiSelectAddSetAll(ms, false); } int range_direction; @@ -7818,6 +7805,15 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) *p_pressed = pressed; } +void ImGui::MultiSelectAddSetAll(ImGuiMultiSelectTempData* ms, bool selected) +{ + ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetAll, selected, 0, ImGuiSelectionUserData_Invalid, ImGuiSelectionUserData_Invalid }; + ms->IO.Requests.resize(0); // Can always clear previous requests + ms->IO.Requests.push_back(req); // Add new request + if (selected == false) + ms->Storage->LastSelectionSize = 0; +} + void ImGui::MultiSelectAddSetRange(ImGuiMultiSelectTempData* ms, bool selected, int range_dir, ImGuiSelectionUserData first_item, ImGuiSelectionUserData last_item) { // Merge contiguous spans into same request (unless NoRangeSelect is set which guarantees single-item ranges) From 237165a9359518573f67cabf2e2f6d648f351244 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Jul 2024 19:14:54 +0200 Subject: [PATCH 09/15] MultiSelect: fixed an issue caused by previous commit. Amend a285835. Breaks box-select. --- imgui_widgets.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index e9cf6f0f7..7739f3036 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7424,7 +7424,11 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel } if (request_clear || request_select_all) + { MultiSelectAddSetAll(ms, request_select_all); + if (!request_select_all) + storage->LastSelectionSize = 0; + } ms->LoopRequestSetAll = request_select_all ? 1 : request_clear ? 0 : -1; ms->LastSubmittedItem = ImGuiSelectionUserData_Invalid; @@ -7810,8 +7814,6 @@ void ImGui::MultiSelectAddSetAll(ImGuiMultiSelectTempData* ms, bool selected) ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetAll, selected, 0, ImGuiSelectionUserData_Invalid, ImGuiSelectionUserData_Invalid }; ms->IO.Requests.resize(0); // Can always clear previous requests ms->IO.Requests.push_back(req); // Add new request - if (selected == false) - ms->Storage->LastSelectionSize = 0; } void ImGui::MultiSelectAddSetRange(ImGuiMultiSelectTempData* ms, bool selected, int range_dir, ImGuiSelectionUserData first_item, ImGuiSelectionUserData last_item) From ed356dc181217439af31e5883fbe58906d0ec1cb Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 25 Jul 2024 14:46:25 +0200 Subject: [PATCH 10/15] MultiSelect: BoxSelect: fixed box-select from void setting nav id multiple times. --- imgui_internal.h | 1 + imgui_widgets.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui_internal.h b/imgui_internal.h index 3bcca8500..29420b6b6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1719,6 +1719,7 @@ struct ImGuiBoxSelectState bool IsActive; bool IsStarting; bool IsStartedFromVoid; // Starting click was not from an item. + bool IsStartedSetNavIdOnce; bool RequestClear; ImGuiKeyChord KeyMods : 16; // Latched key-mods for box-select logic. ImVec2 StartPosRel; // Start position in window-contents relative space (to support scrolling) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 7739f3036..1a11e3834 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7161,6 +7161,7 @@ static void BoxSelectPreStartDrag(ImGuiID id, ImGuiSelectionUserData clicked_ite bs->ID = id; bs->IsStarting = true; // Consider starting box-select. bs->IsStartedFromVoid = (clicked_item == ImGuiSelectionUserData_Invalid); + bs->IsStartedSetNavIdOnce = bs->IsStartedFromVoid; bs->KeyMods = g.IO.KeyMods; bs->StartPosRel = bs->EndPosRel = ImGui::WindowPosAbsToRel(g.CurrentWindow, g.IO.MousePos); bs->ScrollAccum = ImVec2(0.0f, 0.0f); @@ -7682,9 +7683,10 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) const bool rect_overlap_prev = bs->BoxSelectRectPrev.Overlaps(g.LastItemData.Rect); if ((rect_overlap_curr && !rect_overlap_prev && !selected) || (rect_overlap_prev && !rect_overlap_curr)) { - if (storage->LastSelectionSize <= 0 && bs->IsStartedFromVoid) + if (storage->LastSelectionSize <= 0 && bs->IsStartedSetNavIdOnce) { pressed = true; // First item act as a pressed: code below will emit selection request and set NavId (whatever we emit here will be overridden anyway) + bs->IsStartedSetNavIdOnce = false; } else { From 55f54fa512f81885cafcd2c701dcff26c328b146 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 25 Jul 2024 15:10:04 +0200 Subject: [PATCH 11/15] Internals: comment out obsolete g.ActiveIdUsingNavInputMask obsoleted two years ago. (#4921, #4858, #787, #1599, #323) Use SetKeyOwner(ImGuiKey_Escape, g.ActiveId); instead. Amend 8b8a61bd --- imgui.cpp | 20 -------------------- imgui_internal.h | 9 ++------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 31f65a9d4..9e93b8434 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4040,9 +4040,6 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) // (Please note that this is WIP and not all keys/inputs are thoroughly declared by all widgets yet) g.ActiveIdUsingNavDirMask = 0x00; g.ActiveIdUsingAllKeyboardKeys = false; -#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO - g.ActiveIdUsingNavInputMask = 0x00; -#endif } void ImGui::ClearActiveID() @@ -4806,25 +4803,8 @@ void ImGui::NewFrame() { g.ActiveIdUsingNavDirMask = 0x00; g.ActiveIdUsingAllKeyboardKeys = false; -#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO - g.ActiveIdUsingNavInputMask = 0x00; -#endif } -#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO - if (g.ActiveId == 0) - g.ActiveIdUsingNavInputMask = 0; - else if (g.ActiveIdUsingNavInputMask != 0) - { - // If your custom widget code used: { g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel); } - // Since IMGUI_VERSION_NUM >= 18804 it should be: { SetKeyOwner(ImGuiKey_Escape, g.ActiveId); SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId); } - if (g.ActiveIdUsingNavInputMask & (1 << ImGuiNavInput_Cancel)) - SetKeyOwner(ImGuiKey_Escape, g.ActiveId); - if (g.ActiveIdUsingNavInputMask & ~(1 << ImGuiNavInput_Cancel)) - IM_ASSERT(0); // Other values unsupported - } -#endif - // Record when we have been stationary as this state is preserved while over same item. // FIXME: The way this is expressed means user cannot alter HoverStationaryDelay during the frame to use varying values. // To allow this we should store HoverItemMaxStationaryTime+ID and perform the >= check in IsItemHovered() function. diff --git a/imgui_internal.h b/imgui_internal.h index 29420b6b6..6fa1ee799 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2081,9 +2081,7 @@ struct ImGuiContext ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it) bool ActiveIdUsingAllKeyboardKeys; // Active widget will want to read all keyboard keys inputs. (this is a shortcut for not taking ownership of 100+ keys, frequently used by drag operations) ImGuiKeyChord DebugBreakInShortcutRouting; // Set to break in SetShortcutRouting()/Shortcut() calls. -#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO - ImU32 ActiveIdUsingNavInputMask; // If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes 'SetKeyOwner(ImGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId);' -#endif + //ImU32 ActiveIdUsingNavInputMask; // [OBSOLETE] Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes --> 'SetKeyOwner(ImGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId);' // Next window/item data ImGuiID CurrentFocusScopeId; // Value for currently appending items == g.FocusScopeStack.back(). Not to be mistaken with g.NavFocusScopeId. @@ -2395,9 +2393,6 @@ struct ImGuiContext ActiveIdUsingNavDirMask = 0x00; ActiveIdUsingAllKeyboardKeys = false; -#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO - ActiveIdUsingNavInputMask = 0x00; -#endif CurrentFocusScopeId = 0; CurrentItemFlags = ImGuiItemFlags_None; @@ -3196,7 +3191,7 @@ namespace ImGui //#endif // Basic Accessors - inline ImGuiItemStatusFlags GetItemStatusFlags(){ ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; } + inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; } inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.InFlags; } inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; } inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; } From aad86b8756b7cde30fd70ac87e6325257e1a3e27 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 25 Jul 2024 15:50:30 +0200 Subject: [PATCH 12/15] Obsoleted GetWindowContentRegionMin() and GetWindowContentRegionMax(). You should never need those functions. You can do everything with GetCursorScreenPos() and GetContentRegionAvail(). --- docs/CHANGELOG.txt | 6 ++++++ imgui.cpp | 10 +++++++++- imgui.h | 13 +++++++------ imgui_demo.cpp | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index fde5c5144..42c2cea37 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -46,6 +46,12 @@ Breaking changes: - new: io.PlatformSetImeDataFn(ImGuiContext* ctx, ImGuiViewport* viewport, ImGuiPlatformImeData* data); It is expected that for a vast majority of users this is automatically set by core library and/or platform backend so it won't have any effect. +- Obsoleted GetWindowContentRegionMin() and GetWindowContentRegionMax(). + You should never need those functions. Always use GetCursorScreenPos() and GetContentRegionAvail(). + Also consider that if you are using GetWindowPos() and GetCursorPos() you may also be making things + unnecessarily complicated. You can do everything with GetCursorScreenPos() and GetContentRegionAvail()!! + - GetWindowContentRegionMax().x - GetCursorPos().x --> GetContentRegionAvail().x + - GetWindowContentRegionMax().x + GetWindowPos().x --> GetCursorScreenPos().x + GetContentRegionAvail().x - Item flag changes: - Obsoleted PushButtonRepeat()/PopButtonRepeat() in favor of using new PushItemFlag()/PopItemFlag() with ImGuiItemFlags_ButtonRepeat. Kept inline redirecting functions (will obsolete). diff --git a/imgui.cpp b/imgui.cpp index 9e93b8434..626031514 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,6 +430,11 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2024/07/25 (1.91.0) - obsoleted GetWindowContentRegionMin() and GetWindowContentRegionMax(). You should never need those functions. Always use GetCursorScreenPos() and GetContentRegionAvail(). + - instead of: GetWindowContentRegionMax().x - GetCursorPos().x + - you can use: GetContentRegionAvail().x + - instead of: GetWindowContentRegionMax().x + GetWindowPos().x + - you can use: GetCursorScreenPos().x + GetContentRegionAvail().x (from left edge of window) - 2024/07/15 (1.91.0) - renamed ImGuiSelectableFlags_DontClosePopups to ImGuiSelectableFlags_NoAutoClosePopups. (#1379, #1468, #2200, #4936, #5216, #7302, #7573) (internals: also renamed ImGuiItemFlags_SelectableDontClosePopup into ImGuiItemFlags_AutoClosePopups with inverted behaviors) - 2024/07/15 (1.91.0) - obsoleted PushButtonRepeat()/PopButtonRepeat() in favor of using new PushItemFlag(ImGuiItemFlags_ButtonRepeat, ...)/PopItemFlag(). @@ -10609,7 +10614,9 @@ ImVec2 ImGui::GetContentRegionAvail() return GetContentRegionMaxAbs() - window->DC.CursorPos; } -// In window space (not screen space!) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +// You should never need those functions. Always use GetCursorScreenPos() and GetContentRegionAvail()! +// They are bizarre local-coordinates which don't play well with scrolling. ImVec2 ImGui::GetWindowContentRegionMin() { ImGuiWindow* window = GImGui->CurrentWindow; @@ -10621,6 +10628,7 @@ ImVec2 ImGui::GetWindowContentRegionMax() ImGuiWindow* window = GImGui->CurrentWindow; return window->ContentRegionRect.Max - window->Pos; } +#endif // Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) // Groups are currently a mishmash of functionalities which should perhaps be clarified and separated. diff --git a/imgui.h b/imgui.h index 47626ad6f..26aed79bb 100644 --- a/imgui.h +++ b/imgui.h @@ -392,10 +392,10 @@ namespace ImGui IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags=0); // is current window focused? or its root/child, depending on flags. see flags for options. IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags=0); // is current window hovered and hoverable (e.g. not blocked by a popup/modal)? See ImGuiHoveredFlags_ for options. IMPORTANT: If you are trying to check whether your mouse should be dispatched to Dear ImGui or to your underlying app, you should not use this function! Use the 'io.WantCaptureMouse' boolean for that! Refer to FAQ entry "How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?" for details. IMGUI_API ImDrawList* GetWindowDrawList(); // get draw list associated to the current window, to append your own drawing primitives - IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (note: it is unlikely you need to use this. Consider using current layout pos instead, GetCursorScreenPos()) - IMGUI_API ImVec2 GetWindowSize(); // get current window size (note: it is unlikely you need to use this. Consider using GetCursorScreenPos() and e.g. GetContentRegionAvail() instead) - IMGUI_API float GetWindowWidth(); // get current window width (shortcut for GetWindowSize().x) - IMGUI_API float GetWindowHeight(); // get current window height (shortcut for GetWindowSize().y) + IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (IT IS UNLIKELY YOU EVER NEED TO USE THIS. Consider always using GetCursorScreenPos() and GetContentRegionAvail() instead) + IMGUI_API ImVec2 GetWindowSize(); // get current window size (IT IS UNLIKELY YOU EVER NEED TO USE THIS. Consider always using GetCursorScreenPos() and GetContentRegionAvail() instead) + IMGUI_API float GetWindowWidth(); // get current window width (IT IS UNLIKELY YOU EVER NEED TO USE THIS). Shortcut for GetWindowSize().x. + IMGUI_API float GetWindowHeight(); // get current window height (IT IS UNLIKELY YOU EVER NEED TO USE THIS). Shortcut for GetWindowSize().y. // Window manipulation // - Prefer using SetNextXXX functions (before Begin) rather that SetXXX functions (after Begin). @@ -422,8 +422,6 @@ namespace ImGui // - Those functions are bound to be redesigned (they are confusing, incomplete and the Min/Max return values are in local window coordinates which increases confusion) IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates - IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min for the full window (roughly (0,0)-Scroll), in window coordinates - IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max for the full window (roughly (0,0)+Size-Scroll) where Size can be overridden with SetNextWindowContentSize(), in window coordinates // Windows Scrolling // - Any change of Scroll will be applied at the beginning of next frame in the first call to Begin(). @@ -473,6 +471,7 @@ namespace ImGui // - By "cursor" we mean the current output position. // - The typical widget behavior is to output themselves at the current cursor position, then move the cursor one line down. // - You can call SameLine() between widgets to undo the last carriage return and output at the right of the preceding widget. + // - YOU CAN DO 99% OF WHAT YOU NEED WITH ONLY GetCursorScreenPos() and GetContentRegionAvail(). // - Attention! We currently have inconsistencies between window-local and absolute positions we will aim to fix with future API: // - Absolute coordinate: GetCursorScreenPos(), SetCursorScreenPos(), all ImDrawList:: functions. -> this is the preferred way forward. // - Window-local coordinates: SameLine(), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), GetContentRegionMax(), GetWindowContentRegion*(), PushTextWrapPos() @@ -3504,6 +3503,8 @@ namespace ImGui static inline void PopButtonRepeat() { PopItemFlag(); } static inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); } static inline void PopTabStop() { PopItemFlag(); } + IMGUI_API ImVec2 GetWindowContentRegionMin(); // Content boundaries min for the window (roughly (0,0)-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()! + IMGUI_API ImVec2 GetWindowContentRegionMax(); // Content boundaries max for the window (roughly (0,0)+Size-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()! // OBSOLETED in 1.90.0 (from September 2023) static inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags window_flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, window_flags); } static inline void EndChildFrame() { EndChild(); } diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 7a3cdf0f4..8684bd0c6 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3918,7 +3918,7 @@ static void ShowDemoWindowLayout() ImGui::Text("Manual wrapping:"); ImGuiStyle& style = ImGui::GetStyle(); int buttons_count = 20; - float window_visible_x2 = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x; + float window_visible_x2 = ImGui::GetCursorScreenPos().x + ImGui::GetContentRegionAvail().x; for (int n = 0; n < buttons_count; n++) { ImGui::PushID(n); From 055b2e80fbe1f13b81ef6e092381530eaf68fc36 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 25 Jul 2024 16:02:59 +0200 Subject: [PATCH 13/15] Moved everyone's best friend GetContentRegionAvail() to a more prominent position. --- imgui.cpp | 1 - imgui.h | 14 +++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 626031514..ace1d0276 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10315,7 +10315,6 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE // - GetContentRegionMax() // - GetContentRegionMaxAbs() [Internal] // - GetContentRegionAvail(), -// - GetWindowContentRegionMin(), GetWindowContentRegionMax() // - BeginGroup() // - EndGroup() // Also see in imgui_widgets: tab bars, and in imgui_tables: tables, columns. diff --git a/imgui.h b/imgui.h index 26aed79bb..e98399371 100644 --- a/imgui.h +++ b/imgui.h @@ -417,12 +417,6 @@ namespace ImGui IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond = 0); // set named window collapsed state IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / top-most. use NULL to remove focus. - // Content region - // - Retrieve available space from a given point. GetContentRegionAvail() is frequently useful. - // - Those functions are bound to be redesigned (they are confusing, incomplete and the Min/Max return values are in local window coordinates which increases confusion) - IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() - IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates - // Windows Scrolling // - Any change of Scroll will be applied at the beginning of next frame in the first call to Begin(). // - You may instead use SetNextWindowScroll() prior to calling Begin() to avoid this delay, as an alternative to using SetScrollX()/SetScrollY(). @@ -474,10 +468,12 @@ namespace ImGui // - YOU CAN DO 99% OF WHAT YOU NEED WITH ONLY GetCursorScreenPos() and GetContentRegionAvail(). // - Attention! We currently have inconsistencies between window-local and absolute positions we will aim to fix with future API: // - Absolute coordinate: GetCursorScreenPos(), SetCursorScreenPos(), all ImDrawList:: functions. -> this is the preferred way forward. - // - Window-local coordinates: SameLine(), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), GetContentRegionMax(), GetWindowContentRegion*(), PushTextWrapPos() - // - GetCursorScreenPos() = GetCursorPos() + GetWindowPos(). GetWindowPos() is almost only ever useful to convert from window-local to absolute coordinates. - IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute coordinates (prefer using this, also more useful to work with ImDrawList API). + // - Window-local coordinates: SameLine(offset), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), GetContentRegionMax(), PushTextWrapPos() + // - GetCursorScreenPos() = GetCursorPos() + GetWindowPos(). GetWindowPos() is almost only ever useful to convert from window-local to absolute coordinates. Try not to use it. + IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute coordinates. THIS IS YOUR BEST FRIEND (prefer using this rather than GetCursorPos(), also more useful to work with ImDrawList API). IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute coordinates + IMGUI_API ImVec2 GetContentRegionAvail(); // available space from current position. THIS IS YOUR BEST FRIEND. + IMGUI_API ImVec2 GetContentRegionMax(); // [window-local] current content boundaries (e.g. window boundaries including scrolling, or current column boundaries) IMGUI_API ImVec2 GetCursorPos(); // [window-local] cursor position in window coordinates (relative to window position) IMGUI_API float GetCursorPosX(); // [window-local] " IMGUI_API float GetCursorPosY(); // [window-local] " From 4227402b2fe46a24663fd16efd042a8527d2bbed Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 25 Jul 2024 16:10:18 +0200 Subject: [PATCH 14/15] Internals: removed GetContentRegionMaxAbs() which was only meaningfully used in place of GetContentRegionAvail(). --- imgui.cpp | 40 ++++++++++++++-------------------------- imgui_internal.h | 1 - 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ace1d0276..40de62165 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10313,7 +10313,6 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE // - GetFrameHeight() // - GetFrameHeightWithSpacing() // - GetContentRegionMax() -// - GetContentRegionMaxAbs() [Internal] // - GetContentRegionAvail(), // - BeginGroup() // - EndGroup() @@ -10530,8 +10529,8 @@ float ImGui::CalcItemWidth() w = window->DC.ItemWidth; if (w < 0.0f) { - float region_max_x = GetContentRegionMaxAbs().x; - w = ImMax(1.0f, region_max_x - window->DC.CursorPos.x + w); + float region_avail_x = GetContentRegionAvail().x; + w = ImMax(1.0f, region_avail_x + w); } w = IM_TRUNC(w); return w; @@ -10543,22 +10542,19 @@ float ImGui::CalcItemWidth() // The 4.0f here may be changed to match CalcItemWidth() and/or BeginChild() (right now we have a mismatch which is harmless but undesirable) ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_w, float default_h) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - - ImVec2 region_max; + ImVec2 avail; if (size.x < 0.0f || size.y < 0.0f) - region_max = GetContentRegionMaxAbs(); + avail = GetContentRegionAvail(); if (size.x == 0.0f) size.x = default_w; else if (size.x < 0.0f) - size.x = ImMax(4.0f, region_max.x - window->DC.CursorPos.x + size.x); + size.x = ImMax(4.0f, avail.x + size.x); // <-- size.x is negative here so we are subtracting if (size.y == 0.0f) size.y = default_h; else if (size.y < 0.0f) - size.y = ImMax(4.0f, region_max.y - window->DC.CursorPos.y + size.y); + size.y = ImMax(4.0f, avail.y + size.y); // <-- size.y is negative here so we are subtracting return size; } @@ -10587,8 +10583,15 @@ float ImGui::GetFrameHeightWithSpacing() return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y; } -// FIXME: All the Contents Region function are messy or misleading. WE WILL AIM TO OBSOLETE ALL OF THEM WITH A NEW "WORK RECT" API. Thanks for your patience! +ImVec2 ImGui::GetContentRegionAvail() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImVec2 mx = (window->DC.CurrentColumns || g.CurrentTable) ? window->WorkRect.Max : window->ContentRegionRect.Max; + return mx - window->DC.CursorPos; +} +// FIXME: All the Contents Region function are messy or misleading. WE WILL AIM TO OBSOLETE ALL OF THEM WITH A NEW "WORK RECT" API. Thanks for your patience! // FIXME: This is in window space (not screen space!). ImVec2 ImGui::GetContentRegionMax() { @@ -10598,21 +10601,6 @@ ImVec2 ImGui::GetContentRegionMax() return mx - window->Pos; } -// [Internal] Absolute coordinate. Saner. This is not exposed until we finishing refactoring work rect features. -ImVec2 ImGui::GetContentRegionMaxAbs() -{ - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - ImVec2 mx = (window->DC.CurrentColumns || g.CurrentTable) ? window->WorkRect.Max : window->ContentRegionRect.Max; - return mx; -} - -ImVec2 ImGui::GetContentRegionAvail() -{ - ImGuiWindow* window = GImGui->CurrentWindow; - return GetContentRegionMaxAbs() - window->DC.CursorPos; -} - #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // You should never need those functions. Always use GetCursorScreenPos() and GetContentRegionAvail()! // They are bizarre local-coordinates which don't play well with scrolling. diff --git a/imgui_internal.h b/imgui_internal.h index 6fa1ee799..6cee07857 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3217,7 +3217,6 @@ namespace ImGui IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API void PushMultiItemsWidths(int components, float width_full); - IMGUI_API ImVec2 GetContentRegionMaxAbs(); IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess); // Parameter stacks (shared) From b20f62b162e5f1e44748eb768f6b126a25ec29de Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 25 Jul 2024 16:18:46 +0200 Subject: [PATCH 15/15] Obsoleted GetContentRegionMax(). --- docs/CHANGELOG.txt | 10 ++++++---- imgui.cpp | 21 ++++++++++----------- imgui.h | 13 +++++++------ 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 42c2cea37..eb98554ce 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -46,12 +46,14 @@ Breaking changes: - new: io.PlatformSetImeDataFn(ImGuiContext* ctx, ImGuiViewport* viewport, ImGuiPlatformImeData* data); It is expected that for a vast majority of users this is automatically set by core library and/or platform backend so it won't have any effect. -- Obsoleted GetWindowContentRegionMin() and GetWindowContentRegionMax(). - You should never need those functions. Always use GetCursorScreenPos() and GetContentRegionAvail(). - Also consider that if you are using GetWindowPos() and GetCursorPos() you may also be making things - unnecessarily complicated. You can do everything with GetCursorScreenPos() and GetContentRegionAvail()!! +- Obsoleted GetContentRegionMax(), GetWindowContentRegionMin() and GetWindowContentRegionMax(). + You should never need those functions! You can do everything in less a confusing manner by only + using GetCursorScreenPos() and GetContentRegionAvail(). Also always consider that if you are using + GetWindowPos() and GetCursorPos() you may also be making things unnecessarily complicated. + I repeat: You can do everything with GetCursorScreenPos() and GetContentRegionAvail()!! - GetWindowContentRegionMax().x - GetCursorPos().x --> GetContentRegionAvail().x - GetWindowContentRegionMax().x + GetWindowPos().x --> GetCursorScreenPos().x + GetContentRegionAvail().x + - GetContentRegionMax() --> GetContentRegionAvail() + GetCursorScreenPos() - GetWindowPos() // right edge in weird local coordinates - Item flag changes: - Obsoleted PushButtonRepeat()/PopButtonRepeat() in favor of using new PushItemFlag()/PopItemFlag() with ImGuiItemFlags_ButtonRepeat. Kept inline redirecting functions (will obsolete). diff --git a/imgui.cpp b/imgui.cpp index 40de62165..a74ae56c1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,11 +430,14 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2024/07/25 (1.91.0) - obsoleted GetWindowContentRegionMin() and GetWindowContentRegionMax(). You should never need those functions. Always use GetCursorScreenPos() and GetContentRegionAvail(). + - 2024/07/25 (1.91.0) - obsoleted GetContentRegionMax(), GetWindowContentRegionMin() and GetWindowContentRegionMax(). + you should never need those functions. you can do everything with GetCursorScreenPos() and GetContentRegionAvail() in a more simple way. - instead of: GetWindowContentRegionMax().x - GetCursorPos().x - you can use: GetContentRegionAvail().x - instead of: GetWindowContentRegionMax().x + GetWindowPos().x - you can use: GetCursorScreenPos().x + GetContentRegionAvail().x (from left edge of window) + - instead of: GetContentRegionMax() + - you cna use: GetContentRegionAvail() + GetCursorScreenPos() - GetWindowPos() // right edge in weird local coordinates - 2024/07/15 (1.91.0) - renamed ImGuiSelectableFlags_DontClosePopups to ImGuiSelectableFlags_NoAutoClosePopups. (#1379, #1468, #2200, #4936, #5216, #7302, #7573) (internals: also renamed ImGuiItemFlags_SelectableDontClosePopup into ImGuiItemFlags_AutoClosePopups with inverted behaviors) - 2024/07/15 (1.91.0) - obsoleted PushButtonRepeat()/PopButtonRepeat() in favor of using new PushItemFlag(ImGuiItemFlags_ButtonRepeat, ...)/PopItemFlag(). @@ -10591,19 +10594,15 @@ ImVec2 ImGui::GetContentRegionAvail() return mx - window->DC.CursorPos; } -// FIXME: All the Contents Region function are messy or misleading. WE WILL AIM TO OBSOLETE ALL OF THEM WITH A NEW "WORK RECT" API. Thanks for your patience! -// FIXME: This is in window space (not screen space!). -ImVec2 ImGui::GetContentRegionMax() -{ - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - ImVec2 mx = (window->DC.CurrentColumns || g.CurrentTable) ? window->WorkRect.Max : window->ContentRegionRect.Max; - return mx - window->Pos; -} - #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + // You should never need those functions. Always use GetCursorScreenPos() and GetContentRegionAvail()! // They are bizarre local-coordinates which don't play well with scrolling. +ImVec2 ImGui::GetContentRegionMax() +{ + return GetContentRegionAvail() + GetCursorScreenPos() - GetWindowPos(); +} + ImVec2 ImGui::GetWindowContentRegionMin() { ImGuiWindow* window = GImGui->CurrentWindow; diff --git a/imgui.h b/imgui.h index e98399371..0686be2ab 100644 --- a/imgui.h +++ b/imgui.h @@ -468,19 +468,19 @@ namespace ImGui // - YOU CAN DO 99% OF WHAT YOU NEED WITH ONLY GetCursorScreenPos() and GetContentRegionAvail(). // - Attention! We currently have inconsistencies between window-local and absolute positions we will aim to fix with future API: // - Absolute coordinate: GetCursorScreenPos(), SetCursorScreenPos(), all ImDrawList:: functions. -> this is the preferred way forward. - // - Window-local coordinates: SameLine(offset), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), GetContentRegionMax(), PushTextWrapPos() + // - Window-local coordinates: SameLine(offset), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), PushTextWrapPos() + // - Window-local coordinates: GetContentRegionMax(), GetWindowContentRegionMin(), GetWindowContentRegionMax() --> all obsoleted. YOU DON'T NEED THEM. // - GetCursorScreenPos() = GetCursorPos() + GetWindowPos(). GetWindowPos() is almost only ever useful to convert from window-local to absolute coordinates. Try not to use it. - IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute coordinates. THIS IS YOUR BEST FRIEND (prefer using this rather than GetCursorPos(), also more useful to work with ImDrawList API). - IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute coordinates + IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position, absolute coordinates. THIS IS YOUR BEST FRIEND (prefer using this rather than GetCursorPos(), also more useful to work with ImDrawList API). + IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position, absolute coordinates. THIS IS YOUR BEST FRIEND. IMGUI_API ImVec2 GetContentRegionAvail(); // available space from current position. THIS IS YOUR BEST FRIEND. - IMGUI_API ImVec2 GetContentRegionMax(); // [window-local] current content boundaries (e.g. window boundaries including scrolling, or current column boundaries) - IMGUI_API ImVec2 GetCursorPos(); // [window-local] cursor position in window coordinates (relative to window position) + IMGUI_API ImVec2 GetCursorPos(); // [window-local] cursor position in window-local coordinates. This is not your best friend. IMGUI_API float GetCursorPosX(); // [window-local] " IMGUI_API float GetCursorPosY(); // [window-local] " IMGUI_API void SetCursorPos(const ImVec2& local_pos); // [window-local] " IMGUI_API void SetCursorPosX(float local_x); // [window-local] " IMGUI_API void SetCursorPosY(float local_y); // [window-local] " - IMGUI_API ImVec2 GetCursorStartPos(); // [window-local] initial cursor position, in window coordinates + IMGUI_API ImVec2 GetCursorStartPos(); // [window-local] initial cursor position, in window-local coordinates // Other layout functions IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator. @@ -3499,6 +3499,7 @@ namespace ImGui static inline void PopButtonRepeat() { PopItemFlag(); } static inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); } static inline void PopTabStop() { PopItemFlag(); } + IMGUI_API ImVec2 GetContentRegionMax(); // Content boundaries max (e.g. window boundaries including scrolling, or current column boundaries). You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()! IMGUI_API ImVec2 GetWindowContentRegionMin(); // Content boundaries min for the window (roughly (0,0)-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()! IMGUI_API ImVec2 GetWindowContentRegionMax(); // Content boundaries max for the window (roughly (0,0)+Size-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()! // OBSOLETED in 1.90.0 (from September 2023)