|
@@ -492,6 +492,14 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0)
|
|
|
flags |= ImGuiButtonFlags_PressedOnDefault_;
|
|
|
|
|
|
+ // Default behavior inherited from item flags
|
|
|
+ // Note that _both_ ButtonFlags and ItemFlags are valid sources, so copy one into the item_flags and only check that.
|
|
|
+ ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags);
|
|
|
+ if (flags & ImGuiButtonFlags_AllowOverlap)
|
|
|
+ item_flags |= ImGuiItemflags_AllowOverlap;
|
|
|
+ if (flags & ImGuiButtonFlags_Repeat)
|
|
|
+ item_flags |= ImGuiItemFlags_ButtonRepeat;
|
|
|
+
|
|
|
ImGuiWindow* backup_hovered_window = g.HoveredWindow;
|
|
|
const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindowDockTree == window->RootWindowDockTree;
|
|
|
if (flatten_hovered_children)
|
|
@@ -504,11 +512,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
#endif
|
|
|
|
|
|
bool pressed = false;
|
|
|
- bool hovered = ItemHoverable(bb, id);
|
|
|
-
|
|
|
- // Drag source doesn't report as hovered
|
|
|
- if (hovered && g.DragDropActive && g.DragDropPayload.SourceId == id && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover))
|
|
|
- hovered = false;
|
|
|
+ bool hovered = ItemHoverable(bb, id, item_flags);
|
|
|
|
|
|
// Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button
|
|
|
if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers))
|
|
@@ -527,10 +531,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
if (flatten_hovered_children)
|
|
|
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_AllowItemOverlap) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0))
|
|
|
- hovered = false;
|
|
|
-
|
|
|
// Mouse handling
|
|
|
const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id;
|
|
|
if (hovered)
|
|
@@ -579,7 +579,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
{
|
|
|
if (mouse_button_released != -1)
|
|
|
{
|
|
|
- const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; // Repeat mode trumps on release behavior
|
|
|
+ const bool has_repeated_at_least_once = (item_flags & ImGuiItemFlags_ButtonRepeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; // Repeat mode trumps on release behavior
|
|
|
if (!has_repeated_at_least_once)
|
|
|
pressed = true;
|
|
|
if (!(flags & ImGuiButtonFlags_NoNavFocus))
|
|
@@ -590,7 +590,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
|
|
|
// 'Repeat' mode acts when held regardless of _PressedOn flags (see table above).
|
|
|
// Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings.
|
|
|
- if (g.ActiveId == id && (flags & ImGuiButtonFlags_Repeat))
|
|
|
+ if (g.ActiveId == id && (item_flags & ImGuiItemFlags_ButtonRepeat))
|
|
|
if (g.IO.MouseDownDuration[g.ActiveIdMouseButton] > 0.0f && IsMouseClicked(g.ActiveIdMouseButton, test_owner_id, ImGuiInputFlags_Repeat))
|
|
|
pressed = true;
|
|
|
}
|
|
@@ -608,7 +608,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
{
|
|
|
bool nav_activated_by_code = (g.NavActivateId == id);
|
|
|
bool nav_activated_by_inputs = (g.NavActivatePressedId == id);
|
|
|
- if (!nav_activated_by_inputs && (flags & ImGuiButtonFlags_Repeat))
|
|
|
+ if (!nav_activated_by_inputs && (item_flags & ImGuiItemFlags_ButtonRepeat))
|
|
|
{
|
|
|
// Avoid pressing multiple keys from triggering excessive amount of repeat events
|
|
|
const ImGuiKeyData* key1 = GetKeyData(ImGuiKey_Space);
|
|
@@ -655,7 +655,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
{
|
|
|
// Report as pressed when releasing the mouse (this is the most common path)
|
|
|
bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseReleased[mouse_button] && g.IO.MouseClickedLastCount[mouse_button] == 2;
|
|
|
- bool is_repeating_already = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps <on release>
|
|
|
+ bool is_repeating_already = (item_flags & ImGuiItemFlags_ButtonRepeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps <on release>
|
|
|
bool is_button_avail_or_owned = TestKeyOwner(MouseButtonToKey(mouse_button), test_owner_id);
|
|
|
if (!is_double_click_release && !is_repeating_already && is_button_avail_or_owned)
|
|
|
pressed = true;
|
|
@@ -702,9 +702,6 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
|
|
|
if (!ItemAdd(bb, id))
|
|
|
return false;
|
|
|
|
|
|
- if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat)
|
|
|
- flags |= ImGuiButtonFlags_Repeat;
|
|
|
-
|
|
|
bool hovered, held;
|
|
|
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
|
|
|
|
|
@@ -781,9 +778,6 @@ bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu
|
|
|
if (!ItemAdd(bb, id))
|
|
|
return false;
|
|
|
|
|
|
- if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat)
|
|
|
- flags |= ImGuiButtonFlags_Repeat;
|
|
|
-
|
|
|
bool hovered, held;
|
|
|
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
|
|
|
|
|
@@ -1174,10 +1168,8 @@ bool ImGui::CheckboxFlagsT(const char* label, T* flags, T flags_value)
|
|
|
if (!all_on && any_on)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
- ImGuiItemFlags backup_item_flags = g.CurrentItemFlags;
|
|
|
- g.CurrentItemFlags |= ImGuiItemFlags_MixedValue;
|
|
|
+ g.NextItemData.ItemFlags |= ImGuiItemFlags_MixedValue;
|
|
|
pressed = Checkbox(label, &all_on);
|
|
|
- g.CurrentItemFlags = backup_item_flags;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -1559,14 +1551,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_AllowItemOverlap);
|
|
|
+ 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)
|
|
|
- SetItemAllowOverlap();
|
|
|
|
|
|
if (held || (hovered && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
|
|
|
SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW);
|
|
@@ -2421,7 +2419,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
|
|
if (format == NULL)
|
|
|
format = DataTypeGetInfo(data_type)->PrintFmt;
|
|
|
|
|
|
- const bool hovered = ItemHoverable(frame_bb, id);
|
|
|
+ const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
|
|
|
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
|
|
|
if (!temp_input_is_active)
|
|
|
{
|
|
@@ -3014,7 +3012,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
|
|
if (format == NULL)
|
|
|
format = DataTypeGetInfo(data_type)->PrintFmt;
|
|
|
|
|
|
- const bool hovered = ItemHoverable(frame_bb, id);
|
|
|
+ const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
|
|
|
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
|
|
|
if (!temp_input_is_active)
|
|
|
{
|
|
@@ -3181,7 +3179,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
|
|
if (format == NULL)
|
|
|
format = DataTypeGetInfo(data_type)->PrintFmt;
|
|
|
|
|
|
- const bool hovered = ItemHoverable(frame_bb, id);
|
|
|
+ const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
|
|
|
const bool clicked = hovered && IsMouseClicked(0, id);
|
|
|
if (clicked || g.NavActivateId == id)
|
|
|
{
|
|
@@ -4147,7 +4145,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
return false;
|
|
|
item_status_flags = g.LastItemData.StatusFlags;
|
|
|
}
|
|
|
- const bool hovered = ItemHoverable(frame_bb, id);
|
|
|
+ const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
|
|
|
if (hovered)
|
|
|
g.MouseCursor = ImGuiMouseCursor_TextInput;
|
|
|
|
|
@@ -4971,11 +4969,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|
|
{
|
|
|
// For focus requests to work on our multiline we need to ensure our child ItemAdd() call specifies the ImGuiItemFlags_Inputable (ref issue #4761)...
|
|
|
Dummy(ImVec2(text_size.x, text_size.y + style.FramePadding.y));
|
|
|
- ImGuiItemFlags backup_item_flags = g.CurrentItemFlags;
|
|
|
- g.CurrentItemFlags |= ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop;
|
|
|
+ g.NextItemData.ItemFlags |= ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop;
|
|
|
EndChild();
|
|
|
item_data_backup.StatusFlags |= (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredWindow);
|
|
|
- g.CurrentItemFlags = backup_item_flags;
|
|
|
|
|
|
// ...and then we need to undo the group overriding last item data, which gets a bit messy as EndGroup() tries to forward scrollbar being active...
|
|
|
// FIXME: This quite messy/tricky, should attempt to get rid of the child window.
|
|
@@ -6174,8 +6170,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|
|
}
|
|
|
|
|
|
ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None;
|
|
|
- if (flags & ImGuiTreeNodeFlags_AllowItemOverlap)
|
|
|
- button_flags |= ImGuiButtonFlags_AllowItemOverlap;
|
|
|
+ if ((flags & ImGuiTreeNodeFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap))
|
|
|
+ button_flags |= ImGuiButtonFlags_AllowOverlap;
|
|
|
if (!is_leaf)
|
|
|
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
|
|
|
|
@@ -6248,8 +6244,6 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledOpen;
|
|
|
}
|
|
|
}
|
|
|
- if (flags & ImGuiTreeNodeFlags_AllowItemOverlap)
|
|
|
- SetItemAllowOverlap();
|
|
|
|
|
|
// In this branch, TreeNodeBehavior() cannot toggle the selection so this will never trigger.
|
|
|
if (selected != was_selected) //-V547
|
|
@@ -6269,7 +6263,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|
|
else if (!is_leaf)
|
|
|
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 1.0f);
|
|
|
else // Leaf without bullet, left-adjusted text
|
|
|
- text_pos.x -= text_offset_x;
|
|
|
+ text_pos.x -= text_offset_x -padding.x;
|
|
|
if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton)
|
|
|
frame_bb.Max.x -= g.FontSize + style.FramePadding.x;
|
|
|
|
|
@@ -6393,7 +6387,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl
|
|
|
ImGuiID id = window->GetID(label);
|
|
|
flags |= ImGuiTreeNodeFlags_CollapsingHeader;
|
|
|
if (p_visible)
|
|
|
- flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
|
|
|
+ flags |= ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
|
|
|
bool is_open = TreeNodeBehavior(id, flags, label);
|
|
|
if (p_visible != NULL)
|
|
|
{
|
|
@@ -6422,7 +6416,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl
|
|
|
|
|
|
// Tip: pass a non-visible label (e.g. "##hello") then you can use the space to draw other text or image.
|
|
|
// But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID or use ##unique_id.
|
|
|
-// With this scheme, ImGuiSelectableFlags_SpanAllColumns and ImGuiSelectableFlags_AllowItemOverlap are also frequently used flags.
|
|
|
+// With this scheme, ImGuiSelectableFlags_SpanAllColumns and ImGuiSelectableFlags_AllowOverlap are also frequently used flags.
|
|
|
// FIXME: Selectable() with (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported.
|
|
|
bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg)
|
|
|
{
|
|
@@ -6506,7 +6500,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_AllowItemOverlap) { button_flags |= ImGuiButtonFlags_AllowItemOverlap; }
|
|
|
+ if ((flags & ImGuiSelectableFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap)) { button_flags |= ImGuiButtonFlags_AllowOverlap; }
|
|
|
|
|
|
const bool was_selected = selected;
|
|
|
bool hovered, held;
|
|
@@ -6535,9 +6529,6 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|
|
if (pressed)
|
|
|
MarkItemEdited(id);
|
|
|
|
|
|
- if (flags & ImGuiSelectableFlags_AllowItemOverlap)
|
|
|
- SetItemAllowOverlap();
|
|
|
-
|
|
|
// In this branch, Selectable() cannot toggle the selection so this will never trigger.
|
|
|
if (selected != was_selected) //-V547
|
|
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
|
|
@@ -6722,7 +6713,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get
|
|
|
ItemSize(total_bb, style.FramePadding.y);
|
|
|
if (!ItemAdd(total_bb, 0, &frame_bb))
|
|
|
return -1;
|
|
|
- const bool hovered = ItemHoverable(frame_bb, id);
|
|
|
+ const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
|
|
|
|
|
|
// Determine scale from values if not specified
|
|
|
if (scale_min == FLT_MAX || scale_max == FLT_MAX)
|
|
@@ -8464,7 +8455,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|
|
}
|
|
|
|
|
|
// Click to Select a tab
|
|
|
- ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowItemOverlap);
|
|
|
+ ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
|
|
|
if (g.DragDropActive && !g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW)) // FIXME: May be an opt-in property of the payload to disable this
|
|
|
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
|
|
bool hovered, held;
|
|
@@ -8477,10 +8468,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|
|
if (held && docked_window && g.ActiveId == id && g.ActiveIdIsJustActivated)
|
|
|
g.ActiveIdWindow = docked_window;
|
|
|
|
|
|
- // Allow the close button to overlap unless we are dragging (in which case we don't want any overlapping tabs to be hovered)
|
|
|
- if (g.ActiveId != id)
|
|
|
- SetItemAllowOverlap();
|
|
|
-
|
|
|
// Drag and drop a single floating window node moves it
|
|
|
ImGuiDockNode* node = docked_window ? docked_window->DockNode : NULL;
|
|
|
const bool single_floating_window_node = node && node->IsFloatingNode() && (node->Windows.Size == 1);
|