Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_demo.cpp
This commit is contained in:
ocornut 2023-10-18 19:45:19 +02:00
commit 2a6d7b1eaa
6 changed files with 155 additions and 117 deletions

View File

@ -67,15 +67,17 @@ Breaking changes:
Other changes:
- Tooltips: made using SetItemTooltip()/IsItemHovered(ImGuiHoveredFlags_ForTooltip) defaults to
activate tooltips on disabled items. This is done by adding ImGuiHoveredFlags_AllowWhenDisabled
to the default value of style.HoverFlagsForTooltipMouse/HoverFlagsForTooltipNav. (#1485)
- Nav: Tabbing always enable nav highlight when ImGuiConfigFlags_NavEnableKeyboard is set.
Previously was inconsistent and only enabled when stepping through a non-input item.
(#6802, #3092, #5759, #787)
- Separator(): Altered end-points to use more standard boundaries. (#205, #4787, #1643)
- Left position is always current cursor X position.
- Right position is always work-rect rightmost edge.
- Windows:
- Popups: clarified meaning of 'p_open != NULL' in BeginPopupModal() + set back user value
to false when popup is closed in ways other than clicking the close button. (#6900)
- Can also auto-resize by double-clicking lower-left resize grip (not only lower-right one).
- Separators:
- Altered end-points to use more standard boundaries. (#205, #4787, #1643)
Left position is always current cursor X position.
Right position is always work-rect rightmost edge.
- Effectively means that:
- A separator in the root of a window will end up a little more distant from edges
than previously (essentially following WindowPadding instead of clipping edges).
@ -87,13 +89,17 @@ Other changes:
- Mostly legacy behavior when used inside old Columns(), as we favored that idiom back then,
only different is left position follows indentation level, to match calling a Separator()
inside or outside Columns().
- Popups: clarified meaning of 'p_open != NULL' in BeginPopupModal() + set back user value
to false when popup is closed in ways other than clicking the close button. (#6900)
- Drag and Drop: Rework drop target highlight: reduce rectangle to its visible portion, and
then expand slightly. A full rectangle is always visible and it may protrude slightly. (#4281, #3272)
- Drag and Drop: Fixed submitting a tooltip from drop target location when using AcceptDragDropPayload()
with ImGuiDragDropFlags_AcceptNoPreviewTooltip and submitting a tooltip manually.
- TreeNode: Added ImGuiTreeNodeFlags_SpanAllColumns for use in tables. (#3151, #3565, #2451, #2438)
- Tooltips:
- Made using SetItemTooltip()/IsItemHovered(ImGuiHoveredFlags_ForTooltip) defaults to
activate tooltips on disabled items. This is done by adding ImGuiHoveredFlags_AllowWhenDisabled
to the default value of style.HoverFlagsForTooltipMouse/HoverFlagsForTooltipNav. (#1485)
- Made is possible to combine ImGuiHoveredFlags_ForTooltip with a ImGuiHoveredFlags_DelayXXX
override. (#1485)
- Drag and Drop:
- Reworked drop target highlight: reduce rectangle to its visible portion, and
then expand slightly. A full rectangle is always visible and it may protrude slightly. (#4281, #3272)
- Fixed submitting a tooltip from drop target location when using AcceptDragDropPayload()
with ImGuiDragDropFlags_AcceptNoPreviewTooltip and submitting a tooltip manually.
- Tables:
- Added angled headers support. You need to set ImGuiTableColumnFlags_AngledHeader on selected
columns and call TableAngledHeadersRow(). Added style.TableAngledHeadersAngle style option.
@ -105,18 +111,20 @@ Other changes:
so a scrolling table can contribute to initial window size. (#6510)
- Fixed subtle drawing overlap between borders in some situations.
- Fixed bottom-most and right-most outer border offset by one. (#6765, #3752) [@v-ein]
- Fixed top-most and left-most outer border overlapping inner clip-rect when scrolling. (#6765)
- Fixed top-most outer border being drawn with both TableBorderLight and TableBorderStrong
in some situations, causing the earlier to be visible underneath when alpha is not 1.0f.
- fixed right-clicking right-most section (past right-most column) from highlighting a column.
- Fixed right-clicking right-most section (past right-most column) from highlighting a column.
- Fixed an issue with ScrollX enabled where an extraneous draw command would be created.
- Menus:
- Menus: Fixed a bug where activating an item in a child-menu and dragging mouse over the
parent-menu would erroneously close the child-menu. (Regression from 1.88). (#6869)
- MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously
register contents size in a way that would affect the scrolling layer.
Was most often noticable when using an horizontal scrollbar. (#6789)
- TreeNode: Added ImGuiTreeNodeFlags_SpanAllColumns for use in tables. (#3151, #3565, #2451, #2438)
- TabBar: Fixed position of unsaved document marker (ImGuiTabItemFlags_UnsavedDocument) which was
accidentally offset in 1.89.9. (#6862) [@alektron]
- Fonts: 'float size_pixels' passed to AddFontXXX() functions is now rounded to lowest integer.
This is because our layout/font system currently doesn't fully support non-integer sizes. Until
it does, this has been a common pitfall leading to more or less subtle issues. (#3164, #3309, #6800)
- Fonts: Better assert during load when passing truncated font data or wrong data size. (#6822)
- Fonts: Ensure calling AddFontXXX function doesn't invalidates ImFont's ConfigData pointers
prior to building again. (#6825)
- Fonts, imgui_freetype: Fixed a warning and leak in IMGUI_ENABLE_FREETYPE_LUNASVG support. (#6842, #6591)
- InputTextMultiline: Fixed a crash pressing Down on last empty line of a multiline buffer.
(regression from 1.89.2, only happened in some states). (#6783, #6000)
- InputTextMultiline: Fixed Tabbing cycle leading to a situation where Enter key wouldn't
@ -125,11 +133,14 @@ Other changes:
to SameLine() followed by manual cursor manipulation.
- BeginCombo(): Added ImGuiComboFlags_WidthFitPreview flag. (#6881) [@mpv-enjoyer]
- BeginListBox(): Fixed not consuming SetNextWindowXXX data when returning false.
- Menus: Fixed a bug where activating an item in a child-menu and dragging mouse over the
parent-menu would erroneously close the child-menu. (Regression from 1.88). (#6869)
- MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously
register contents size in a way that would affect the scrolling layer.
Was most often noticable when using an horizontal scrollbar. (#6789)
- Fonts:
- Arument 'float size_pixels' passed to AddFontXXX() functions is now rounded to lowest integer.
This is because our layout/font system currently doesn't fully support non-integer sizes. Until
it does, this has been a common pitfall leading to more or less subtle issues. (#3164, #3309, #6800)
- Better assert during load when passing truncated font data or wrong data size. (#6822)
- Ensure calling AddFontXXX function doesn't invalidates ImFont's ConfigData pointers
prior to building again. (#6825)
- imgui_freetype: Fixed a warning and leak in IMGUI_ENABLE_FREETYPE_LUNASVG support. (#6842, #6591)
- Misc: Most text functions also treat "%.*s" (along with "%s") specially to avoid formatting. (#3466, #6846)
- IO: Add extra keys to ImGuiKey enum: ImGuiKey_F13 to ImGuiKey_F24. (#6891, #4921)
- IO: Add extra keys to ImGuiKey enum: ImGuiKey_AppBack, ImGuiKey_AppForward. (#4921)

143
imgui.cpp
View File

@ -2538,11 +2538,9 @@ void ImGuiStorage::SetInt(ImGuiID key, int val)
{
ImGuiStoragePair* it = LowerBound(Data, key);
if (it == Data.end() || it->key != key)
{
Data.insert(it, ImGuiStoragePair(key, val));
return;
}
it->val_i = val;
else
it->val_i = val;
}
void ImGuiStorage::SetBool(ImGuiID key, bool val)
@ -2554,22 +2552,18 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val)
{
ImGuiStoragePair* it = LowerBound(Data, key);
if (it == Data.end() || it->key != key)
{
Data.insert(it, ImGuiStoragePair(key, val));
return;
}
it->val_f = val;
else
it->val_f = val;
}
void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val)
{
ImGuiStoragePair* it = LowerBound(Data, key);
if (it == Data.end() || it->key != key)
{
Data.insert(it, ImGuiStoragePair(key, val));
return;
}
it->val_p = val;
else
it->val_p = val;
}
void ImGuiStorage::SetAllInt(int v)
@ -4098,13 +4092,21 @@ bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flag
static inline float CalcDelayFromHoveredFlags(ImGuiHoveredFlags flags)
{
ImGuiContext& g = *GImGui;
if (flags & ImGuiHoveredFlags_DelayShort)
return g.Style.HoverDelayShort;
if (flags & ImGuiHoveredFlags_DelayNormal)
return g.Style.HoverDelayNormal;
if (flags & ImGuiHoveredFlags_DelayShort)
return g.Style.HoverDelayShort;
return 0.0f;
}
static ImGuiHoveredFlags ApplyHoverFlagsForTooltip(ImGuiHoveredFlags user_flags, ImGuiHoveredFlags shared_flags)
{
// Allow instance flags to override shared flags
if (user_flags & (ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal))
shared_flags &= ~(ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal);
return user_flags | shared_flags;
}
// This is roughly matching the behavior of internal-facing ItemHoverable()
// - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()
// - this should work even for non-interactive items that have no ID, so we cannot use LastItemId
@ -4122,7 +4124,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
return false;
if (flags & ImGuiHoveredFlags_ForTooltip)
flags |= g.Style.HoverFlagsForTooltipNav;
flags = ApplyHoverFlagsForTooltip(flags, g.Style.HoverFlagsForTooltipNav);
}
else
{
@ -4132,7 +4134,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
return false;
if (flags & ImGuiHoveredFlags_ForTooltip)
flags |= g.Style.HoverFlagsForTooltipMouse;
flags = ApplyHoverFlagsForTooltip(flags, g.Style.HoverFlagsForTooltipMouse);
IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_DockHierarchy)) == 0); // Flags not supported by this function
@ -5686,18 +5688,28 @@ ImVec2 ImGui::GetItemRectSize()
return g.LastItemData.Rect.GetSize();
}
bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags)
bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags)
{
ImGuiID id = GetCurrentWindow()->GetID(str_id);
return BeginChildEx(str_id, id, size_arg, border, window_flags);
}
bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags)
{
IM_ASSERT(id != 0);
return BeginChildEx(NULL, id, size_arg, border, window_flags);
}
bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* parent_window = g.CurrentWindow;
flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoDocking;
flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoDocking;
window_flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag
// Size
const ImVec2 content_avail = GetContentRegionAvail();
ImVec2 size = ImTrunc(size_arg);
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 + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too many issues)
if (size.y <= 0.0f)
@ -5714,12 +5726,13 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
const float backup_border_size = g.Style.ChildBorderSize;
if (!border)
g.Style.ChildBorderSize = 0.0f;
bool ret = Begin(temp_window_name, NULL, flags);
// Begin into window
const bool ret = Begin(temp_window_name, NULL, window_flags);
g.Style.ChildBorderSize = backup_border_size;
ImGuiWindow* child_window = g.CurrentWindow;
child_window->ChildId = id;
child_window->AutoFitChildAxises = (ImS8)auto_fit_axises;
// Set the cursor to handle case where the user called SetNextWindowPos()+BeginChild() manually.
// While this is not really documented/defined, it seems that the expected thing to do.
@ -5727,11 +5740,11 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
parent_window->DC.CursorPos = child_window->Pos;
// Process navigation-in immediately so NavInit can run on first frame
// Can enter a child if (A) it has navigatable items or (B) it can be scrolled.
// Can enter a child if (A) it has navigable items or (B) it can be scrolled.
const ImGuiID temp_id_for_activation = ImHashStr("##Child", 0, id);
if (g.ActiveId == temp_id_for_activation)
ClearActiveID();
if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY))
if (g.NavActivateId == id && !(window_flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY))
{
FocusWindow(child_window);
NavInitWindow(child_window, false);
@ -5741,50 +5754,29 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
return ret;
}
bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
{
ImGuiWindow* window = GetCurrentWindow();
return BeginChildEx(str_id, window->GetID(str_id), size_arg, border, extra_flags);
}
bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
{
IM_ASSERT(id != 0);
return BeginChildEx(NULL, id, size_arg, border, extra_flags);
}
void ImGui::EndChild()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiWindow* child_window = g.CurrentWindow;
IM_ASSERT(g.WithinEndChild == false);
IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() calls
IM_ASSERT(child_window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() calls
g.WithinEndChild = true;
if (window->BeginCount > 1)
ImVec2 child_size = child_window->Size;
End();
if (child_window->BeginCount == 1)
{
End();
}
else
{
ImVec2 sz = window->Size;
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 & (1 << ImGuiAxis_Y))
sz.y = ImMax(4.0f, sz.y);
End();
ImGuiWindow* parent_window = g.CurrentWindow;
ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz);
ItemSize(sz);
if ((window->DC.NavLayersActiveMask != 0 || window->DC.NavWindowHasScrollY) && !(window->Flags & ImGuiWindowFlags_NavFlattened))
ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + child_size);
ItemSize(child_size);
if ((child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY) && !(child_window->Flags & ImGuiWindowFlags_NavFlattened))
{
ItemAdd(bb, window->ChildId);
RenderNavHighlight(bb, window->ChildId);
ItemAdd(bb, child_window->ChildId);
RenderNavHighlight(bb, child_window->ChildId);
// When browsing a window that has no activable items (scroll only) we keep a highlight on the child (pass g.NavId to trick into always displaying)
if (window->DC.NavLayersActiveMask == 0 && window == g.NavWindow)
if (child_window->DC.NavLayersActiveMask == 0 && child_window == g.NavWindow)
RenderNavHighlight(ImRect(bb.Min - ImVec2(2, 2), bb.Max + ImVec2(2, 2)), g.NavId, ImGuiNavHighlightFlags_TypeThin);
}
else
@ -5793,10 +5785,10 @@ void ImGui::EndChild()
ItemAdd(bb, 0);
// But when flattened we directly reach items, adjust active layer mask accordingly
if (window->Flags & ImGuiWindowFlags_NavFlattened)
parent_window->DC.NavLayersActiveMaskNext |= window->DC.NavLayersActiveMaskNext;
if (child_window->Flags & ImGuiWindowFlags_NavFlattened)
parent_window->DC.NavLayersActiveMaskNext |= child_window->DC.NavLayersActiveMaskNext;
}
if (g.HoveredWindow == window)
if (g.HoveredWindow == child_window)
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
}
g.WithinEndChild = false;
@ -6202,7 +6194,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
if (hovered || held)
g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
if (held && g.IO.MouseClickedCount[0] == 2 && resize_grip_n == 0)
if (held && g.IO.MouseClickedCount[0] == 2)
{
// Manual auto-fit when double-clicking
size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit);
@ -6731,7 +6723,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->IDStack.push_back(window->ID);
// Add to stack
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
g.CurrentWindow = window;
ImGuiWindowStackData window_stack_data;
window_stack_data.Window = window;
@ -6749,6 +6740,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
}
// Add to focus scope stack
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
PushFocusScope(window->ID);
window->NavRootFocusScopeId = g.CurrentFocusScopeId;
g.CurrentWindow = NULL;
@ -7934,7 +7926,7 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
// for different windows of the hierarchy. Possibly need a Hash(Current+Flags) ==> (Timer) cache.
// We can implement this for _Stationary because the data is linked to HoveredWindow rather than CurrentWindow.
if (flags & ImGuiHoveredFlags_ForTooltip)
flags |= g.Style.HoverFlagsForTooltipMouse;
flags = ApplyHoverFlagsForTooltip(flags, g.Style.HoverFlagsForTooltipMouse);
if ((flags & ImGuiHoveredFlags_Stationary) != 0 && g.HoverWindowUnlockedStationaryId != ref_window->ID)
return false;
@ -9758,16 +9750,10 @@ void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags)
}
}
bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
// This is equivalent to comparing KeyMods + doing a IsKeyPressed()
bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
{
ImGuiContext& g = *GImGui;
// When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any.
if ((flags & ImGuiInputFlags_RouteMask_) == 0)
flags |= ImGuiInputFlags_RouteFocused;
if (!SetShortcutRouting(key_chord, owner_id, flags))
return false;
if (key_chord & ImGuiMod_Shortcut)
key_chord = ConvertShortcutMod(key_chord);
ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_);
@ -9778,11 +9764,22 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
if (key == ImGuiKey_None)
key = ConvertSingleModFlagToKey(&g, mods);
if (!IsKeyPressed(key, owner_id, (flags & (ImGuiInputFlags_Repeat | (ImGuiInputFlags)ImGuiInputFlags_RepeatRateMask_))))
return false;
IM_ASSERT((flags & ~ImGuiInputFlags_SupportedByShortcut) == 0); // Passing flags not supported by this function!
return true;
}
bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
{
// When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any.
if ((flags & ImGuiInputFlags_RouteMask_) == 0)
flags |= ImGuiInputFlags_RouteFocused;
if (!SetShortcutRouting(key_chord, owner_id, flags))
return false;
if (!IsKeyChordPressed(key_chord, owner_id, flags))
return false;
IM_ASSERT((flags & ~ImGuiInputFlags_SupportedByShortcut) == 0); // Passing flags not supported by this function!
return true;
}

17
imgui.h
View File

@ -349,8 +349,8 @@ namespace ImGui
// [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu,
// BeginPopup/EndPopup, etc. where the EndXXX call should only be called if the corresponding BeginXXX function
// returned true. Begin and BeginChild are the only odd ones out. Will be fixed in a future update.]
IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0);
IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0);
IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags window_flags = 0);
IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags window_flags = 0);
IMGUI_API void EndChild();
// Windows Utilities
@ -2465,9 +2465,9 @@ struct ImGuiStorage
{
ImGuiID key;
union { int val_i; float val_f; void* val_p; };
ImGuiStoragePair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }
ImGuiStoragePair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; }
ImGuiStoragePair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; }
ImGuiStoragePair(ImGuiID _key, int _val) { key = _key; val_i = _val; }
ImGuiStoragePair(ImGuiID _key, float _val) { key = _key; val_f = _val; }
ImGuiStoragePair(ImGuiID _key, void* _val) { key = _key; val_p = _val; }
};
ImVector<ImGuiStoragePair> Data;
@ -2494,11 +2494,10 @@ struct ImGuiStorage
IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0.0f);
IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL);
// Use on your own storage if you know only integer are being stored (open/close all tree nodes)
IMGUI_API void SetAllInt(int val);
// For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once.
// Advanced: for quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once.
IMGUI_API void BuildSortByKey();
// Obsolete: use on your own storage if you know only integer are being stored (open/close all tree nodes)
IMGUI_API void SetAllInt(int val);
};
// Helper: Manually clip large list of items.

View File

@ -1256,6 +1256,14 @@ static void ShowDemoWindowWidgets()
if (ImGui::CheckboxFlags("ImGuiComboFlags_WidthFitPreview", &flags, ImGuiComboFlags_WidthFitPreview))
flags &= ~ImGuiComboFlags_NoPreview;
// Override default popup height
if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightSmall", &flags, ImGuiComboFlags_HeightSmall))
flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightSmall);
if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightRegular", &flags, ImGuiComboFlags_HeightRegular))
flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightRegular);
if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightLargest", &flags, ImGuiComboFlags_HeightLargest))
flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightLargest);
// Using the generic BeginCombo() API, you have full control over how to display the combo contents.
// (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively
// stored in the object itself, etc.)
@ -1277,6 +1285,10 @@ static void ShowDemoWindowWidgets()
ImGui::EndCombo();
}
ImGui::Spacing();
ImGui::SeparatorText("One-liner variants");
HelpMarker("Flags above don't apply to this section.");
// Simplified one-liner Combo() API, using values packed in a single constant string
// This is a convenience for when the selection set is small and known at compile-time.
static int item_current_2 = 0;
@ -5283,6 +5295,7 @@ static void ShowDemoWindowTables()
ImGui::CheckboxFlags("_HighlightHoveredColumn", &table_flags, ImGuiTableFlags_HighlightHoveredColumn);
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
ImGui::SliderInt("Frozen columns", &frozen_cols, 0, 2);
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
ImGui::SliderInt("Frozen rows", &frozen_rows, 0, 2);
if (ImGui::BeginTable("table_angled_headers", columns_count, table_flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 12)))
@ -6661,7 +6674,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
"Right-click to open edit options menu.");
ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened);
ImGui::PushItemWidth(-160);
ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
for (int i = 0; i < ImGuiCol_COUNT; i++)
{
const char* name = ImGui::GetStyleColorName(i);

View File

@ -1272,9 +1272,9 @@ struct IMGUI_API ImGuiStackSizes
// Data saved for each window pushed into the stack
struct ImGuiWindowStackData
{
ImGuiWindow* Window;
ImGuiLastItemData ParentLastItemDataBackup;
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
ImGuiWindow* Window;
ImGuiLastItemData ParentLastItemDataBackup;
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
};
struct ImGuiShrinkWidthItem
@ -2660,7 +2660,6 @@ struct IMGUI_API ImGuiWindow
short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused.
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
ImS8 AutoFitFramesX, AutoFitFramesY;
ImS8 AutoFitChildAxises;
bool AutoFitOnlyGrows;
ImGuiDir AutoPosLastDirection;
ImS8 HiddenFramesCanSkipItems; // Hide the window for N frames
@ -3256,7 +3255,7 @@ namespace ImGui
IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix);
// Popups, Modals, Tooltips
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags);
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags);
IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
@ -3380,6 +3379,10 @@ namespace ImGui
// - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route.
// - Multiple read sites may use the same owner id and will all get the granted route.
// - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location.
// - TL;DR;
// - IsKeyChordPressed() compares mods + call IsKeyPressed() -> function has no side-effect.
// - Shortcut() submits a route then if currently can be routed calls IsKeyChordPressed() -> function has (desirable) side-effects.
IMGUI_API bool IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags = 0);
IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id);

