imgui icon indicating copy to clipboard operation
imgui copied to clipboard

ImGui::SetItemKeyOwner does not work on images

Open nasiratif opened this issue 10 months ago • 4 comments

Version/Branch of Dear ImGui:

Version 1.91.8, Branch: master

Back-ends:

imgui_impl_win32.cpp + imgui_impl_dx9.cpp

Compiler, OS:

WIndows 11 + MSVC 2022

Full config/build information:

Dear ImGui 1.91.8 (19180)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _WIN64
define: _MSC_VER=1941
define: _MSVC_LANG=201402
--------------------------------
io.BackendPlatformName: imgui_impl_win32
io.BackendRendererName: imgui_impl_dx9
io.ConfigFlags: 0x00000003
 NavEnableKeyboard
 NavEnableGamepad
io.ConfigNavCaptureKeyboard
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x0000000E
 HasMouseCursors
 HasSetMousePos
 RendererHasVtxOffset
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1264.00,761.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

I haven't tested other keys, but If you use ImGui::SetItemKeyOwner(ImGuiKey_MouseWheelY) on Images, it doesn't work as you can still scroll on the window.

I needed to do this because in my project I'm writing a 2D animation editor where you can preview the image and zoom in/out, but I can't have the window scroll along with the image.

The only thing I've tried was calling SetItemKeyOwner before Image, but that of course did not fix the problem.

Screenshots/Video:

Image

Minimal, Complete and Verifiable Example code:

ImGui::Begin("Hello, world!");

ImGui::Button("Scrolling doesn't work on this button as expected:");
ImGui::SetItemKeyOwner(ImGuiKey_MouseWheelY);

ImGui::Text("But scrolling still works on this image:");
ImGui::Image(0, ImVec2(128, 128));
ImGui::SetItemKeyOwner(ImGuiKey_MouseWheelY);

ImGui::End();

nasiratif avatar Mar 03 '25 13:03 nasiratif

Images, like text, don't have an item ID (0). You can use ImGui::ImageButton instead to create an interactive item for SetItemKeyOwner to act upon.

ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0});
ImGui::ImageButton("foo", 0, {128, 128});
ImGui::PopStyleVar();
ImGui::SetItemKeyOwner(ImGuiKey_MouseWheelY);

cfillion avatar Mar 03 '25 13:03 cfillion

Images, like text, don't have an item ID (0). You can use ImGui::ImageButton instead to create an interactive item for SetItemKeyOwner to act upon.

ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, 0}); ImGui::ImageButton("foo", 0, {128, 128}); ImGui::PopStyleVar(); ImGui::SetItemKeyOwner(ImGuiKey_MouseWheelY);

While this works, since it's a button, I get a background color behind the image, which I don't like since my editor deals with transparent images. Any way to disable this for images only?

nasiratif avatar Mar 04 '25 13:03 nasiratif

ImGui::PushStyleColor(ImGuiCol_Button, 0) (+ ButtonActive and ButtonHovered) with a matching Pop surrounding the image(s).

cfillion avatar Mar 04 '25 13:03 cfillion

You might alternatively bypass SetItemKeyOwner():

if (IsItemHovered())
    SetKeyOwner(ImGuiKey_MouseWheelY, 0, ImGuiInputFlags_LockThisFrame);

We could perhaps find a way for SetItemKeyOwner() to work in this case, but it may be ambiguous/hard to decide which id the underlying call to SetKeyOwner() would use. If the goal is to simply steal the key away from e.g. nav systems it doesn't matter either way, but it may be confusing if SetItemKeyOwner() transparently handled case where LastItem has no ID and arbitrary locked the key.. or not.

ocornut avatar Mar 04 '25 13:03 ocornut