Inputs: Internal: added SetItemUsingMouseWheel() and mechanism to request mouse wheel for both HoveredId and ActiveId. (#2891)

Based on @kudaba PR.
This commit is contained in:
ocornut 2020-12-25 17:52:01 +01:00
parent eb88fee052
commit fa963b9aaf
3 changed files with 28 additions and 4 deletions

View File

@ -3026,6 +3026,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
// Clear declaration of inputs claimed by the widget // Clear declaration of inputs claimed by the widget
// (Please note that this is WIP and not all keys/inputs are thoroughly declared by all widgets yet) // (Please note that this is WIP and not all keys/inputs are thoroughly declared by all widgets yet)
g.ActiveIdUsingMouseWheel = false;
g.ActiveIdUsingNavDirMask = 0x00; g.ActiveIdUsingNavDirMask = 0x00;
g.ActiveIdUsingNavInputMask = 0x00; g.ActiveIdUsingNavInputMask = 0x00;
g.ActiveIdUsingKeyInputMask = 0x00; g.ActiveIdUsingKeyInputMask = 0x00;
@ -3041,6 +3042,7 @@ void ImGui::SetHoveredID(ImGuiID id)
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
g.HoveredId = id; g.HoveredId = id;
g.HoveredIdAllowOverlap = false; g.HoveredIdAllowOverlap = false;
g.HoveredIdUsingMouseWheel = false;
if (id != 0 && g.HoveredIdPreviousFrame != id) if (id != 0 && g.HoveredIdPreviousFrame != id)
g.HoveredIdTimer = g.HoveredIdNotActiveTimer = 0.0f; g.HoveredIdTimer = g.HoveredIdNotActiveTimer = 0.0f;
} }
@ -3606,6 +3608,9 @@ void ImGui::UpdateMouseWheel()
if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f) if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f)
return; return;
if ((g.ActiveId != 0 && g.ActiveIdUsingMouseWheel) || (g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrameUsingMouseWheel))
return;
ImGuiWindow* window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow; ImGuiWindow* window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
if (!window || window->Collapsed) if (!window || window->Collapsed)
return; return;
@ -3839,8 +3844,10 @@ void ImGui::NewFrame()
if (g.HoveredId && g.ActiveId != g.HoveredId) if (g.HoveredId && g.ActiveId != g.HoveredId)
g.HoveredIdNotActiveTimer += g.IO.DeltaTime; g.HoveredIdNotActiveTimer += g.IO.DeltaTime;
g.HoveredIdPreviousFrame = g.HoveredId; g.HoveredIdPreviousFrame = g.HoveredId;
g.HoveredIdPreviousFrameUsingMouseWheel = g.HoveredIdUsingMouseWheel;
g.HoveredId = 0; g.HoveredId = 0;
g.HoveredIdAllowOverlap = false; g.HoveredIdAllowOverlap = false;
g.HoveredIdUsingMouseWheel = false;
g.HoveredIdDisabled = false; g.HoveredIdDisabled = false;
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore) // Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
@ -4768,12 +4775,23 @@ bool ImGui::IsItemEdited()
void ImGui::SetItemAllowOverlap() void ImGui::SetItemAllowOverlap()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (g.HoveredId == g.CurrentWindow->DC.LastItemId) ImGuiID id = g.CurrentWindow->DC.LastItemId;
if (g.HoveredId == id)
g.HoveredIdAllowOverlap = true; g.HoveredIdAllowOverlap = true;
if (g.ActiveId == g.CurrentWindow->DC.LastItemId) if (g.ActiveId == id)
g.ActiveIdAllowOverlap = true; g.ActiveIdAllowOverlap = true;
} }
void ImGui::SetItemUsingMouseWheel()
{
ImGuiContext& g = *GImGui;
ImGuiID id = g.CurrentWindow->DC.LastItemId;
if (g.HoveredId == id)
g.HoveredIdUsingMouseWheel = true;
if (g.ActiveId == id)
g.ActiveIdUsingMouseWheel = true;
}
ImVec2 ImGui::GetItemRectMin() ImVec2 ImGui::GetItemRectMin()
{ {
ImGuiWindow* window = GetCurrentWindowRead(); ImGuiWindow* window = GetCurrentWindowRead();

View File

@ -59,7 +59,7 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.80 WIP" #define IMGUI_VERSION "1.80 WIP"
#define IMGUI_VERSION_NUM 17908 #define IMGUI_VERSION_NUM 17909
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE

View File

@ -1275,9 +1275,11 @@ struct ImGuiContext
float WheelingWindowTimer; float WheelingWindowTimer;
// Item/widgets state and tracking information // Item/widgets state and tracking information
ImGuiID HoveredId; // Hovered widget ImGuiID HoveredId; // Hovered widget, filled during the frame
ImGuiID HoveredIdPreviousFrame; ImGuiID HoveredIdPreviousFrame;
bool HoveredIdAllowOverlap; bool HoveredIdAllowOverlap;
bool HoveredIdUsingMouseWheel; // Hovered widget will use mouse wheel. Blocks scrolling the underlying window.
bool HoveredIdPreviousFrameUsingMouseWheel;
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0. bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
float HoveredIdTimer; // Measure contiguous hovering time float HoveredIdTimer; // Measure contiguous hovering time
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
@ -1290,6 +1292,7 @@ struct ImGuiContext
bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch. bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state. bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
bool ActiveIdHasBeenEditedThisFrame; bool ActiveIdHasBeenEditedThisFrame;
bool ActiveIdUsingMouseWheel; // Active widget will want to read mouse wheel. Blocks scrolling the underlying window.
ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it) ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
ImU32 ActiveIdUsingNavInputMask; // Active widget will want to read those nav inputs. ImU32 ActiveIdUsingNavInputMask; // Active widget will want to read those nav inputs.
ImU64 ActiveIdUsingKeyInputMask; // Active widget will want to read those key inputs. When we grow the ImGuiKey enum we'll need to either to order the enum to make useful keys come first, either redesign this into e.g. a small array. ImU64 ActiveIdUsingKeyInputMask; // Active widget will want to read those key inputs. When we grow the ImGuiKey enum we'll need to either to order the enum to make useful keys come first, either redesign this into e.g. a small array.
@ -1501,6 +1504,7 @@ struct ImGuiContext
HoveredId = HoveredIdPreviousFrame = 0; HoveredId = HoveredIdPreviousFrame = 0;
HoveredIdAllowOverlap = false; HoveredIdAllowOverlap = false;
HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false;
HoveredIdDisabled = false; HoveredIdDisabled = false;
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f; HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
ActiveId = 0; ActiveId = 0;
@ -1512,6 +1516,7 @@ struct ImGuiContext
ActiveIdHasBeenPressedBefore = false; ActiveIdHasBeenPressedBefore = false;
ActiveIdHasBeenEditedBefore = false; ActiveIdHasBeenEditedBefore = false;
ActiveIdHasBeenEditedThisFrame = false; ActiveIdHasBeenEditedThisFrame = false;
ActiveIdUsingMouseWheel = false;
ActiveIdUsingNavDirMask = 0x00; ActiveIdUsingNavDirMask = 0x00;
ActiveIdUsingNavInputMask = 0x00; ActiveIdUsingNavInputMask = 0x00;
ActiveIdUsingKeyInputMask = 0x00; ActiveIdUsingKeyInputMask = 0x00;
@ -2267,6 +2272,7 @@ namespace ImGui
// Inputs // Inputs
// FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions. // FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
IMGUI_API void SetItemUsingMouseWheel();
inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; } 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 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 IsActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; IM_ASSERT(key < 64); return (g.ActiveIdUsingKeyInputMask & ((ImU64)1 << key)) != 0; }