Modal window flickers when shown? #690

Closed
opened 2016-06-10 04:12:56 +00:00 by leiradel · 5 comments
leiradel commented 2016-06-10 04:12:56 +00:00 (Migrated from github.com)

I've implemented a message box dialog on top of imgui, but it seems to flicker a little when the dialog is shown as if it is deciding how to layout the controls in it.

This screenshot was taken just before the window accommodates its contents:

ccfinder0

After maybe just one frame, the final window is shown until its closed:

ccfinder

It could be something wrong with my code, but I decided to open an issue just to make sure it's not a known problem.

I've implemented a [message box dialog](https://github.com/leiradel/ImGuiAl/tree/master/msgbox) on top of imgui, but it seems to flicker a little when the dialog is shown as if it is deciding how to layout the controls in it. This screenshot was taken just before the window accommodates its contents: ![ccfinder0](https://cloud.githubusercontent.com/assets/357536/15954008/27b02332-2ea8-11e6-9429-338df55a6eb1.png) After maybe just one frame, the final window is shown until its closed: ![ccfinder](https://cloud.githubusercontent.com/assets/357536/15954016/5093d33e-2ea8-11e6-918a-45a34b336ba4.png) It could be something wrong with my code, but I decided to open an issue just to make sure it's not a known problem.
ocornut commented 2016-06-10 07:13:14 +00:00 (Migrated from github.com)

Hi,

The problem is that TextWrapped() relies on the window width (content width) which is undefined when you first open a window with ImGuiWindowFlags_AlwaysAutoResize. You can't really have both.

The easy solution is to set an explicit width via e.g. SetNextWindowSize(ImVec2(400,0)); prior to the Begin call.

To draw the icon you could just use SetCursorPos(), Text(), SetCursorPos(), TextWrapped(). You can also lock the X position with BeginGroup()/EndGroup() but it isn't needed here as you have a single TextWrapped() element.

Hi, The problem is that TextWrapped() relies on the window width (content width) which is undefined when you first open a window with `ImGuiWindowFlags_AlwaysAutoResize`. You can't really have both. The easy solution is to set an explicit width via e.g. `SetNextWindowSize(ImVec2(400,0));` prior to the Begin call. To draw the icon you could just use SetCursorPos(), Text(), SetCursorPos(), TextWrapped(). You can also lock the X position with BeginGroup()/EndGroup() but it isn't needed here as you have a single TextWrapped() element.
leiradel commented 2016-06-10 15:35:30 +00:00 (Migrated from github.com)

The easy solution is to set an explicit width via e.g. SetNextWindowSize(ImVec2(400,0)); prior to the Begin call.

I was under the impression that it would freeze the window width and resize vertically as items are added but that's not the case (and if it was it would probably have the same problem as the auto resize option). I'd have to specify a height big enough for everyone which isn't really possible nor desirable.

Maybe I'll play with the clipping rectangle to avoid the window being shown for the first frame and let it have a chance to decide on its size. Or maybe not, since imgui is a programmer's UI, It's not likely that people will demand fixes for something like that :)

Thanks!

> The easy solution is to set an explicit width via e.g. SetNextWindowSize(ImVec2(400,0)); prior to the Begin call. I was under the impression that it would freeze the window width and resize vertically as items are added but that's not the case (and if it was it would probably have the same problem as the auto resize option). I'd have to specify a height big enough for everyone which isn't really possible nor desirable. Maybe I'll play with the clipping rectangle to avoid the window being shown for the first frame and let it have a chance to decide on its size. Or maybe not, since imgui is a programmer's UI, It's not likely that people will demand fixes for something like that :) Thanks!
leiradel commented 2016-06-10 15:42:58 +00:00 (Migrated from github.com)

Woot, I decided to draw the icon using your technique and the flicker is gone!

      if ( m_Icon != NULL )
      {
        ImVec2 size = ImGui::CalcTextSize( m_Icon );
        ImVec2 pos = ImGui::GetCursorPos();
        float save_y = pos.y;
        pos.y += size.y * 2;

        ImGui::SetCursorPos( pos );
        ImGui::Text( "%s", m_Icon );

        pos.x += size.x;
        pos.y = save_y;

        ImGui::SetCursorPos( pos );
        ImGui::TextWrapped( "%s", m_Text );
      }
      else
      {
        ImGui::TextWrapped( "%s", m_Text );
      }

