Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered(). (this does not rely on LastItemData it can be called from a ButtonBehavior() call not following an ItemAdd() call) FIXME-LEGACY: the 'ImGuiItemFlags item_flags' parameter was added on 2023-06-28. If you used this in your legacy/custom widgets code: - Commonly: if your ItemHoverable() call comes aft
| 4077 | // - Commonly: if your ItemHoverable() call comes after an ItemAdd() call: pass 'item_flags = g.LastItemData.InFlags'. |
| 4078 | // - Rare: otherwise you may pass 'item_flags = 0' (ImGuiItemFlags_None) unless you want to benefit from special behavior handled by ItemHoverable. |
| 4079 | bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags) |
| 4080 | { |
| 4081 | ImGuiContext& g = *GImGui; |
| 4082 | ImGuiWindow* window = g.CurrentWindow; |
| 4083 | if (g.HoveredWindow != window) |
| 4084 | return false; |
| 4085 | if (!IsMouseHoveringRect(bb.Min, bb.Max)) |
| 4086 | return false; |
| 4087 | |
| 4088 | if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap) |
| 4089 | return false; |
| 4090 | if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap) |
| 4091 | return false; |
| 4092 | |
| 4093 | // Done with rectangle culling so we can perform heavier checks now. |
| 4094 | if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) |
| 4095 | { |
| 4096 | g.HoveredIdDisabled = true; |
| 4097 | return false; |
| 4098 | } |
| 4099 | |
| 4100 | // We exceptionally allow this function to be called with id==0 to allow using it for easy high-level |
| 4101 | // hover test in widgets code. We could also decide to split this function is two. |
| 4102 | if (id != 0) |
| 4103 | { |
| 4104 | // Drag source doesn't report as hovered |
| 4105 | if (g.DragDropActive && g.DragDropPayload.SourceId == id && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover)) |
| 4106 | return false; |
| 4107 | |
| 4108 | SetHoveredID(id); |
| 4109 | |
| 4110 | // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. |
| 4111 | // This allows using patterns where a later submitted widget overlaps a previous one. Generally perceived as a front-to-back hit-test. |
| 4112 | if (item_flags & ImGuiItemFlags_AllowOverlap) |
| 4113 | { |
| 4114 | g.HoveredIdAllowOverlap = true; |
| 4115 | if (g.HoveredIdPreviousFrame != id) |
| 4116 | return false; |
| 4117 | } |
| 4118 | } |
| 4119 | |
| 4120 | // When disabled we'll return false but still set HoveredId |
| 4121 | if (item_flags & ImGuiItemFlags_Disabled) |
| 4122 | { |
| 4123 | // Release active id if turning disabled |
| 4124 | if (g.ActiveId == id && id != 0) |
| 4125 | ClearActiveID(); |
| 4126 | g.HoveredIdDisabled = true; |
| 4127 | return false; |
| 4128 | } |
| 4129 | |
| 4130 | if (id != 0) |
| 4131 | { |
| 4132 | // [DEBUG] Item Picker tool! |
| 4133 | // We perform the check here because SetHoveredID() is not frequently called (1~ time a frame), making |
| 4134 | // the cost of this tool near-zero. We can get slightly better call-stack and support picking non-hovered |
| 4135 | // items if we performed the test in ItemAdd(), but that would incur a small runtime cost. |
| 4136 | if (g.DebugItemPickerActive && g.HoveredIdPreviousFrame == id) |
nothing calls this directly
no test coverage detected