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

Issue programmatically setting Scrolling with SetScrollHereY() in window with clipped contents #8212

Open
llxiaoyuan opened this issue Dec 6, 2024 · 3 comments

Comments

@llxiaoyuan
Copy link

llxiaoyuan commented Dec 6, 2024

Version/Branch of Dear ImGui:

Version 1.XX, Branch: XXX (master/docking/etc.)

Back-ends:

imgui_impl_XXX.cpp + imgui_impl_XXX.cpp

Compiler, OS:

win10

Full config/build information:

No response

Details:

why I need to click twice to get the scroll bar at right pos

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

        static bool need_to_set_scroll = false;
        static bool need_to_set_scroll2 = false;
        static bool need_to_set_scroll3 = false;
        ImGui::Begin(u8"chat111");
        if (ImGui::Button("track_once111"))
        {
            need_to_set_scroll = true;
            need_to_set_scroll2 = true;
            need_to_set_scroll3 = true;
        }
        ImGui::BeginChild("chatBeginChild", ImVec2(280, 280), ImGuiChildFlags_Border, ImGuiWindowFlags_HorizontalScrollbar);

        ImGui::BeginChild("chatBeginChild_1", ImVec2(300, 300), ImGuiChildFlags_Border);
        int scroll_index = 49;
        for (size_t j = 0; j < 50; j++) {
            ImGui::TextColored(ImVec4(1, 1, 1, 1), "%d %d", j, scroll_index);
            if (need_to_set_scroll && scroll_index == j) {
                need_to_set_scroll = false;
                printf("SetScrollHereY called\n");
                ImGui::SetScrollHereY(0.5f);
            }
        }
        ImGui::EndChild();

        ImGui::SameLine();

        ImGui::BeginChild("chatBeginChild_2", ImVec2(300, 300), ImGuiChildFlags_Border);
        int scroll_index2 = 49;
        for (size_t j = 0; j < 50; j++) {
            ImGui::TextColored(ImVec4(1, 1, 1, 1), "%d %d", j, scroll_index2);
            if (need_to_set_scroll2 && scroll_index2 == j) {
                need_to_set_scroll2 = false;
                printf("SetScrollHereY2 called\n");
                ImGui::SetScrollHereY(0.5f);
            }
        }
        ImGui::EndChild();

        if (need_to_set_scroll3) {
            need_to_set_scroll3 = false;
            printf("SetScrollHereX called\n");
            printf("\n");
            ImGui::SetScrollHereX(0.5f);
        }

        ImGui::EndChild();
        ImGui::End();
@llxiaoyuan
Copy link
Author

@ocornut It seems that setting y is invalid when the column is not displayed

@llxiaoyuan
Copy link
Author

llxiaoyuan commented Dec 8, 2024

I can solve some problems in this way, But I don't think that's a good idea

if (ImGui::IsRectVisible(ImGui::GetContentRegionAvail())){
  drawCol();
}

@ocornut ocornut changed the title question with Scrollbar Question with programmatically setting Scrolling with SetScrollHereY() Dec 9, 2024
@ocornut
Copy link
Owner

ocornut commented Dec 9, 2024

The problem you have is that BeginChild() returns false when not visible and goes in a state when none of the element submitted are processed (internally it sets window->SkipItems = true). So when the child is 100% not visible, not of the Text() calls are going through and SetScrollHere() functions are still referring to the start position.

Possible solutions:
(A) either you queue/store your request to be processed when the window is visible.

if (ImGui::BeginChild("chatBeginChild_2", ImVec2(300, 300), ImGuiChildFlags_Borders))
{
    int scroll_index2 = 49;
    for (size_t j = 0; j < 50; j++)
    {
        ImGui::TextColored(ImVec4(1, 1, 1, 1), "%d %d", j, scroll_index2);
        if (need_to_set_scroll2 && scroll_index2 == j)
        {
            need_to_set_scroll2 = false;
            IMGUI_DEBUG_LOG("SetScrollHereY2 called\n");
            ImGui::SetScrollHereY(0.5f);
        }
    }
}
ImGui::EndChild();

And need_to_set_scroll2 needs to persist across frames until used.

(B) Either you compute the scroll target rather than rely on current layout:

ImGui::BeginChild("chatBeginChild_2", ImVec2(300, 300), ImGuiChildFlags_Borders);
int scroll_index2 = 49;
if (need_to_set_scroll2)
{
    ImGui::SetScrollY(ImGui::GetTextLineHeightWithSpacing() * scroll_index2);
    need_to_set_scroll2 = false;
}
for (size_t j = 0; j < 50; j++)
    ImGui::TextColored(ImVec4(1, 1, 1, 1), "%d %d", j, scroll_index2);
ImGui::EndChild();

@ocornut ocornut changed the title Question with programmatically setting Scrolling with SetScrollHereY() Issue programmatically setting Scrolling with SetScrollHereY() in clipped window Dec 9, 2024
@ocornut ocornut changed the title Issue programmatically setting Scrolling with SetScrollHereY() in clipped window Issue programmatically setting Scrolling with SetScrollHereY() in window with clipped contents Dec 12, 2024
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

2 participants