diff --git a/imgui.cpp b/imgui.cpp index ef6a4b9a..cd2f622f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4502,7 +4502,7 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_ char window_name[16]; ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip%02d", g.TooltipOverrideCount); if (override_previous_tooltip) - if (ImGuiWindow* window = ImGui::FindWindowByName(window_name)) + if (ImGuiWindow* window = FindWindowByName(window_name)) if (window->Active) { // Hide previous tooltips. We can't easily "reset" the content of a window so we create a new one. @@ -4510,7 +4510,7 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_ ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip%02d", ++g.TooltipOverrideCount); } ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoNavFocus; - ImGui::Begin(window_name, NULL, flags | extra_flags); + Begin(window_name, NULL, flags | extra_flags); } void ImGui::SetTooltipV(const char* fmt, va_list args) @@ -4807,7 +4807,7 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b const ImVec2 content_avail = ImGui::GetContentRegionAvail(); ImVec2 size = ImFloor(size_arg); - const int auto_fit_axises = ((size.x == 0.0f) ? 0x01 : 0x00) | ((size.y == 0.0f) ? 0x02 : 0x00); + const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00); if (size.x <= 0.0f) size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues) if (size.y <= 0.0f) @@ -4867,9 +4867,9 @@ void ImGui::EndChild() { // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. ImVec2 sz = GetWindowSize(); - if (window->AutoFitChildAxises & 0x01) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f + if (window->AutoFitChildAxises & (1 << ImGuiAxis_X)) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f sz.x = ImMax(4.0f, sz.x); - if (window->AutoFitChildAxises & 0x02) + if (window->AutoFitChildAxises & (1 << ImGuiAxis_Y)) sz.y = ImMax(4.0f, sz.y); ImGui::End(); @@ -5055,6 +5055,14 @@ static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) return new_size; } +static ImVec2 CalcSizeContents(ImGuiWindow* window) +{ + ImVec2 sz; + sz.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : (window->DC.CursorMaxPos.x - window->Pos.x + window->Scroll.x)); + sz.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : (window->DC.CursorMaxPos.y - window->Pos.y + window->Scroll.y)); + return sz + window->WindowPadding; +} + static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) { ImGuiContext& g = *GImGui; @@ -5179,13 +5187,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // IM_ASSERT(flags & ImGuiWindowFlags_ChildWindow); // Find or create - bool window_is_new = false; ImGuiWindow* window = FindWindowByName(name); if (!window) { ImVec2 size_on_first_use = (g.SetNextWindowSizeCond != 0) ? g.SetNextWindowSizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. window = CreateNewWindow(name, size_on_first_use, flags); - window_is_new = true; } const int current_frame = g.FrameCount; @@ -5229,7 +5235,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->NavLastIds[0] = 0; // Process SetNextWindow***() calls - bool window_pos_set_by_api = false, window_size_set_by_api = false; + bool window_pos_set_by_api = false; + bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; if (g.SetNextWindowPosCond) { window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; @@ -5249,7 +5256,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } if (g.SetNextWindowSizeCond) { - window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0; + window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0 && (g.SetNextWindowSizeVal.x > 0.0f); + window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0 && (g.SetNextWindowSizeVal.y > 0.0f); SetWindowSize(window, g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); g.SetNextWindowSizeCond = 0; } @@ -5331,11 +5339,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // SIZE // Update contents size from last frame for auto-fitting (unless explicitly specified) - window->SizeContents.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.x - window->Pos.x) + window->Scroll.x)); - window->SizeContents.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : ((window_is_new ? 0.0f : window->DC.CursorMaxPos.y - window->Pos.y) + window->Scroll.y)); - window->SizeContents += window->WindowPadding; + window->SizeContents = CalcSizeContents(window); - // Hide popup/tooltip window when first appearing while we measure size (because we recycle them) + // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) if (window->HiddenFrames > 0) window->HiddenFrames--; if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && window_just_activated_by_user) @@ -5343,8 +5349,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->HiddenFrames = 1; if (flags & ImGuiWindowFlags_AlwaysAutoResize) { - if (!window_size_set_by_api) - window->Size = window->SizeFull = ImVec2(0.f, 0.f); + if (!window_size_x_set_by_api) + window->Size.x = window->SizeFull.x = 0.f; + if (!window_size_y_set_by_api) + window->Size.y = window->SizeFull.y = 0.f; window->SizeContents = ImVec2(0.f, 0.f); } } @@ -5360,30 +5368,25 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window); - if (window->Collapsed) + ImVec2 size_for_scrollbars_visibility = window->SizeFullAtLastBegin; + if (flags & ImGuiWindowFlags_AlwaysAutoResize && !window->Collapsed) { - // We still process initial auto-fit on collapsed windows to get a window width, - // But otherwise we don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. - if (window->AutoFitFramesX > 0) - window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; - if (window->AutoFitFramesY > 0) - window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. + if (!window_size_x_set_by_api) + window->SizeFull.x = size_for_scrollbars_visibility.x = size_auto_fit.x; + if (!window_size_y_set_by_api) + window->SizeFull.y = size_for_scrollbars_visibility.y = size_auto_fit.y; } - else if (!window_size_set_by_api) + else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) { - if (flags & ImGuiWindowFlags_AlwaysAutoResize) - { - window->SizeFull = size_auto_fit; - } - else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) - { - // Auto-fit only grows during the first few frames - if (window->AutoFitFramesX > 0) - window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; - if (window->AutoFitFramesY > 0) - window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + // Auto-fit only grows during the first few frames + // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize ImGuiWindowFlags_AlwaysAutoResize. + if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) + window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; + if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) + window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + if (!window->Collapsed) MarkIniSettingsDirty(window); - } } // Apply minimum/maximum window size constraints and final size @@ -5391,7 +5394,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) { - IM_ASSERT(window_size_set_by_api); // Submitted by BeginChild() + IM_ASSERT(window_size_x_set_by_api && window_size_x_set_by_api); // Submitted by BeginChild() window->Size = window->SizeFull; } @@ -5400,10 +5403,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). if (!window->Collapsed) { - window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFullAtLastBegin.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); - window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFullAtLastBegin.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > size_for_scrollbars_visibility.y) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > size_for_scrollbars_visibility.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (window->SizeContents.y > window->SizeFullAtLastBegin.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarY = (window->SizeContents.y > size_for_scrollbars_visibility.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); } @@ -5537,7 +5540,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size); resize_rect.FixInverted(); bool hovered, held; - ButtonBehavior(resize_rect, window->GetID((void*)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChilds | ImGuiButtonFlags_NoNavFocus); + ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChilds | ImGuiButtonFlags_NoNavFocus); if (hovered || held) g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; @@ -5563,7 +5566,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise bool hovered, held; ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); - ButtonBehavior(border_rect, window->GetID((void*)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChilds | ImGuiButtonFlags_NoNavFocus); + ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChilds | ImGuiButtonFlags_NoNavFocus); if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held) { g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; @@ -10188,8 +10191,9 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa return value_changed; } -bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popup_size) +bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags, ImVec2 popup_size) { + (void)flags; // Unused ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; @@ -10287,7 +10291,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi height_in_items = 7; float popup_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); - if (!BeginCombo(label, preview_text, ImVec2(0.0f, popup_height))) + if (!BeginCombo(label, preview_text, 0, ImVec2(0.0f, popup_height))) return false; // Display items @@ -12079,7 +12083,7 @@ void ImGui::Indent(float indent_w) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - window->DC.IndentX += (indent_w > 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.IndentX += (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; } @@ -12087,7 +12091,7 @@ void ImGui::Unindent(float indent_w) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - window->DC.IndentX -= (indent_w > 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.IndentX -= (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; } diff --git a/imgui.h b/imgui.h index 9689a97d..3e1ff327 100644 --- a/imgui.h +++ b/imgui.h @@ -219,8 +219,8 @@ namespace ImGui IMGUI_API void NewLine(); // undo a SameLine() IMGUI_API void Spacing(); // add vertical spacing IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size - IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by style.IndentSpacing or indent_w if >0 - IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by style.IndentSpacing or indent_w if >0 + IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by style.IndentSpacing or indent_w if != 0 + IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by style.IndentSpacing or indent_w if != 0 IMGUI_API void BeginGroup(); // 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.) IMGUI_API void EndGroup(); IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position diff --git a/imgui_internal.h b/imgui_internal.h index 369644ac..945b336d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -50,6 +50,7 @@ typedef int ImGuiItemFlags; // flags: for PushItemFlag() typedef int ImGuiNavHighlightFlags; // flags: for RenderNavHighlight() // enum ImGuiNavHighlightFlags_ typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_ typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_ +typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ //------------------------------------------------------------------------- // STB libraries @@ -213,6 +214,10 @@ enum ImGuiSelectableFlagsPrivate_ ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 }; +enum ImGuiComboFlags_ +{ +}; + enum ImGuiSeparatorFlags_ { ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar @@ -952,7 +957,7 @@ namespace ImGui IMGUI_API void PushColumnClipRect(int column_index = -1); // FIXME-WIP: New Combo API - IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImVec2 popup_size = ImVec2(0.0f,0.0f)); + IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0, ImVec2 popup_size = ImVec2(0.0f,0.0f)); IMGUI_API void EndCombo(); // NB: All position are in absolute pixels coordinates (never using window coordinates internally)