View File

@ -445,6 +445,18 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
// Make left and top borders not overlap our contents by offsetting HostClipRect (#6765)
// (we normally shouldn't alter HostClipRect as we rely on TableMergeDrawChannels() expanding non-clipped column toward the
// limits of that rectangle, in order for ImDrawListSplitter::Merge() to merge the draw commands. However since the overlap
// problem only affect scrolling tables in this case we can get away with doing it without extra cost).
if (inner_window != outer_window)
{
if (flags & ImGuiTableFlags_BordersOuterV)
table->HostClipRect.Min.x = ImMin(table->HostClipRect.Min.x + TABLE_BORDER_SIZE, table->HostClipRect.Max.x);
if (flags & ImGuiTableFlags_BordersOuterH)
table->HostClipRect.Min.y = ImMin(table->HostClipRect.Min.y + TABLE_BORDER_SIZE, table->HostClipRect.Max.y);
}
// Padding and Spacing
// - None ........Content..... Pad .....Content........
// - PadOuter | Pad ..Content..... Pad .....Content.. Pad |
@ -1149,7 +1161,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->InnerClipRect.Max.x = ImMin(table->InnerClipRect.Max.x, unused_x1);
}
table->InnerWindow->ParentWorkRect = table->WorkRect;
table->BorderX1 = table->InnerClipRect.Min.x + ((table->Flags & ImGuiTableFlags_BordersOuterV) ? 1.0f : 0.0f);
table->BorderX1 = table->InnerClipRect.Min.x;
table->BorderX2 = table->InnerClipRect.Max.x;
// Setup window's WorkRect.Max.y for GetContentRegionAvail(). Other values will be updated in each TableBeginCell() call.
@ -3015,11 +3027,14 @@ void ImGui::TableHeader(const char* label)
// Calculate ideal size for sort order arrow
float w_arrow = 0.0f;
float w_sort_text = 0.0f;
bool sort_arrow = false;
char sort_order_suf[4] = "";
const float ARROW_SCALE = 0.65f;
if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort))
{
w_arrow = ImTrunc(g.FontSize * ARROW_SCALE + g.Style.FramePadding.x);
if (column->SortOrder != -1)
sort_arrow = true;
if (column->SortOrder > 0)
{
ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf), "%d", column->SortOrder + 1);
@ -3027,9 +3042,9 @@ void ImGui::TableHeader(const char* label)
}
}
// We feed our unclipped width to the column without writing on CursorMaxPos, so that column is still considering for merging.
// We feed our unclipped width to the column without writing on CursorMaxPos, so that column is still considered for merging.
float max_pos_x = label_pos.x + label_size.x + w_sort_text + w_arrow;
column->ContentMaxXHeadersUsed = ImMax(column->ContentMaxXHeadersUsed, column->WorkMaxX);
column->ContentMaxXHeadersUsed = ImMax(column->ContentMaxXHeadersUsed, sort_arrow ? cell_r.Max.x : ImMin(max_pos_x, cell_r.Max.x));
column->ContentMaxXHeadersIdeal = ImMax(column->ContentMaxXHeadersIdeal, max_pos_x);
// Keep header highlighted when context menu is open.