-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
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
Trying to scroll in the same frame #6349
Comments
You should go with Plan A. You can call As you are adjusted both scrolling and contents together you should probably use If your text is really large you might want to consider an optimization AFTER it works, of tracking how much new text height is added and then adding that to previous |
Thanks for your reply. I tried Plan A, but can't get it to work. Scrolling still seems to need two frames. Also Here's what's going on: I calculate in advance the size of my child window (to hold the text object) and the client space, based on some hackery with padding.
Then i layout my content internally and calculate any scroll in Y, which is the height of my "page" minus the height of the client area (when >0).
So if Then decide to scroll either once or twice depending on how many
When So if Or is there something horrible, I'm missing? (most likely) Thanks for helping. |
I can’t see any call to SetNextWindowContentSize() in your sample. Please try to build a minimal repro to exhibit the problem if any. |
Hi, Adding I've discovered that instead of manually doing a 2-frame loop, you can add another call to Like this:
So you'd expect "window scroll" to report the same as "my scroll". But what you get is:
So without issuing any new scroll commands, or moving the UI, there are two "window scroll" values reported on subsequent frame renders, and it takes Imgui another frame to "magically" catch up with "my scroll". |
But you need to tell it so scrolling doesn't get clamped on You are not providing a repro here as I don't know what's the value you are passing to And actual content submitted needs to at least match or be more (not be less) than |
Ok solved. If Imgui gets it wrong for one frame, but fixes it automatically later. I just have to apply any correction to the true scroll value by adjusting my content position for that frame. Thus;
ha! |
You went back for Plan B which is not ideal. I am 99% certain Plan A should work but don't seem to trying it so far or at least not providing evidence that it doesn't work. |
Ok. let me investigate further. |
int frame_count = ImGui::GetFrameCount();
ImGui::SetNextWindowSize(ImVec2(100, 100));
ImGui::SetNextWindowScroll(ImVec2(0.0f, 300.0f));
ImGui::Begin("Test #6349");
if (frame_count < 10)
ImGui::Dummy(ImVec2(200, 200));
if (frame_count >= 10)
ImGui::Dummy(ImVec2(200, 500)); // Grow content after frame 10
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IMGUI_DEBUG_LOG("Inside window: Scroll=%.3f/%.3f, ContentSize=%.3f\n", window->Scroll.y, window->ScrollMax.y, window->ContentSize.y);
ImGui::End(); [00001] Inside window: Scroll=0.000/0.000, ContentSize=0.000
[00002] Inside window: Scroll=135.000/135.000, ContentSize=200.000 <-- Scroll clamped
[00003] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00004] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00005] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00006] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00007] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00008] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00009] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00010] Inside window: Scroll=135.000/135.000, ContentSize=200.000 <-- submitted Dummy(500,500) but scroll is late
[00011] Inside window: Scroll=300.000/435.000, ContentSize=500.000 <-- GOOD
[00012] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00013] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00014] Inside window: Scroll=300.000/435.000, ContentSize=500.000 Now if I add BEFORE Begin(); if (frame_count >= 10)
ImGui::SetNextWindowContentSize(ImVec2(0, 500.0f));
ImGui::Begin(...); [00001] Inside window: Scroll=0.000/0.000, ContentSize=0.000
[00002] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00003] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00004] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00005] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00006] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00007] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00008] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00009] Inside window: Scroll=135.000/135.000, ContentSize=200.000
[00010] Inside window: Scroll=300.000/435.000, ContentSize=500.000 <--- GOOD
[00011] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00012] Inside window: Scroll=300.000/435.000, ContentSize=500.000 It works. EDIT for completeness, if I always call SetNextWindowContentSize(), then the scroll is right on 1st frame as well: //if (frame_count >= 10)
ImGui::SetNextWindowContentSize(ImVec2(0, 500.0f));
ImGui::Begin(...); [00001] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00002] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00003] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00004] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00005] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00006] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00007] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00008] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00009] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00010] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00011] Inside window: Scroll=300.000/435.000, ContentSize=500.000
[00012] Inside window: Scroll=300.000/435.000, ContentSize=500.000 |
Hi. Thanks for that. You're right. I need I don't need any of my previous hacks (neither planB). So, to summarise: I calculate the child window visible client area, based on the size i will give to
Then I perform my internal layout and figure out if the layout has changed and whether there is any excess scroll over the region above.
Then important, i pass in the height of my layout region and my required scroll excess. Then
And that is it! Thanks very much for helping. Plan B was a hack. The trick was getting the correct height to Cheers! |
I don't understand the complexity of your code above. I can't understand nor guess what's going on in the other functions that are in your code, but this sounds abnormally complicated. |
The first block of code calculates the child window visible area and is needed for my text layout. It would be nice to have a function that calculates, given a I need the view area width for text layout and the height for placement of sensible picture sizes.
Above
I recover the page height using
Here's a pic that might make things clearer. |
It's tricky to calculate it ahead of Begin() in a trustable and generic manner because those elements (e.g. Scrollbar, Menu Bar) state may change based on other parameters. Since a refactor a few months ago there are 4 fields in Also note
Right, that makes sense in this context. I would guess once you performed this layout you may be able to obtain a content size and then the Nice looking richtext layout btw ! |
Begin() does: window->InnerRect.Min.x = window->Pos.x + window->DecoOuterSizeX1;
window->InnerRect.Min.y = window->Pos.y + window->DecoOuterSizeY1;
window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->DecoOuterSizeX2;
window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->DecoOuterSizeY2; So you may as well use |
version: latest master.
As text gets added, it won't scroll in the same frame, only 1 later. This means i get a horrible flicker as it renders the text in the wrong place, then scrolls up and renders again.
To make things exciting all this text appears in a single ImgGui item which i add like this:
The text itself is added directly to the window drawlist.
Plan A
I was hoping to use
SetNextWindowScroll
. So it appears this either doesn't apply immediately or must be before the entire window and not just a child region (where the item is to go). So that didn't work.Plan B
This nearly worked;
Because i have everything in one item. I can calculate the size of this item and the size of the client area it is to be placed before
ItemAdd
usingGetContentRegionAvail
This means i can calculate how much it needs to scroll. then i adjust by placing the item higher (just like some hacker would!)
Works nicely. Except the scrollbar appears to have no idea what I'm doing. Instead showing space to scroll below instead of above.
Is there a way to fix the scrollbar? Or is there a better way altogether (i actually hope so).
thanks for any help.
The text was updated successfully, but these errors were encountered: