mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-27 16:29:02 +08:00
Overlap: Added 'SetNextItemAllowOverlap()' as a replacement for 'SetItemAllowOverlap()'. (#6512, #3909, #517)
# Conflicts: # imgui.cpp # imgui_widgets.cpp
This commit is contained in:
parent
a9a5cbf431
commit
8439a73645
@ -40,7 +40,12 @@ Breaking changes:
|
||||
As the fields were added in 1.89 and expected to be left unchanged by most users, or only
|
||||
tweaked once during app initialisation, we are exceptionally accepting the breakage.
|
||||
Majority of users should not even notice.
|
||||
- Overlapping items: (#6512, #3909)
|
||||
- Overlapping items: (#6512, #3909, #517)
|
||||
- Added 'SetNextItemAllowOverlap()' (called before an item) as a replacement for using
|
||||
'SetItemAllowOverlap()' (called after an item). This is roughly equivalent to using the
|
||||
legacy 'SetItemAllowOverlap()' call (public API) + ImGuiButtonFlags_AllowOverlap (internal).
|
||||
- Obsoleted 'SetItemAllowOverlap()': it didn't and couldn't work reliably since 1.89 (2022-11-15),
|
||||
and relied on ambiguously defined design. Use 'SetNextItemAllowOverlap()' before item instead.
|
||||
- Renamed 'ImGuiTreeNodeFlags_AllowItemOverlap' to 'ImGuiTreeNodeFlags_AllowOverlap'.
|
||||
- Renamed 'ImGuiSelectableFlags_AllowItemOverlap' to 'ImGuiSelectableFlags_AllowOverlap'
|
||||
- Kept redirecting enums (will obsolete).
|
||||
|
16
imgui.cpp
16
imgui.cpp
@ -397,6 +397,7 @@ CODE
|
||||
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
||||
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||
|
||||
- 2023/06/28 (1.89.7) - overlapping items: obsoleted 'SetItemAllowOverlap()' (called after item) in favor of calling 'SetNextItemAllowOverlap()' (called before item). 'SetItemAllowOverlap()' didn't and couldn't work reliably since 1.89 (2022-11-15).
|
||||
- 2023/06/28 (1.89.7) - overlapping items: renamed 'ImGuiTreeNodeFlags_AllowItemOverlap' to 'ImGuiTreeNodeFlags_AllowOverlap', 'ImGuiSelectableFlags_AllowItemOverlap' to 'ImGuiSelectableFlags_AllowOverlap'. Kept redirecting enums (will obsolete).
|
||||
- 2023/06/20 (1.89.7) - moved io.HoverDelayShort/io.HoverDelayNormal to style.HoverDelayShort/style.HoverDelayNormal. As the fields were added in 1.89 and expected to be left unchanged by most users, or only tweaked once during app initialization, we are exceptionally accepting the breakage.
|
||||
- 2023/05/30 (1.89.6) - backends: renamed "imgui_impl_sdlrenderer.cpp" to "imgui_impl_sdlrenderer2.cpp" and "imgui_impl_sdlrenderer.h" to "imgui_impl_sdlrenderer2.h". This is in prevision for the future release of SDL3.
|
||||
@ -5284,17 +5285,28 @@ bool ImGui::IsItemEdited()
|
||||
return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Edited) != 0;
|
||||
}
|
||||
|
||||
// Allow next item to be overlapped by subsequent items.
|
||||
// This works by requiring HoveredId to match for two subsequent frames,
|
||||
// so if a following items overwrite it our interactions will naturally be disabled.
|
||||
void ImGui::SetNextItemAllowOverlap()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.NextItemData.ItemFlags |= ImGuiItemflags_AllowOverlap;
|
||||
}
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
|
||||
// FIXME: Although this is exposed, its interaction and ideal idiom with using ImGuiButtonFlags_AllowOverlap flag are extremely confusing, need rework.
|
||||
// FIXME-LEGACY: Use SetNextItemAllowOverlap() *before* your item instead.
|
||||
void ImGui::SetItemAllowOverlap()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiID id = g.LastItemData.ID;
|
||||
if (g.HoveredId == id)
|
||||
g.HoveredIdAllowOverlap = true;
|
||||
if (g.ActiveId == id)
|
||||
if (g.ActiveId == id) // Before we made this obsolete, most calls to SetItemAllowOverlap() used to avoid this path by testing g.ActiveId != id.
|
||||
g.ActiveIdAllowOverlap = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// FIXME: It might be undesirable that this will likely disable KeyOwner-aware shortcuts systems. Consider a more fine-tuned version for the two users of this function.
|
||||
void ImGui::SetActiveIdUsingAllKeyboardKeys()
|
||||
|
8
imgui.h
8
imgui.h
@ -23,7 +23,7 @@
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.89.7 WIP"
|
||||
#define IMGUI_VERSION_NUM 18966
|
||||
#define IMGUI_VERSION_NUM 18967
|
||||
#define IMGUI_HAS_TABLE
|
||||
|
||||
/*
|
||||
@ -839,6 +839,9 @@ namespace ImGui
|
||||
IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window.
|
||||
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget.
|
||||
|
||||
// Overlapping mode
|
||||
IMGUI_API void SetNextItemAllowOverlap(); // allow next item to be overlapped by a subsequent item. Useful with invisible buttons, selectable, treenode covering an area where subsequent items may need to be added. Note that both Selectable() and TreeNode() have dedicated flags doing this.
|
||||
|
||||
// Item/Widgets Utilities and Query Functions
|
||||
// - Most of the functions are referring to the previous Item that has been submitted.
|
||||
// - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions.
|
||||
@ -859,7 +862,6 @@ namespace ImGui
|
||||
IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space)
|
||||
IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space)
|
||||
IMGUI_API ImVec2 GetItemRectSize(); // get size of last item
|
||||
IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area.
|
||||
|
||||
// Viewports
|
||||
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
|
||||
@ -3072,6 +3074,8 @@ namespace ImGui
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
namespace ImGui
|
||||
{
|
||||
// OBSOLETED in 1.89.7 (from June 2023)
|
||||
IMGUI_API void SetItemAllowOverlap(); // Use SetNextItemAllowOverlap() before item.
|
||||
// OBSOLETED in 1.89.4 (from March 2023)
|
||||
static inline void PushAllowKeyboardFocus(bool tab_stop) { PushTabStop(tab_stop); }
|
||||
static inline void PopAllowKeyboardFocus() { PopTabStop(); }
|
||||
|
@ -802,6 +802,7 @@ enum ImGuiItemFlags_
|
||||
ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
|
||||
ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
|
||||
ImGuiItemFlags_NoWindowHoverableCheck = 1 << 8, // false // Disable hoverable check in ItemHoverable()
|
||||
ImGuiItemflags_AllowOverlap = 1 << 9, // false // Allow being overlapped by another widget. Not-hovered to Hovered transition deferred by a frame.
|
||||
|
||||
// Controlled by widget code
|
||||
ImGuiItemFlags_Inputable = 1 << 10, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature.
|
||||
@ -861,7 +862,7 @@ enum ImGuiButtonFlagsPrivate_
|
||||
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
|
||||
ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat
|
||||
ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
|
||||
ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
|
||||
ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable.
|
||||
ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED]
|
||||
//ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled
|
||||
ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
|
||||
@ -1179,7 +1180,7 @@ enum ImGuiNextItemDataFlags_
|
||||
struct ImGuiNextItemData
|
||||
{
|
||||
ImGuiNextItemDataFlags Flags;
|
||||
ImGuiItemFlags ItemFlags;
|
||||
ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemflags_AllowOverlap.
|
||||
float Width; // Set by SetNextItemWidth()
|
||||
ImGuiID FocusScopeId; // Set by SetNextItemMultiSelectData() (!= 0 signify value has been set, so it's an alternate version of HasSelectionData, we don't use Flags for this because they are cleared too early. This is mostly used for debugging)
|
||||
ImGuiCond OpenCond;
|
||||
|
@ -2962,8 +2962,6 @@ void ImGui::TableHeader(const char* label)
|
||||
// Using AllowOverlap mode because we cover the whole cell, and we want user to be able to submit subsequent items.
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowOverlap);
|
||||
if (g.ActiveId != id)
|
||||
SetItemAllowOverlap();
|
||||
if (held || hovered || selected)
|
||||
{
|
||||
const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
|
||||
|
@ -496,6 +496,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
const ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags);
|
||||
if (item_flags & ImGuiItemFlags_ButtonRepeat)
|
||||
flags |= ImGuiButtonFlags_Repeat;
|
||||
if (item_flags & ImGuiItemflags_AllowOverlap)
|
||||
flags |= ImGuiButtonFlags_AllowOverlap;
|
||||
|
||||
ImGuiWindow* backup_hovered_window = g.HoveredWindow;
|
||||
const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindow == window;
|
||||
@ -529,8 +531,13 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
g.HoveredWindow = backup_hovered_window;
|
||||
|
||||
// AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one.
|
||||
if (hovered && (flags & ImGuiButtonFlags_AllowOverlap) && g.HoveredIdPreviousFrame != id)
|
||||
hovered = false;
|
||||
if (flags & ImGuiButtonFlags_AllowOverlap)
|
||||
{
|
||||
if (hovered && g.HoveredIdPreviousFrame != id)
|
||||
hovered = false;
|
||||
if (g.HoveredId == id) // FIXME: Added this to match legacy SetItemAllowOverlap(). Investigate precise side-effects of using (hovered==true) instead?
|
||||
g.HoveredIdAllowOverlap = true;
|
||||
}
|
||||
|
||||
// Mouse handling
|
||||
const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id;
|
||||
@ -1546,14 +1553,20 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float
|
||||
if (!ItemAdd(bb, id, NULL, ImGuiItemFlags_NoNav))
|
||||
return false;
|
||||
|
||||
// FIXME: AFAIK the only leftover reason for passing ImGuiButtonFlags_AllowOverlap here is
|
||||
// to allow caller of SplitterBehavior() to call SetItemAllowOverlap() after the item.
|
||||
// Nowadays we would instead want to use SetNextItemAllowOverlap() before the item.
|
||||
ImGuiButtonFlags button_flags = ImGuiButtonFlags_FlattenChildren;
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
button_flags |= ImGuiButtonFlags_AllowOverlap;
|
||||
#endif
|
||||
|
||||
bool hovered, held;
|
||||
ImRect bb_interact = bb;
|
||||
bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f));
|
||||
ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowOverlap);
|
||||
ButtonBehavior(bb_interact, id, &hovered, &held, button_flags);
|
||||
if (hovered)
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect; // for IsItemHovered(), because bb_interact is larger than bb
|
||||
if (g.ActiveId != id) // Because: we don't want to hover other while Active
|
||||
SetItemAllowOverlap();
|
||||
|
||||
if (held || (hovered && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
|
||||
SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW);
|
||||
@ -6158,7 +6171,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
}
|
||||
|
||||
ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None;
|
||||
if (flags & ImGuiTreeNodeFlags_AllowOverlap)
|
||||
if ((flags & ImGuiTreeNodeFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap))
|
||||
button_flags |= ImGuiButtonFlags_AllowOverlap;
|
||||
if (!is_leaf)
|
||||
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
||||
@ -6232,8 +6245,6 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledOpen;
|
||||
}
|
||||
}
|
||||
if ((flags & ImGuiTreeNodeFlags_AllowOverlap) && g.ActiveId != id) // Because: we don't want to hover other while Active
|
||||
SetItemAllowOverlap();
|
||||
|
||||
// In this branch, TreeNodeBehavior() cannot toggle the selection so this will never trigger.
|
||||
if (selected != was_selected) //-V547
|
||||
@ -6490,7 +6501,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
if (flags & ImGuiSelectableFlags_SelectOnClick) { button_flags |= ImGuiButtonFlags_PressedOnClick; }
|
||||
if (flags & ImGuiSelectableFlags_SelectOnRelease) { button_flags |= ImGuiButtonFlags_PressedOnRelease; }
|
||||
if (flags & ImGuiSelectableFlags_AllowDoubleClick) { button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; }
|
||||
if (flags & ImGuiSelectableFlags_AllowOverlap) { button_flags |= ImGuiButtonFlags_AllowOverlap; }
|
||||
if ((flags & ImGuiSelectableFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap)) { button_flags |= ImGuiButtonFlags_AllowOverlap; }
|
||||
|
||||
const bool was_selected = selected;
|
||||
bool hovered, held;
|
||||
@ -6519,9 +6530,6 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
if (pressed)
|
||||
MarkItemEdited(id);
|
||||
|
||||
if ((flags & ImGuiSelectableFlags_AllowOverlap) && g.ActiveId != id) // Because: we don't want to hover other while Active
|
||||
SetItemAllowOverlap();
|
||||
|
||||
// In this branch, Selectable() cannot toggle the selection so this will never trigger.
|
||||
if (selected != was_selected) //-V547
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
|
||||
@ -8390,6 +8398,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
}
|
||||
|
||||
// Click to Select a tab
|
||||
// Allow the close button to overlap
|
||||
ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
|
||||
if (g.DragDropActive)
|
||||
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
||||
@ -8398,10 +8407,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
if (pressed && !is_tab_button)
|
||||
TabBarQueueFocus(tab_bar, tab);
|
||||
|
||||
// Allow the close button to overlap unless we are dragging (in which case we don't want any overlapping tabs or collapse/close button to be hovered)
|
||||
if (g.ActiveId != id) // Because: we don't want to hover other items while dragging active)
|
||||
SetItemAllowOverlap();
|
||||
|
||||
// Drag and drop: re-order tabs
|
||||
if (held && !tab_appearing && IsMouseDragging(0))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user