So I guess all is good now :D

Thanks again!

Woot, I decided to draw the icon using your technique and the flicker is gone! ``` C++ if ( m_Icon != NULL ) { ImVec2 size = ImGui::CalcTextSize( m_Icon ); ImVec2 pos = ImGui::GetCursorPos(); float save_y = pos.y; pos.y += size.y * 2; ImGui::SetCursorPos( pos ); ImGui::Text( "%s", m_Icon ); pos.x += size.x; pos.y = save_y; ImGui::SetCursorPos( pos ); ImGui::TextWrapped( "%s", m_Text ); } else { ImGui::TextWrapped( "%s", m_Text ); } ``` So I guess all is good now :D Thanks again!
ocornut commented 2016-06-10 15:47:36 +00:00 (Migrated from github.com)

It's a totally legit question and i'd like to solve it. If width is known then the vertical extent of TextWrapped() will be known on the first pass so there shouldn't be a problem. It's just that auto-width + textwrapped can't work together.

Maybe (400,-1) as size, I don't have the code in front of me but there should be a way to keep auto resize on the vertical axis but not the horizontal one.

Or you can also set explicit text wrapping x position instead of using TextWrapping() that would also work.

It's a totally legit question and i'd like to solve it. If width is known then the vertical extent of TextWrapped() will be known on the first pass so there shouldn't be a problem. It's just that auto-width + textwrapped can't work together. Maybe (400,-1) as size, I don't have the code in front of me but there should be a way to keep auto resize on the vertical axis but not the horizontal one. Or you can also set explicit text wrapping x position instead of using TextWrapping() that would also work.
ocornut commented 2016-06-11 08:25:27 +00:00 (Migrated from github.com)

Re- on the discussion above
That works:

ImGui::SetNextWindowSize(ImVec2(400,0), ImGuiSetCond_Once);
if (ImGui::BeginPopupModal("Bug #690", NULL))

Without ImGuiWindowFlags_AlwaysAutoResize and WITH the ImGuiSetCond_Once parameter.
It is important because repeatedly calling SetNextWindowSize() every frame with 0 height and no condition will keep delaying resizing to the next frame (due to a need to calculate height).
It is listed as a thing to improve/fix to allow it working without the ImGuiSetCond_Once parameter.

That also works:

if (ImGui::BeginPopupModal("Bug #690"))
{
    ImGui::PushTextWrapPos(400);
    ImGui::Text("Are you really really sure you want to delete the entire log history and loose that information forever?");
    ImGui::PopTextWrapPos();

I have fixed a minor bug now where TextWrapped() would override the wrap position is one was already set. So:

ImGui::PushTextWrapPos(400);
ImGui::TextWrapped("Are you really really sure you want to delete the entire log history and loose that information forever?");
ImGui::PopTextWrapPos();

Would have lost the explicit 400 before that fix.

Re- on the discussion above That works: ``` ImGui::SetNextWindowSize(ImVec2(400,0), ImGuiSetCond_Once); if (ImGui::BeginPopupModal("Bug #690", NULL)) ``` Without `ImGuiWindowFlags_AlwaysAutoResize` and WITH the `ImGuiSetCond_Once` parameter. It is important because repeatedly calling SetNextWindowSize() every frame with 0 height and no condition will keep delaying resizing to the next frame (due to a need to calculate height). It is listed as a thing to improve/fix to allow it working without the `ImGuiSetCond_Once` parameter. That also works: ``` if (ImGui::BeginPopupModal("Bug #690")) { ImGui::PushTextWrapPos(400); ImGui::Text("Are you really really sure you want to delete the entire log history and loose that information forever?"); ImGui::PopTextWrapPos(); ``` I have fixed a minor bug now where TextWrapped() would override the wrap position is one was already set. So: ``` ImGui::PushTextWrapPos(400); ImGui::TextWrapped("Are you really really sure you want to delete the entire log history and loose that information forever?"); ImGui::PopTextWrapPos(); ``` Would have lost the explicit 400 before that fix.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ocornut/imgui#690
No description provided.