ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
58.41k stars 10.01k forks source link

Scroll wrapping behavior in ImGui? #2678

Open ndevasia opened 5 years ago

ndevasia commented 5 years ago

Version: v1.65 Branch: master Back-ends: Using custom engine backend Compiler: VS2017 Operating System: Windows 10 Enterprise v. 1809

I'm trying to create an ImGui version of a custom debug tool. An issue I'm having right now is with making ImGui recognize when the entries have wrapped around and it needs to update the scrollbar. For example, if I'm at entry 0 and I try to move to entry 10 by pressing up, the highlight and NavID change (I manually set the NavID to map to whatever is selected in the custom debug tool, which supports scroll wrapping) but scrollbar doesn't recognize that it needs to move. However, when I press up again to move from entry 10 to entry 9, the scrollbar updates correctly. I would like it to update on the first press - is this a feature that has been added to a newer version of ImGui or will be added in the near future? I spent quite a while fiddling with NavScoreItem() and the quadrant system to see if I could make it work, but I couldn't find a solution and am now back to square 1.

ocornut commented 5 years ago

Please do provide repro and code as requested, there's dozen possible things you could be doing in your code that I don't know about. When you say "I'm at entry 0 and I try to move to entry 10 by pressing up" I don't know what is making that happen.

NavUpdateMoveResult() is calling NavScrollToBringItemIntoView() so if you are hijacking the system by setting your own NavId we should probably design a way to trigger than "scroll into view" operation.

There's however a system within Navigation to handle wrapping around automatically, see what EndPopup() is doing:

NavMoveRequestTryWrapping(g.CurrentWindow, ImGuiNavMoveFlags_LoopY);

This needs to be called and the end of the scope/window to give a chance for other items to catch the request.

ndevasia commented 5 years ago

Thanks for the quick response. Here are the repro steps:

I followed your suggestion and put NavMoveRequestTryWrapping() right before End() is called. This fixes the problem halfway - the scrollbar recognizes that it needs to wrap when going from entry 0 to entry 10, but it doesn't quite scroll enough. For example, if I am at entry 0 and press DPadUp to scroll to entry 10, the scrollbar moves down, but only entry 9 and a tiny bit of entry 10 are in view. ImGui seems to think that I'm trying to view entry 9 rather than entry 10.

(As a sidenote, my DPadUp code is basically just when DPadUp is pressed, set io.NavInputs[ImGuiNavInput_DpadUp] = 1.0f;)

Let me know if you need any other repro steps.

ocornut commented 5 years ago

An actual repro would be helpful, yes.

ndevasia commented 5 years ago

Sorry for the late response - got caught up with some work. Here's the repro.

Here's what I did:

Let me know if you need anything else and sorry for the delay.

ocornut commented 4 years ago

Hello @ndevasia, I looked at this today and couldn't repro the issue.

However, there was a known bug between 1.71 (around June 2019) and 1.72b (31 July 2019) which exhibit exactly that issue, 1.72b changelog says:

- Nav, Scrolling: Fixed programmatic scroll leading to a slightly incorrect scroll offset when
  the window has decorations or a menu-bar (broken in 1.71). This was mostly noticeable when
  a keyboard/gamepad movement led to scrolling the view, or using e.g. SetScrollHereY() function.

So as I understand after my first answer you updated to latest to be able to call NavMoveRequestTryWrapping() and it was at a time when there was a bug. AFAIK the current version doesn't have this bug, could you confirm it?

Thank you!

//Repro example for imgui issue #2678
{
    ImGui::Begin("Window filled with selectables");
    ImGuiContext& g = *GImGui;
    g.IO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
    ImGui::SetNextWindowSize(ImVec2(100, 100));
    static bool selection[11] = { false, true, false, false, false };
    ImGui::Selectable("1. I am selectable", &selection[0]);
    ImGui::Selectable("2. I am selectable", &selection[1]);
    ImGui::Text("3. I am not selectable");
    ImGui::Selectable("4. I am selectable", &selection[3]);
    if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick))
        if (ImGui::IsMouseDoubleClicked(0))
            selection[4] = !selection[4];
    ImGui::NavMoveRequestTryWrapping(g.CurrentWindow, ImGuiNavMoveFlags_LoopY);
    ImGui::End();
}
ndevasia commented 4 years ago

?Hello!

I actually worked on an ImGui related project while I was an intern over the summer, so I can no longer check if this works correctly or not because I don't have access to my work any longer. However, I can forward this message to the right people and hopefully they'll test it out on my work!

Thanks,

-ndevasia


From: omar notifications@github.com Sent: Wednesday, January 15, 2020 10:58 AM To: ocornut/imgui Cc: Nisha E Devasia; Mention Subject: Re: [ocornut/imgui] Scroll wrapping behavior in ImGui? (#2678)

Hello @ndevasiahttps://github.com/ndevasia, I looked at this today and couldn't repro the issue.

However, there was a known bug between 1.71 (around June 2019) and 1.72b (31 July 2019) which exhibit exactly that issue, 1.72b changelog says:

So as I understand after my first answer you updated to latest to be able to call NavMoveRequestTryWrapping() and it was at a time when there was a bug. AFAIK the current version doesn't have this bug, could you confirm it?

Thank you!

//Repro example for imgui issue #2678 { ImGui::Begin("Window filled with selectables"); ImGuiContext& g = *GImGui; g.IO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; ImGui::SetNextWindowSize(ImVec2(100, 100)); static bool selection[11] = { false, true, false, false, false }; ImGui::Selectable("1. I am selectable", &selection[0]); ImGui::Selectable("2. I am selectable", &selection[1]); ImGui::Text("3. I am not selectable"); ImGui::Selectable("4. I am selectable", &selection[3]); if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick)) if (ImGui::IsMouseDoubleClicked(0)) selection[4] = !selection[4]; ImGui::NavMoveRequestTryWrapping(g.CurrentWindow, ImGuiNavMoveFlags_LoopY); ImGui::End(); }

- You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/ocornut/imgui/issues/2678?email_source=notifications&email_token=AIMTUBYCUG4YAYVO4BH446DQ54XCZA5CNFSM4IFM6RA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJAZ46Y#issuecomment-574725755, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AIMTUB6RCRNWH4YF3MWKB2LQ54XCZANCNFSM4IFM6RAQ.