Skip to content

Commit b4d1287

Browse files
committed
Selectable: Clarifying the code around use of ImGuiSelectableFlags_DrawFillAvailWidth (with intent of trying to remove it).
Amend old 6251d37, 2bcafc8
1 parent 7c11997 commit b4d1287

File tree

3 files changed

+21
-18
lines changed

3 files changed

+21
-18
lines changed

imgui.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6818,6 +6818,8 @@ static void ImGui::ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool
68186818
//-----------------------------------------------------------------------------
68196819

68206820
// Advance cursor given item size for layout.
6821+
// Register minimum needed size so it can extend the bounding box used for auto-fit calculation.
6822+
// See comments in ItemAdd() about how/why the size provided to ItemSize() vs ItemAdd() may often different.
68216823
void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
68226824
{
68236825
ImGuiContext& g = *GImGui;
@@ -6858,7 +6860,7 @@ void ImGui::ItemSize(const ImRect& bb, float text_baseline_y)
68586860

68596861
// Declare item bounding box for clipping and interaction.
68606862
// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface
6861-
// declare their minimum size requirement to ItemSize() and then use a larger region for drawing/interaction, which is passed to ItemAdd().
6863+
// declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction.
68626864
bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg)
68636865
{
68646866
ImGuiContext& g = *GImGui;

imgui_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ enum ImGuiSelectableFlagsPrivate_
494494
ImGuiSelectableFlags_NoHoldingActiveID = 1 << 20,
495495
ImGuiSelectableFlags_SelectOnClick = 1 << 21, // Override button behavior to react on Click (default is Click+Release)
496496
ImGuiSelectableFlags_SelectOnRelease = 1 << 22, // Override button behavior to react on Release (default is Click+Release)
497-
ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 23, // FIXME: We may be able to remove this (added in 6251d379 for menus)
497+
ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 23, // Draw over all avail width even if we declared less for layout. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus)
498498
ImGuiSelectableFlags_DrawHoveredWhenHeld= 1 << 24, // Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow.
499499
ImGuiSelectableFlags_SetNavIdOnHover = 1 << 25
500500
};

imgui_widgets.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5578,15 +5578,11 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
55785578
ImRect bb_inner(pos, pos + size);
55795579
ItemSize(size, 0.0f);
55805580

5581-
// Fill horizontal space.
5582-
ImVec2 window_padding = window->WindowPadding;
5583-
float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x + window->Pos.x : GetContentRegionMaxAbs().x;
5584-
float w_draw = ImMax(label_size.x, max_x - window_padding.x - pos.x);
5585-
ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size.y);
5586-
5587-
ImRect bb_align(pos, pos + size_draw);
5581+
// Fill horizontal space
5582+
const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x + window->Pos.x : GetContentRegionMaxAbs().x;
55885583
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth))
5589-
bb_align.Max.x += window_padding.x;
5584+
size.x = ImMax(label_size.x, max_x - window->WindowPadding.x - pos.x) + window->WindowPadding.x;
5585+
ImRect bb_align(pos, pos + size);
55905586

55915587
// Selectables are meant to be tightly packed together with no click-gap, so we extend the box to cover spacing between selectable.
55925588
ImRect bb_enlarged = bb_align;
@@ -6228,10 +6224,12 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
62286224
else
62296225
{
62306226
// Menu inside a menu
6227+
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
6228+
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
62316229
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
6232-
float w = window->DC.MenuColumns.DeclColumns(label_size.x, 0.0f, IM_FLOOR(g.FontSize * 1.20f)); // Feedback to next frame
6233-
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w);
6234-
pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
6230+
float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, 0.0f, IM_FLOOR(g.FontSize * 1.20f)); // Feedback to next frame
6231+
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
6232+
pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(min_w, 0.0f));
62356233
ImU32 text_col = GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled);
62366234
RenderArrow(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), text_col, ImGuiDir_Right);
62376235
}
@@ -6376,11 +6374,14 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo
63766374
}
63776375
else
63786376
{
6379-
ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f);
6380-
float w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_size.x, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame
6381-
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w);
6382-
pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f));
6383-
if (shortcut_size.x > 0.0f)
6377+
// Menu item inside a vertical menu
6378+
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
6379+
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
6380+
float shortcut_w = shortcut ? CalcTextSize(shortcut, NULL).x : 0.0f;
6381+
float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_w, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame
6382+
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
6383+
pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(min_w, 0.0f));
6384+
if (shortcut_w > 0.0f)
63846385
{
63856386
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
63866387
RenderText(pos + ImVec2(window->DC.MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false);

0 commit comments

Comments
 (0)