mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-22 11:57:00 +00:00
(Breaking) Internals: added ImGuiItemFlags param to ItemHoverable(), so it can be called from ButtonBehavior() not following an ItemAdd().
This also allow moving AllowOverlap logic from ButtonBehavior() to ItemHoverable(), allowing other widgets to honor it. (#6512, #3909, #517)
This commit is contained in:
parent
10c7709f30
commit
4dee919bc0
@ -4038,7 +4038,8 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered().
|
// Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered().
|
||||||
bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
// (this does not rely on LastItemData it can be called from a ButtonBehavior() call not following an ItemAdd() call)
|
||||||
|
bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
@ -4053,7 +4054,6 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Done with rectangle culling so we can perform heavier checks now.
|
// Done with rectangle culling so we can perform heavier checks now.
|
||||||
ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags);
|
|
||||||
if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
|
if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
|
||||||
{
|
{
|
||||||
g.HoveredIdDisabled = true;
|
g.HoveredIdDisabled = true;
|
||||||
@ -12360,7 +12360,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
|
|||||||
// Rely on keeping other window->LastItemXXX fields intact.
|
// Rely on keeping other window->LastItemXXX fields intact.
|
||||||
source_id = g.LastItemData.ID = window->GetIDFromRectangle(g.LastItemData.Rect);
|
source_id = g.LastItemData.ID = window->GetIDFromRectangle(g.LastItemData.Rect);
|
||||||
KeepAliveID(source_id);
|
KeepAliveID(source_id);
|
||||||
bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id);
|
bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id, g.LastItemData.InFlags);
|
||||||
if (is_hovered && g.IO.MouseClicked[mouse_button])
|
if (is_hovered && g.IO.MouseClicked[mouse_button])
|
||||||
{
|
{
|
||||||
SetActiveID(source_id, window);
|
SetActiveID(source_id, window);
|
||||||
|
@ -2876,7 +2876,7 @@ namespace ImGui
|
|||||||
IMGUI_API void ItemSize(const ImVec2& size, float text_baseline_y = -1.0f);
|
IMGUI_API void ItemSize(const ImVec2& size, float text_baseline_y = -1.0f);
|
||||||
inline void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f) { ItemSize(bb.GetSize(), text_baseline_y); } // FIXME: This is a misleading API since we expect CursorPos to be bb.Min.
|
inline void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f) { ItemSize(bb.GetSize(), text_baseline_y); } // FIXME: This is a misleading API since we expect CursorPos to be bb.Min.
|
||||||
IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemFlags extra_flags = 0);
|
IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemFlags extra_flags = 0);
|
||||||
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
|
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags);
|
||||||
IMGUI_API bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags = 0);
|
IMGUI_API bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags = 0);
|
||||||
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id);
|
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id);
|
||||||
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
|
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
|
||||||
|
@ -976,7 +976,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
const ImRect mouse_hit_rect(table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.Max.x, ImMax(table->OuterRect.Max.y, table->OuterRect.Min.y + table_instance->LastOuterHeight));
|
const ImRect mouse_hit_rect(table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.Max.x, ImMax(table->OuterRect.Max.y, table->OuterRect.Min.y + table_instance->LastOuterHeight));
|
||||||
const ImGuiID backup_active_id = g.ActiveId;
|
const ImGuiID backup_active_id = g.ActiveId;
|
||||||
g.ActiveId = 0;
|
g.ActiveId = 0;
|
||||||
const bool is_hovering_table = ItemHoverable(mouse_hit_rect, 0);
|
const bool is_hovering_table = ItemHoverable(mouse_hit_rect, 0, ImGuiItemFlags_None);
|
||||||
g.ActiveId = backup_active_id;
|
g.ActiveId = backup_active_id;
|
||||||
|
|
||||||
// [Part 6] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column
|
// [Part 6] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column
|
||||||
|
@ -493,11 +493,12 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|||||||
flags |= ImGuiButtonFlags_PressedOnDefault_;
|
flags |= ImGuiButtonFlags_PressedOnDefault_;
|
||||||
|
|
||||||
// Default behavior inherited from item flags
|
// Default behavior inherited from item flags
|
||||||
const ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags);
|
// Note that _both_ ButtonFlags and ItemFlags are valid sources, so copy one into the item_flags and only check that.
|
||||||
if (item_flags & ImGuiItemFlags_ButtonRepeat)
|
ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags);
|
||||||
flags |= ImGuiButtonFlags_Repeat;
|
if (flags & ImGuiButtonFlags_AllowOverlap)
|
||||||
if (item_flags & ImGuiItemflags_AllowOverlap)
|
item_flags |= ImGuiItemflags_AllowOverlap;
|
||||||
flags |= ImGuiButtonFlags_AllowOverlap;
|
if (flags & ImGuiButtonFlags_Repeat)
|
||||||
|
item_flags |= ImGuiItemFlags_ButtonRepeat;
|
||||||
|
|
||||||
ImGuiWindow* backup_hovered_window = g.HoveredWindow;
|
ImGuiWindow* backup_hovered_window = g.HoveredWindow;
|
||||||
const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindow == window;
|
const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindow == window;
|
||||||
@ -511,7 +512,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool pressed = false;
|
bool pressed = false;
|
||||||
bool hovered = ItemHoverable(bb, id);
|
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
|
// 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))
|
if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers))
|
||||||
@ -531,7 +532,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|||||||
g.HoveredWindow = backup_hovered_window;
|
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.
|
// 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 (flags & ImGuiButtonFlags_AllowOverlap)
|
if (item_flags & ImGuiItemflags_AllowOverlap)
|
||||||
{
|
{
|
||||||
if (hovered && g.HoveredIdPreviousFrame != id)
|
if (hovered && g.HoveredIdPreviousFrame != id)
|
||||||
hovered = false;
|
hovered = false;
|
||||||
@ -587,7 +588,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|||||||
{
|
{
|
||||||
if (mouse_button_released != -1)
|
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)
|
if (!has_repeated_at_least_once)
|
||||||
pressed = true;
|
pressed = true;
|
||||||
if (!(flags & ImGuiButtonFlags_NoNavFocus))
|
if (!(flags & ImGuiButtonFlags_NoNavFocus))
|
||||||
@ -598,7 +599,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).
|
// '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.
|
// 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))
|
if (g.IO.MouseDownDuration[g.ActiveIdMouseButton] > 0.0f && IsMouseClicked(g.ActiveIdMouseButton, test_owner_id, ImGuiInputFlags_Repeat))
|
||||||
pressed = true;
|
pressed = true;
|
||||||
}
|
}
|
||||||
@ -616,7 +617,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_code = (g.NavActivateId == id);
|
||||||
bool nav_activated_by_inputs = (g.NavActivatePressedId == 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
|
// Avoid pressing multiple keys from triggering excessive amount of repeat events
|
||||||
const ImGuiKeyData* key1 = GetKeyData(ImGuiKey_Space);
|
const ImGuiKeyData* key1 = GetKeyData(ImGuiKey_Space);
|
||||||
@ -663,7 +664,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)
|
// 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_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);
|
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)
|
if (!is_double_click_release && !is_repeating_already && is_button_avail_or_owned)
|
||||||
pressed = true;
|
pressed = true;
|
||||||
@ -2421,7 +2422,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
|||||||
if (format == NULL)
|
if (format == NULL)
|
||||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
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);
|
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
|
||||||
if (!temp_input_is_active)
|
if (!temp_input_is_active)
|
||||||
{
|
{
|
||||||
@ -3014,7 +3015,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
|||||||
if (format == NULL)
|
if (format == NULL)
|
||||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
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);
|
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
|
||||||
if (!temp_input_is_active)
|
if (!temp_input_is_active)
|
||||||
{
|
{
|
||||||
@ -3181,7 +3182,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
|||||||
if (format == NULL)
|
if (format == NULL)
|
||||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
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);
|
const bool clicked = hovered && IsMouseClicked(0, id);
|
||||||
if (clicked || g.NavActivateId == id)
|
if (clicked || g.NavActivateId == id)
|
||||||
{
|
{
|
||||||
@ -4147,7 +4148,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
return false;
|
return false;
|
||||||
item_status_flags = g.LastItemData.StatusFlags;
|
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)
|
if (hovered)
|
||||||
g.MouseCursor = ImGuiMouseCursor_TextInput;
|
g.MouseCursor = ImGuiMouseCursor_TextInput;
|
||||||
|
|
||||||
@ -6714,7 +6715,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get
|
|||||||
ItemSize(total_bb, style.FramePadding.y);
|
ItemSize(total_bb, style.FramePadding.y);
|
||||||
if (!ItemAdd(total_bb, 0, &frame_bb))
|
if (!ItemAdd(total_bb, 0, &frame_bb))
|
||||||
return -1;
|
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
|
// Determine scale from values if not specified
|
||||||
if (scale_min == FLT_MAX || scale_max == FLT_MAX)
|
if (scale_min == FLT_MAX || scale_max == FLT_MAX)
|
||||||
|
Loading…
Reference in New Issue
Block a user