-
-
Notifications
You must be signed in to change notification settings - Fork 10.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Separating click and double-click events #8337
Comments
I took another look at how the other programs work. This is how I get a delay in a normal click. But in other programs, the click is triggered first. Then a double click. I guess I don't need such a complicated one. I will do as in other programs. |
It's very rare for application to make use of single click with "destructive" side-effects when a double-click is expected. const double time = ImGui::GetTime();
if (ImGui::IsMouseReleased(0))
my_mouse_released_time[0] = time; I believe that's the only storage you actually need that's missing. Then something like: bool IsMouseReleasedPending(ImGuiMouseButton mouse_button, float delay)
{
const float time_since_release = current_time - my_mouse_released_time[0];
const float dt = ImGui::GetIO().DeltaTime;
return !IsMouseDown(0) && time_since_release - dt < delay && time_since_release >= delay)
}; use with I would like to confirm that this can be used and I might add the data/function. |
@ocornut Well, personally, I've lost the need. Maybe I should explain why that's a bad thing. The code I provided actually adds a delay after release, and as a result, the trigger actually occurs after about 0.4-0.5 sec. I changed it so that it updates at release but using the time received during the click. And even in this case there is a delay after the click. It's very noticeable. The UI becomes terribly unsmooth. I looked at other software: Maxon Cinema 4D, Blender, Affinity Photo. In Affinity Photo, the action always happens after release. In Cinema 4D and Blender, it depends on the context. If the object is selected, the event after release is processed. If the object is not selected, the event after the click is triggered. I think that my task is non-trivial and depends on the context of use. That's why I don't think it's worth making it a part of ImGUI API. |
Yes that's obviously the only way to distinguish single click from double-click.
It's even most complicated than that usually (multi-select api needs to change quite a few edge cases) but yeah that's the basics of it.
Even if rare, some apps use the delayed reactions on mouse release. MS Explorer uses that for renaming. |
You are probably right. And by the way, I now also think that this is quite enough. We can look at pending and, depending on the result, check the number of clicks or wait further. That is, it will be much easier to implement the necessary application logic with such the feature. |
I have pushed fdca6c0 with now adds a Example: ImGui::Button("XXXX", ImVec2(100, 100));
if (ImGui::IsItemHovered())
{
if (ImGui::IsMouseClicked(0))
IMGUI_DEBUG_LOG("IsMouseClicked\n");
if (ImGui::IsMouseReleased(0))
IMGUI_DEBUG_LOG("IsMouseReleased\n");
if (ImGui::IsMouseDoubleClicked(0))
IMGUI_DEBUG_LOG("IsMouseDoubleClicked\n");
if (ImGui::IsMouseReleasedWithDelay(0, io.MouseDoubleClickTime))
IMGUI_DEBUG_LOG("IsMouseReleasedWithDelay %f, count %d\n", io.MouseDoubleClickTime, io.MouseClickedLastCount[0]);
if (ImGui::IsMouseReleasedWithDelay(0, 1.0f))
IMGUI_DEBUG_LOG("IsMouseReleasedWithDelay %f, count %d\n", 1.0f, io.MouseClickedLastCount[0]);
} Note that it is likely important that you combine |
I really wanted to use your commit in my project, but since it checks the release time instead of the click time, it didn’t quite fit my use case. However, I think it's still a useful feature that might help others. auto &io = ImGui::GetIO();
if (object.selected)
{
if (ImGui::IsItemHovered() && ImGui::IsMouseDragging(0) && drag_item_id == 0)
{
drag_item_id = object.ptr->id;
logTrace("Dragging started (selected) for ID: %llx", drag_item_id);
}
if (ImGui::IsMouseReleased(0))
{
if (drag_item_id == object.ptr->id)
{
drag_item_id = 0;
logTrace("Dragging ended (selected) for ID: %llx", object.ptr->id);
}
else if (ImGui::IsItemHovered())
{
if (io.MouseClickedLastCount[0] >= 2)
{
object.editing = true;
logTrace("Double click (selected)");
}
else if (io.MouseClickedLastCount[0] == 1)
{
object.selected = true;
logTrace("Single click (selected)");
}
}
}
else if (drag_item_id == object.ptr->id)
{
logTrace("Dragging (active) for ID: %llx", object.ptr->id);
}
}
else if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0))
{
object.selected = true;
logTrace("Single click (unselected)");
} This behavior is similar to Cinema 4D or Blender, and everything seems to work fine—unless I missed something! Since my original question was about delayed single click detection, and that’s exactly what you implemented, I think we can close the issue. Great job, and thanks again! |
Reopening as I would like to reevaluate that. Maybe both are useful, maybe ReleasedWithDelay is not even useful. |
Version/Branch of Dear ImGui:
v1.91.8 WIP master
Back-ends:
custom
Compiler, OS:
Windows 11 + clang 18.1.8
Full config/build information:
No response
Details:
Hi,
I hope I'm not being too much of a bother ;)
I have a situation where I need to distinguish single click and double click events separately for an element. However, no matter what I try, I always run into one of these issues:
As a workaround, I implemented a structure similar to ImGui’s mouse state tracking. If MouseDoubleClickTime passes without a second click, I return a clickPended state. This works for me, but effectively, it's a simplified duplicate of ImGui’s internal context doing the same thing.
It would be great to have a native way to distinguish single clicks from double clicks, so they don't interfere with each other.
Would it be possible to introduce a built-in mechanism in ImGui to separate click and double-click logic more cleanly?
Screenshots/Video:
No response
Minimal, Complete and Verifiable Example code:
Here I also handle dragging since the click event is also triggered if the mouse is released (But ImGui has DragAPI to get around this, but that's just for the record.)
Example Callee code:
The text was updated successfully, but these errors were encountered: