Skip to content
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

Scroll parent window once child window is fully scrolled #8202

Open
lawrence-laz opened this issue Dec 4, 2024 · 3 comments
Open

Scroll parent window once child window is fully scrolled #8202

lawrence-laz opened this issue Dec 4, 2024 · 3 comments

Comments

@lawrence-laz
Copy link

lawrence-laz commented Dec 4, 2024

Version/Branch of Dear ImGui:

1.90.8

Back-ends:

imgui_impl_glfw.cpp + imgui_impl_opengl.cpp

Compiler, OS:

Windows

Full config/build information:

ImGui.NET

Details:

Can I scroll a parent window while hovering the child window?

I have a vertically scrollable window with a child window, which is also vertically scrollable.

Currently imgui chooses which window to scroll with the mouse wheel/touchpad based on which window the pointer is hovering.

However, there's a situation where this behavior alone creates a bit of an uncomfortable experience. If the child window is not fully visible in the viewport and you are trying to scroll to the bottom of the child window the scrolling stops once the child window is at the bottom. The bottom items are still not visible though, because the parent needs to be scrolled down a bit too. But to get the parent to scroll you have to move the pointer away from the child window and then scroll again.

I would like to achieve a behavior, where hovering over a child window and moving mouse wheel/touchpad scrolls the child window, but once you are fully scrolled to that direction it would start scrolling the parent window. This would eliminate the need move the pointer mid-scrolling.

The same situation can be shown in the demo window (attached a gif).

Can this be achieved with the current public API?

Screenshots/Video:

image

@ocornut
Copy link
Owner

ocornut commented Dec 4, 2024

I guess this was mentioned in passing while we worked on #3795 but never implemented.
We can probably investigate it, and add ImGuiChildFlags values for request preventing the bubbling up to parent window if desired.

@yuvashrikarunakaran
Copy link

To achieve the behavior where scrolling propagates from a child window to its parent window once the child has reached its scroll limit, you can use ImGui's public API along with some custom logic to manually handle the scroll.

#include "imgui.h"

void ScrollableParentChild()
{
// Set up the parent window
ImGui::Begin("Parent Window", nullptr, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);

// Ensure a fixed height to make the parent window scrollable
ImVec2 parentSize = ImGui::GetContentRegionAvail();
parentSize.y = 300; // Example fixed height
ImGui::BeginChild("ParentScrollRegion", parentSize, true, ImGuiWindowFlags_NoScrollWithMouse);

// Add some dummy content to make the parent scrollable
for (int i = 0; i < 30; ++i)
    ImGui::Text("Parent Item %d", i);

// Set up the child window
ImVec2 childSize(parentSize.x * 0.9f, 150); // Example fixed child size
ImGui::BeginChild("ChildScrollRegion", childSize, true);

// Add some dummy content to make the child scrollable
for (int i = 0; i < 10; ++i)
    ImGui::Text("Child Item %d", i);

// Check scrolling state
float childScrollY = ImGui::GetScrollY();
float childScrollMaxY = ImGui::GetScrollMaxY();

if (ImGui::IsWindowHovered() && ImGui::GetIO().MouseWheel != 0.0f)
{
    if ((childScrollY <= 0.0f && ImGui::GetIO().MouseWheel > 0.0f) || (childScrollY >= childScrollMaxY && ImGui::GetIO().MouseWheel < 0.0f))
    {
        // Pass scroll to the parent
        ImGui::SetScrollY(ImGui::GetScrollY() - ImGui::GetIO().MouseWheel * 20.0f); // Adjust scroll speed
    }
}

ImGui::EndChild(); // End child window
ImGui::EndChild(); // End parent scroll region
ImGui::End();      // End parent window

}

Separate Scroll Management:

Both the parent and child windows are scrollable.
The parent window's scroll functionality is disabled while hovering the child (ImGuiWindowFlags_NoScrollWithMouse).
Scroll Propagation Logic:

While hovering the child window, check the ImGui::GetScrollY() and ImGui::GetScrollMaxY() values.
If the scroll direction exceeds the child’s scroll limits, propagate the scroll to the parent window.
Mouse Wheel Handling:

Use ImGui::GetIO().MouseWheel to detect the scroll direction and apply it conditionally to the parent.
Scroll Speed Adjustment:

The factor 20.0f in SetScrollY can be adjusted to control how much the parent scrolls per wheel tick.

@cfillion
Copy link
Contributor

cfillion commented Dec 6, 2024

SetScrollY affects the current window (ChildScrollRegion). It does not propagate to the parent so it needs to be delayed after the corresponding End*() for that snippet to do anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants