mirror of
https://github.com/ocornut/imgui.git
synced 2026-07-05 09:05:20 +00:00
Added GetItemClickedCountWithSingleClickDelay(), io.MouseSingleClickDelay. (#8337)
This commit is contained in:
@@ -100,6 +100,15 @@ Other Changes:
|
||||
instead of _NavEnableGamepad. (#9454, #8803, #9270) [@Clownacy]
|
||||
- TreeNode:
|
||||
- Fixed nav cursor rendering with rounding even though tree nodes don't have it. (#7589)
|
||||
- Inputs:
|
||||
- Added GetItemClickedCountWithSingleClickDelay() helper for easy disambiguation
|
||||
between single-click and double-click for actions that needs single-click to do
|
||||
something other than selection. (#8337)
|
||||
- Returns 1 on single-click but delayed by io.MouseSingleClickDelay.
|
||||
- Returns 2 on double-click, and 2+ on subsequent repeated cicks.
|
||||
- Added io.MouseSingleClickDelay to configure default delayed single click delay when
|
||||
using GetItemClickedCountWithSingleClickDelay() or IsMouseReleasedWithDelay(). (#8337)
|
||||
Note that io.MouseSingleClickDelay is always > io.MouseDoubleClickTime.
|
||||
- Style:
|
||||
- Added style.MenuItemRounding, ImGuiStyleVar_MenuItemRounding. (#7589, #9375, #9453)
|
||||
- Added style.SelectableRounding, ImGuiStyleVar_SelectableRounding. (#7589, #9375, #9453)
|
||||
|
||||
67
imgui.cpp
67
imgui.cpp
@@ -1692,6 +1692,7 @@ ImGuiIO::ImGuiIO()
|
||||
// Inputs Behaviors
|
||||
MouseDoubleClickTime = 0.30f;
|
||||
MouseDoubleClickMaxDist = 6.0f;
|
||||
MouseSingleClickDelay = 0.50f;
|
||||
MouseDragThreshold = 6.0f;
|
||||
KeyRepeatDelay = 0.275f;
|
||||
KeyRepeatRate = 0.050f;
|
||||
@@ -9427,6 +9428,7 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
// - IsMouseReleased()
|
||||
// - IsMouseDoubleClicked()
|
||||
// - GetMouseClickedCount()
|
||||
// - GetItemClickedCountWithSingleClickDelay()
|
||||
// - IsMouseHoveringRect() [Internal]
|
||||
// - IsMouseDragPastThreshold() [Internal]
|
||||
// - IsMouseDragging()
|
||||
@@ -10006,6 +10008,8 @@ bool ImGui::IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id)
|
||||
return g.IO.MouseReleased[button] && TestKeyOwner(MouseButtonToKey(button), owner_id); // Should be same as IsKeyReleased(MouseButtonToKey(button), owner_id)
|
||||
}
|
||||
|
||||
|
||||
// Prefer higher-level helper GetItemClickedCountWithSingleClickDelay()
|
||||
// Use if you absolutely need to distinguish single-click from double-click by introducing a delay.
|
||||
// Generally use with 'delay >= io.MouseDoubleClickTime' + combined with a 'io.MouseClickedLastCount == 1' test.
|
||||
// This is a very rarely used UI idiom, but some apps use this: e.g. MS Explorer single click on an icon to rename.
|
||||
@@ -10013,8 +10017,12 @@ bool ImGui::IsMouseReleasedWithDelay(ImGuiMouseButton button, float delay)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(button >= 0 && button < IM_COUNTOF(g.IO.MouseDown));
|
||||
if (IsMouseDown(button))
|
||||
return false;
|
||||
if (delay < 0.0f)
|
||||
delay = g.IO.MouseSingleClickDelay;
|
||||
const float time_since_release = (float)(g.Time - g.IO.MouseReleasedTime[button]);
|
||||
return !IsMouseDown(button) && (time_since_release - g.IO.DeltaTime < delay) && (time_since_release >= delay);
|
||||
return (time_since_release - g.IO.DeltaTime < delay) && (time_since_release >= delay);
|
||||
}
|
||||
|
||||
bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button)
|
||||
@@ -10038,6 +10046,62 @@ int ImGui::GetMouseClickedCount(ImGuiMouseButton button)
|
||||
return g.IO.MouseClickedCount[button];
|
||||
}
|
||||
|
||||
// FIXME: This is close to what BeginDragDropSource() is doing, maybe rework.
|
||||
static ImGuiID LastItemOverlayButtonForNullId(ImGuiMouseButton mouse_button)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.LastItemData.ID == 0);
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiID id = window->GetIDFromRectangle(g.LastItemData.Rect);
|
||||
if (g.IO.MouseClicked[mouse_button] && ImGui::ItemHoverable(g.LastItemData.Rect, id, g.LastItemData.ItemFlags))
|
||||
{
|
||||
ImGui::SetActiveID(id, window);
|
||||
ImGui::FocusWindow(window);
|
||||
}
|
||||
else if (g.ActiveId == id)
|
||||
{
|
||||
ImGui::KeepAliveID(id);
|
||||
if (!g.IO.MouseDown[mouse_button])
|
||||
ImGui::ClearActiveID();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
// [BETA] Building block for disambiguation between single-click and double-click.
|
||||
// - Returns 1 on single-click but delayed by io.MouseSingleClickDelay (which is always > io.MouseDoubleClickTime) after mouse release.
|
||||
// - Returns 2+ on double-click and subsequent repeated clicks.
|
||||
// In order use that to replicate Windows Explorer's "click on label to rename after a delay",
|
||||
// When the function returns 1 for a delayed single click, you can add with further tests:
|
||||
// - If you want to test that the mouse position AT THE TIME of the click (before the delay): you can use the 'io.MouseClickedPos[mouse_button]' position.
|
||||
// - If you want to test that the mouse position is still over the item at the end of delay: you can use '&& IsItemHovered()'.
|
||||
// - If you want to test that the item was selected or the sole selection AT THE TIME of the click (before the delay): you can test for 'g.LastActiveIdWasSelected' or 'g.LastActiveIdWasSoleSelected'.
|
||||
// e.g.
|
||||
// int click_count = ImGui::GetItemClickedCountWithSingleClickDelay(mouse_button);
|
||||
// if (click_count == 1 && ImGui::GetCurrentContext()->LastActiveIdWasSoleSelected)
|
||||
// StartRename();
|
||||
// if (click_count == 2)
|
||||
// Launch();
|
||||
int ImGui::GetItemClickedCountWithSingleClickDelay(ImGuiMouseButton mouse_button, float delay)
|
||||
{
|
||||
// Action: double-click and subsequent clicks
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.IO.MouseClickedCount[mouse_button] >= 2 && IsItemClicked(mouse_button))
|
||||
return g.IO.MouseClickedCount[mouse_button];
|
||||
|
||||
// Action: second click, delayed
|
||||
ImGuiID id = g.LastItemData.ID;
|
||||
if (id == 0)
|
||||
id = LastItemOverlayButtonForNullId(mouse_button);
|
||||
if (g.LastActiveId == id)
|
||||
{
|
||||
if (delay >= 0.0f)
|
||||
delay = ImMax(delay, g.IO.MouseDoubleClickTime + 0.01f);
|
||||
if (IsMouseReleasedWithDelay(mouse_button, delay) && g.IO.MouseClickedLastCount[mouse_button] == 1)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Test if mouse cursor is hovering given rectangle
|
||||
// NB- Rectangle is clipped by our current clip setting
|
||||
// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding)
|
||||
@@ -10985,6 +11049,7 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
|
||||
IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right);
|
||||
IM_ASSERT(g.Style.ColorButtonPosition == ImGuiDir_Left || g.Style.ColorButtonPosition == ImGuiDir_Right);
|
||||
IM_ASSERT(g.Style.TreeLinesFlags == ImGuiTreeNodeFlags_DrawLinesNone || g.Style.TreeLinesFlags == ImGuiTreeNodeFlags_DrawLinesFull || g.Style.TreeLinesFlags == ImGuiTreeNodeFlags_DrawLinesToNodes);
|
||||
IM_ASSERT(g.IO.MouseSingleClickDelay > g.IO.MouseDoubleClickTime);
|
||||
|
||||
// Error handling: we do not accept 100% silent recovery! Please contact me if you feel this is getting in your way.
|
||||
if (g.IO.ConfigErrorRecovery)
|
||||
|
||||
8
imgui.h
8
imgui.h
@@ -1026,6 +1026,7 @@ namespace ImGui
|
||||
IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space)
|
||||
IMGUI_API ImVec2 GetItemRectSize(); // get size of last item
|
||||
IMGUI_API ImGuiItemFlags GetItemFlags(); // get generic flags of last item
|
||||
IMGUI_API int GetItemClickedCountWithSingleClickDelay(ImGuiMouseButton mouse_button = 0, float delay = -1.0f); // [BETA] building block for disambiguation between single-click and double-click. Returns 1 on single-click but delayed by io.MouseSingleClickDelay after mouse release. Returns 2+ on double-click or repeated clicks.
|
||||
|
||||
// Viewports
|
||||
// - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows.
|
||||
@@ -1108,7 +1109,7 @@ namespace ImGui
|
||||
IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down). Same as GetMouseClickedCount() == 1.
|
||||
IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down)
|
||||
IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? Same as GetMouseClickedCount() == 2. (note that a double-click will also report IsMouseClicked() == true)
|
||||
IMGUI_API bool IsMouseReleasedWithDelay(ImGuiMouseButton button, float delay); // delayed mouse release (use very sparingly!). Generally used with 'delay >= io.MouseDoubleClickTime' + combined with a 'io.MouseClickedLastCount==1' test. This is a very rarely used UI idiom, but some apps use this: e.g. MS Explorer single click on an icon to rename.
|
||||
IMGUI_API bool IsMouseReleasedWithDelay(ImGuiMouseButton button, float delay=-1.f);// delayed mouse release. Use sparingly. Prefer higher-level helper GetItemClickedCountWithSingleClickDelay(). Generally used with 'delay >= io.MouseDoubleClickTime' + combined with a 'io.MouseClickedLastCount==1' test.
|
||||
IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0).
|
||||
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
|
||||
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available
|
||||
@@ -2451,8 +2452,9 @@ struct ImGuiIO
|
||||
|
||||
// Inputs Behaviors
|
||||
// (other variables, ones which are expected to be tweaked within UI code, are exposed in ImGuiStyle)
|
||||
float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.
|
||||
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
|
||||
float MouseDoubleClickTime; // = 0.30f // Time for consecutive clicks to account as a double-click, in seconds.
|
||||
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click or multiple clicks, in pixels.
|
||||
float MouseSingleClickDelay; // = 0.60f // Time for a delayed click when using GetItemClickedCountWithSingleClickDelay() or IsMouseReleasedWithDelay(), in seconds. Must be > io.MouseDoubleClickTime.
|
||||
float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging.
|
||||
float KeyRepeatDelay; // = 0.275f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.).
|
||||
float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds.
|
||||
|
||||
Reference in New Issue
Block a user