Update InputFloat value with mouse wheel
Version/Branch of Dear ImGui:
Version: 1.83 Branch: docking
Back-end/Renderer/Compiler/OS
Back-ends: SDL2 + Vulkan Compiler: MSVC 16.9 Operating System: Windows 10
My Issue/Question:
I am trying to allow to increase or decrease InputFloat field value by scrolling mouse wheel while the field is hovered by mouse cursor. I managed to do so (see below for my provided example). However, when the window has vertical scrollbar my solution works only when the window scroll is at its limits, e.g. when the window is scrolled to the top, value in the hovered field can only be increased with the mouse wheel -- scrolling the mouse wheel down causes the window to scroll down and the value remains unchanged (note that when the widget is "active" it is deactivated at the first mouse wheel action, otherwise the value is changed only temporarily -- for one frame).
Could someone give me some pointers on how to proceed from here?
Screenshots/Video

Standalone, minimal, complete and verifiable example: (see https://github.com/ocornut/imgui/issues/2261)
bool InputFloatWithScroll( const char* label, float* v, const char* format, ImGuiInputTextFlags flags, float scrolStep )
{
const bool rv = ImGui::InputFloat( label, v, 0.0f, 0.0f, format, flags );
if( !ImGui::IsItemHovered() ) return rv;
float wheel = ImGui::GetIO().MouseWheel;
if ( wheel )
{
if( ImGui::IsItemActive() )
{
ImGui::ClearActiveID();
}
else
{
*v += wheel * scrolStep;
}
}
}
Back-ends: SDL2 + Vulkan
Note that this is a completely custom backend implementation.
Hello,
Not so long ago we formalized this with an imgui_internal.h function called SetItemUsingMouseWheel() (#2891):
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
ImGui::SetItemUsingMouseWheel();
if (ImGui::IsItemHovered())
{
float wheel = ImGui::GetIO().MouseWheel;
if (wheel)
{
if (ImGui::IsItemActive())
{
ImGui::ClearActiveID();
}
else
{
f += wheel;
}
}
}
I would be interested in feedback and further example to figure out if this is a viable design to expose into the public API.
Thanks! Somehow my previous attempt to use this function has failed. Not this time though!
Sticking with InputFloat I wrote this:
const bool rv = ImGui::InputFloat( label, v, 0.0f, 0.0f, format, flags );
ImGui::SetItemUsingMouseWheel();
if( !ImGui::IsItemHovered() ) return rv;
float wheel = ImGui::GetIO().MouseWheel;
if( wheel )
{
if( ImGui::IsItemActive() )
{
ImGui::ClearActiveID();
}
else
{
*v += wheel * scrolStep;
}
}
// [...]
return rv;
And it works just as expected -- prevents window from scrolling when the value is modified with mouse wheel. Once again, thank you for the assist!
Good to hear!
Technically speaking your *v += wheel * scrolStep; line should be followed by rv = true if you want to notify caller of a value change.
Closing this.
I would be interested in feedback and further example to figure out if this is a viable design to expose into the public API.
So far, this is working well in my use cases. I ended up wrapping the widgets that I want to interact with the mouse wheel up in custom functions, and am using ImGui::SetItemUsingMouseWheel.
Working great so far. Would vote to have this exposed in the public API. 👍
I just upgraded my codebase to v1.89.1, and I'm getting errors now trying to use SetItemUsingMouseWheel.
I see this in imgui_internal.h:
// Obsolete functions
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline void SetItemUsingMouseWheel() { SetItemKeyOwner(ImGuiKey_MouseWheelY); } // Changed in 1.89
But I'm not really finding any details on what the current mechanism is to support this functionality?
Err, you literally pasted the answer to your question? Use SetItemKeyOwner().
I get that. Is this functionality stable, even if the naming keeps changing?
Everything in imgui_internal.h is technically not guaranteed to be stable, but SetItemKeyOwner() is the way forward.
As SetItemUsingMouseWheel() was mentioned in #5108 #4303 #4207 #2891 #2704 I added a redirection function in imgui_internal.h but those are fairly exceptional and the SetItemUsingMouseWheel() inline function will eventually be removed.
@ocornut sorry for bugging you for a century old and closed issue.
Is there any chance of making SetItemKeyOwner() a public API function
rather than internal API.
Basically I am trying to do what this issue is talking about but in C#. :)
It will be progressively be made public when the API has been used enough.
I think you should ask for your C# bindings to allow access to imgui_internal too.
Hi, Is there any new solution to this that allows scrolling of the region that contains the slider to not stop when the mouse just so happens to land on a slider? Afaik most UI systems handle this by checking of the mouse has moved or not following the scrolling of the container but I'm not sure how to cleanly implement this.
Should probably check that the mouse moving window lock is disabled before claiming ownership. Will try to test this.
Hi again, Any update on this? Even if not in ImGui, a working way to do this as a custom widget would be helpful :+1:
Here's an incomplete wrapper I created to support this usecase: https://gist.github.com/Folling/06c223badea6fb7da76d8039947f2398. This almost certainly misses certain ergonomics like focus handling, keyboard navigation, styling, etc. I didn't do a full test, so it should be seen as a jumping off point for proper applications — works for our internal tool though. The label rendering is a bit hacky, I didn't find any better way without using imgui_internal.
As for Dear ImGui itself, it would be nice to have a new ImGuiSliderFlag to support scrolling ootb. I can create a PR for this if desired.