|
@@ -509,7 +509,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
|
|
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
|
|
// Alternate registration spot, for when caller didn't use ItemAdd()
|
|
|
- if (id != 0 && g.LastItemData.ID != id)
|
|
|
+ if (g.LastItemData.ID != id)
|
|
|
IMGUI_TEST_ENGINE_ITEM_ADD(id, bb, NULL);
|
|
|
#endif
|
|
|
|
|
@@ -537,6 +537,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id;
|
|
|
if (hovered)
|
|
|
{
|
|
|
+ IM_ASSERT(id != 0); // Lazily check inside rare path.
|
|
|
+
|
|
|
// Poll mouse buttons
|
|
|
// - 'mouse_button_clicked' is generally carried into ActiveIdMouseButton when setting ActiveId.
|
|
|
// - Technically we only need some values in one code path, but since this is gated by hovered test this is fine.
|
|
@@ -1295,27 +1297,47 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
|
|
if (!ItemAdd(bb, 0))
|
|
|
return;
|
|
|
|
|
|
+ // Fraction < 0.0f will display an indeterminate progress bar animation
|
|
|
+ // The value must be animated along with time, so e.g. passing '-1.0f * ImGui::GetTime()' as fraction works.
|
|
|
+ const bool is_indeterminate = (fraction < 0.0f);
|
|
|
+ if (!is_indeterminate)
|
|
|
+ fraction = ImSaturate(fraction);
|
|
|
+
|
|
|
// Out of courtesy we accept a NaN fraction without crashing
|
|
|
- fraction = ImSaturate(fraction);
|
|
|
- const float fraction_not_nan = (fraction == fraction) ? fraction : 0.0f;
|
|
|
+ float fill_n0 = 0.0f;
|
|
|
+ float fill_n1 = (fraction == fraction) ? fraction : 0.0f;
|
|
|
+
|
|
|
+ if (is_indeterminate)
|
|
|
+ {
|
|
|
+ const float fill_width_n = 0.2f;
|
|
|
+ fill_n0 = ImFmod(-fraction, 1.0f) * (1.0f + fill_width_n) - fill_width_n;
|
|
|
+ fill_n1 = ImSaturate(fill_n0 + fill_width_n);
|
|
|
+ fill_n0 = ImSaturate(fill_n0);
|
|
|
+ }
|
|
|
|
|
|
// Render
|
|
|
RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
|
bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize));
|
|
|
- const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction_not_nan), bb.Max.y);
|
|
|
- RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction_not_nan, style.FrameRounding);
|
|
|
+ RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), fill_n0, fill_n1, style.FrameRounding);
|
|
|
|
|
|
// Default displaying the fraction as percentage string, but user can override it
|
|
|
- char overlay_buf[32];
|
|
|
- if (!overlay)
|
|
|
+ // Don't display text for indeterminate bars by default
|
|
|
+ if (!is_indeterminate || overlay != NULL)
|
|
|
{
|
|
|
- ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f);
|
|
|
- overlay = overlay_buf;
|
|
|
- }
|
|
|
+ char overlay_buf[32];
|
|
|
+ if (!overlay)
|
|
|
+ {
|
|
|
+ ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f);
|
|
|
+ overlay = overlay_buf;
|
|
|
+ }
|
|
|
|
|
|
- ImVec2 overlay_size = CalcTextSize(overlay, NULL);
|
|
|
- if (overlay_size.x > 0.0f)
|
|
|
- RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
|
|
|
+ ImVec2 overlay_size = CalcTextSize(overlay, NULL);
|
|
|
+ if (overlay_size.x > 0.0f)
|
|
|
+ {
|
|
|
+ float text_x = is_indeterminate ? (bb.Min.x + bb.Max.x - overlay_size.x) * 0.5f : ImLerp(bb.Min.x, bb.Max.x, fill_n1) + style.ItemSpacing.x;
|
|
|
+ RenderTextClipped(ImVec2(ImClamp(text_x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void ImGui::Bullet()
|
|
@@ -6190,13 +6212,17 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|
|
label_end = FindRenderedTextEnd(label);
|
|
|
const ImVec2 label_size = CalcTextSize(label, label_end, false);
|
|
|
|
|
|
+ const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing
|
|
|
+ const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it
|
|
|
+ const float text_width = g.FontSize + label_size.x + padding.x * 2; // Include collapsing arrow
|
|
|
+
|
|
|
// We vertically grow up to current line height up the typical widget height.
|
|
|
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2);
|
|
|
const bool span_all_columns = (flags & ImGuiTreeNodeFlags_SpanAllColumns) != 0 && (g.CurrentTable != NULL);
|
|
|
ImRect frame_bb;
|
|
|
frame_bb.Min.x = span_all_columns ? window->ParentWorkRect.Min.x : (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x;
|
|
|
frame_bb.Min.y = window->DC.CursorPos.y;
|
|
|
- frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x;
|
|
|
+ frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanTextWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x;
|
|
|
frame_bb.Max.y = window->DC.CursorPos.y + frame_height;
|
|
|
if (display_frame)
|
|
|
{
|
|
@@ -6206,15 +6232,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|
|
frame_bb.Max.x += IM_TRUNC(window->WindowPadding.x * 0.5f);
|
|
|
}
|
|
|
|
|
|
- const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing
|
|
|
- const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it
|
|
|
- const float text_width = g.FontSize + label_size.x + padding.x * 2; // Include collapsing arrow
|
|
|
ImVec2 text_pos(window->DC.CursorPos.x + text_offset_x, window->DC.CursorPos.y + text_offset_y);
|
|
|
ItemSize(ImVec2(text_width, frame_height), padding.y);
|
|
|
|
|
|
// For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing
|
|
|
ImRect interact_bb = frame_bb;
|
|
|
- if (!display_frame && (flags & (ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0)
|
|
|
+ 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);
|
|
|
|
|
|
// Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable..
|