1
0
Fork 0
mirror of https://github.com/ocornut/imgui.git synced 2026-02-07 04:30:08 +00:00

Merge remote-tracking branch 'origin/master' into docking

# Conflicts:
#	imgui.cpp
#	imgui.h
This commit is contained in:
ocornut 2023-12-14 17:20:31 +01:00
commit 8add6bcb9f
8 changed files with 295 additions and 303 deletions

107
imgui.cpp
View file

@ -432,6 +432,9 @@ CODE
- likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
- 2023/12/06 (1.90.1) - removed CalcListClipping() marked obsolete in 1.86. Prefer using ImGuiListClipper which can return non-contiguous ranges.
- 2023/12/05 (1.90.1) - imgui_freetype: commented out ImGuiFreeType::BuildFontAtlas() obsoleted in 1.81. prefer using #define IMGUI_ENABLE_FREETYPE or see commented code for manual calls.
- 2023/12/05 (1.90.1) - internals,columns: commented out legacy ImGuiColumnsFlags_XXX symbols redirecting to ImGuiOldColumnsFlags_XXX, obsoleted from imgui_internal.h in 1.80.
- 2023/11/09 (1.90.0) - removed IM_OFFSETOF() macro in favor of using offsetof() available in C++11. Kept redirection define (will obsolete).
- 2023/11/07 (1.90.0) - removed BeginChildFrame()/EndChildFrame() in favor of using BeginChild() with the ImGuiChildFlags_FrameStyle flag. kept inline redirection function (will obsolete).
those functions were merely PushStyle/PopStyle helpers, the removal isn't so much motivated by needing to add the feature in BeginChild(), but by the necessity to avoid BeginChildFrame() signature mismatching BeginChild() signature and features.
@ -2783,54 +2786,6 @@ static bool GetSkipItemForListClipping()
return (g.CurrentTable ? g.CurrentTable->HostSkipItems : g.CurrentWindow->SkipItems);
}
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Legacy helper to calculate coarse clipping of large list of evenly sized items.
// This legacy API is not ideal because it assumes we will return a single contiguous rectangle.
// Prefer using ImGuiListClipper which can returns non-contiguous ranges.
void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (g.LogEnabled)
{
// If logging is active, do not perform any clipping
*out_items_display_start = 0;
*out_items_display_end = items_count;
return;
}
if (GetSkipItemForListClipping())
{
*out_items_display_start = *out_items_display_end = 0;
return;
}
// We create the union of the ClipRect and the scoring rect which at worst should be 1 page away from ClipRect
// We don't include g.NavId's rectangle in there (unless g.NavJustMovedToId is set) because the rectangle enlargement can get costly.
ImRect rect = window->ClipRect;
if (g.NavMoveScoringItems)
rect.Add(g.NavScoringNoClipRect);
if (g.NavJustMovedToId && window->NavLastIds[0] == g.NavJustMovedToId)
rect.Add(WindowRectRelToAbs(window, window->NavRectRel[0])); // Could store and use NavJustMovedToRectRel
const ImVec2 pos = window->DC.CursorPos;
int start = (int)((rect.Min.y - pos.y) / items_height);
int end = (int)((rect.Max.y - pos.y) / items_height);
// When performing a navigation request, ensure we have one item extra in the direction we are moving to
// FIXME: Verify this works with tabbing
const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav);
if (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up)
start--;
if (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down)
end++;
start = ImClamp(start, 0, items_count);
end = ImClamp(end + 1, start, items_count);
*out_items_display_start = start;
*out_items_display_end = end;
}
#endif
static void ImGuiListClipper_SortAndFuseRanges(ImVector<ImGuiListClipperRange>& ranges, int offset = 0)
{
if (ranges.Size - offset <= 1)
@ -6014,7 +5969,7 @@ static inline ImVec2 CalcWindowMinSize(ImGuiWindow* window)
{
ImGuiWindow* window_for_height = GetWindowForTitleAndMenuHeight(window);
size_min.x = ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) == 0) ? g.Style.WindowMinSize.x : 4.0f;
size_min.y = ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) == 0) ? g.Style.WindowMinSize.x : 4.0f;
size_min.y = ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) == 0) ? g.Style.WindowMinSize.y : 4.0f;
size_min.y = ImMax(size_min.y, window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows
}
return size_min;
@ -8940,22 +8895,25 @@ static int CalcRoutingScore(ImGuiWindow* location, ImGuiID owner_id, ImGuiInputF
if (owner_id != 0 && g.ActiveId == owner_id)
return 1;
// Early out when not in focus stack
if (focused == NULL || focused->RootWindow != location->RootWindow)
return 255;
// Score based on distance to focused window (lower is better)
// Assuming both windows are submitting a routing request,
// - When Window....... is focused -> Window scores 3 (best), Window/ChildB scores 255 (no match)
// - When Window/ChildB is focused -> Window scores 4, Window/ChildB scores 3 (best)
// Assuming only WindowA is submitting a routing request,
// - When Window/ChildB is focused -> Window scores 4 (best), Window/ChildB doesn't have a score.
if (focused != NULL && focused->RootWindow == location->RootWindow)
for (int next_score = 3; focused != NULL; next_score++)
for (int next_score = 3; focused != NULL; next_score++)
{
if (focused == location)
{
if (focused == location)
{
IM_ASSERT(next_score < 255);
return next_score;
}
focused = (focused->RootWindow != focused) ? focused->ParentWindow : NULL; // FIXME: This could be later abstracted as a focus path
IM_ASSERT(next_score < 255);
return next_score;
}
focused = (focused->RootWindow != focused) ? focused->ParentWindow : NULL; // FIXME: This could be later abstracted as a focus path
}
return 255;
}
@ -10552,14 +10510,18 @@ void ImGui::PushMultiItemsWidths(int components, float w_full)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(components > 0);
const ImGuiStyle& style = g.Style;
const float w_item_one = ImMax(1.0f, IM_TRUNC((w_full - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components));
const float w_item_last = ImMax(1.0f, IM_TRUNC(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components - 1)));
window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); // Backup current width
window->DC.ItemWidthStack.push_back(w_item_last);
for (int i = 0; i < components - 2; i++)
window->DC.ItemWidthStack.push_back(w_item_one);
window->DC.ItemWidth = (components == 1) ? w_item_last : w_item_one;
float w_items = w_full - style.ItemInnerSpacing.x * (components - 1);
float prev_split = w_items;
for (int i = components - 1; i > 0; i--)
{
float next_split = IM_TRUNC(w_items * i / components);
window->DC.ItemWidthStack.push_back(prev_split - next_split);
prev_split = next_split;
}
window->DC.ItemWidth = prev_split;
g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth;
}
@ -10813,7 +10775,7 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
}
scroll[axis] = scroll_target - center_ratio * (window->SizeFull[axis] - decoration_size[axis]);
}
scroll[axis] = IM_TRUNC(ImMax(scroll[axis], 0.0f));
scroll[axis] = IM_ROUND(ImMax(scroll[axis], 0.0f));
if (!window->Collapsed && !window->SkipItems)
scroll[axis] = ImMin(scroll[axis], window->ScrollMax[axis]);
}
@ -12737,7 +12699,7 @@ void ImGui::NavMoveRequestApplyResult()
g.NavNextActivateId = result->ID;
g.NavNextActivateFlags = ImGuiActivateFlags_None;
if (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing)
g.NavNextActivateFlags |= ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState;
g.NavNextActivateFlags |= ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState | ImGuiActivateFlags_FromTabbing;
}
// Enable nav highlight
@ -20275,6 +20237,14 @@ void ImGui::DebugNodeDockNode(ImGuiDockNode* node, const char* label)
}
}
static void FormatTextureIDForDebugDisplay(char* buf, int buf_size, ImTextureID tex_id)
{
if (sizeof(tex_id) >= sizeof(void*))
ImFormatString(buf, buf_size, "0x%p", (void*)*(intptr_t*)(void*)&tex_id);
else
ImFormatString(buf, buf_size, "0x%04X", *(int*)(void*)&tex_id);
}
// [DEBUG] Display contents of ImDrawList
// Note that both 'window' and 'viewport' may be NULL here. Viewport is generally null of destroyed popups which previously owned a viewport.
void ImGui::DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label)
@ -20311,10 +20281,11 @@ void ImGui::DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, con
continue;
}
char texid_desc[20];
FormatTextureIDForDebugDisplay(texid_desc, IM_ARRAYSIZE(texid_desc), pcmd->TextureId);
char buf[300];
ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd:%5d tris, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
pcmd->ElemCount / 3, (void*)(intptr_t)pcmd->TextureId,
pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd:%5d tris, Tex %s, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
pcmd->ElemCount / 3, texid_desc, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
bool pcmd_node_open = TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf);
if (IsItemHovered() && (cfg->ShowDrawCmdMesh || cfg->ShowDrawCmdBoundingBoxes) && fg_draw_list)
DebugNodeDrawCmdShowMeshAndBoundingBox(fg_draw_list, draw_list, pcmd, cfg->ShowDrawCmdMesh, cfg->ShowDrawCmdBoundingBoxes);