Skip to content

Commit

Permalink
MouseWheel: Add functions to allow a hovered items to block imgui fro…
Browse files Browse the repository at this point in the history
…m processing mouse wheel events in various scenarios.
  • Loading branch information
kudaba committed Nov 12, 2019
1 parent 6e8e2c0 commit 33e9986
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
29 changes: 28 additions & 1 deletion imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2724,6 +2724,7 @@ void ImGui::SetHoveredID(ImGuiID id)
ImGuiContext& g = *GImGui;
g.HoveredId = id;
g.HoveredIdAllowOverlap = false;
g.HoveredIdUsingMouseWheel = false;
if (id != 0 && g.HoveredIdPreviousFrame != id)
g.HoveredIdTimer = g.HoveredIdNotActiveTimer = 0.0f;
}
Expand Down Expand Up @@ -3360,6 +3361,9 @@ void ImGui::UpdateMouseWheel()
if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f)
return;

if (IsHoveredIdUsingMouseWheel())
return;

ImGuiWindow* window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
if (!window || window->Collapsed)
return;
Expand Down Expand Up @@ -3648,6 +3652,8 @@ void ImGui::NewFrame()
// Mouse wheel scrolling, scale
UpdateMouseWheel();

g.HoveredIdUsingMouseWheel = false; // clear after processing mouse wheel

// Pressing TAB activate widget focus
g.FocusTabPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab));
if (g.ActiveId == 0 && g.FocusTabPressed)
Expand Down Expand Up @@ -4510,6 +4516,27 @@ void ImGui::SetItemAllowOverlap()
g.ActiveIdAllowOverlap = true;
}

void ImGui::SetItemUsesMouseWheel()
{
ImGuiContext& g = *GImGui;
if (g.HoveredId == g.CurrentWindow->DC.LastItemId)
g.HoveredIdUsingMouseWheel = true;
}

void ImGui::SetActiveItemUsesMouseWheel()
{
ImGuiContext& g = *GImGui;
SetActiveItemUsesMouseWheel(g.CurrentWindow->DC.LastItemId);
}

void ImGui::SetActiveItemUsesMouseWheel(ImGuiID id)
{
IM_ASSERT(id != 0);
ImGuiContext& g = *GImGui;
if (g.ActiveId == id && g.HoveredId == g.CurrentWindow->DC.LastItemId)
g.HoveredIdUsingMouseWheel = true;
}

ImVec2 ImGui::GetItemRectMin()
{
ImGuiWindow* window = GetCurrentWindowRead();
Expand Down Expand Up @@ -9870,7 +9897,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
const char* input_source_names[] = { "None", "Mouse", "Nav", "NavKeyboard", "NavGamepad" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT);
ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL");
ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Blocks Mouse Wheel: %s", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap, g.HoveredIdUsingMouseWheel ? "Yes" : "No"); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, input_source_names[g.ActiveIdSource]);
ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
ImGui::Text("MovingWindow: '%s'", g.MovingWindow ? g.MovingWindow->Name : "NULL");
Expand Down
6 changes: 6 additions & 0 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,7 @@ struct ImGuiContext
// Item/widgets state and tracking information
ImGuiID HoveredId; // Hovered widget
bool HoveredIdAllowOverlap;
bool HoveredIdUsingMouseWheel; // When hovered, the widget blocks imgui from processing mouse wheel (i.e. scrolling)
ImGuiID HoveredIdPreviousFrame;
float HoveredIdTimer; // Measure contiguous hovering time
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
Expand Down Expand Up @@ -1129,6 +1130,7 @@ struct ImGuiContext

HoveredId = 0;
HoveredIdAllowOverlap = false;
HoveredIdUsingMouseWheel = false;
HoveredIdPreviousFrame = 0;
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
ActiveId = 0;
Expand Down Expand Up @@ -1636,11 +1638,15 @@ namespace ImGui
inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; }
inline bool IsActiveIdUsingNavInput(ImGuiNavInput input) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavInputMask & (1 << input)) != 0; }
inline bool IsActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; IM_ASSERT(key < 64); return (g.ActiveIdUsingKeyInputMask & ((ImU64)1 << key)) != 0; }
inline bool IsHoveredIdUsingMouseWheel() { ImGuiContext& g = *GImGui; return g.HoveredIdUsingMouseWheel; }
IMGUI_API bool IsMouseDragPastThreshold(int button, float lock_threshold = -1.0f);
inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { ImGuiContext& g = *GImGui; const int key_index = g.IO.KeyMap[key]; return (key_index >= 0) ? IsKeyPressed(key_index, repeat) : false; }
inline bool IsNavInputDown(ImGuiNavInput n) { ImGuiContext& g = *GImGui; return g.IO.NavInputs[n] > 0.0f; }
inline bool IsNavInputPressed(ImGuiNavInput n, ImGuiInputReadMode mode) { return GetNavInputAmount(n, mode) > 0.0f; }
inline bool IsNavInputPressedAnyOfTwo(ImGuiNavInput n1, ImGuiNavInput n2, ImGuiInputReadMode mode) { return (GetNavInputAmount(n1, mode) + GetNavInputAmount(n2, mode)) > 0.0f; }
IMGUI_API void SetItemUsesMouseWheel(); // block Imgui from using mouse wheel when last item is hovered.
IMGUI_API void SetActiveItemUsesMouseWheel(); // block Imgui from using mouse wheel when last item is hovered AND active.
IMGUI_API void SetActiveItemUsesMouseWheel(ImGuiID id); // block Imgui from using mouse wheel when last item is hovered AND the given ID is active. Used when making composite controls where the active item isn't the hovered item.

// Drag and Drop
IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id);
Expand Down

0 comments on commit 33e9986

Please sign in to comment.