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

Controlling z order #1328

Open
inolen opened this issue Sep 17, 2017 · 8 comments
Open

Controlling z order #1328

inolen opened this issue Sep 17, 2017 · 8 comments

Comments

@inolen
Copy link
Contributor

inolen commented Sep 17, 2017

I've been doing some custom UI rendering with a mixture of widgets / raw draw list commands.

All was well, until I split one of my windows up with a child window through BeginChild / EndChild:
clouds

In this image, the clouds and white rectangle are added through AddRectFilled, and each disc is an Image widget added inside of a child window. Finally, a fullscreen black quad is again added with AddRectFilled when "fading out" the UI.

After converting over to using BeginChild / EndChild, the black quad stopped covering the disc images. Is there a way I can control the z-order in order to ensure the black quad renders last?

@inolen inolen changed the title Controlling z-order Controlling z order Sep 17, 2017
@ocornut
Copy link
Owner

ocornut commented Sep 17, 2017

Childs are always drawn after parents, in the same order as BeginChild() was called.
If you need a black quad covering everything you might create yet another child.

However - I don't know exactly what you are using here but it looks like you could ignore most of ImGui constructs and just work within a single ImDrawList for that sort of high-level very custom ui.

Also linking to #983

PS: Please always use the github attachment system for pictures and not imgur. The later will delete images in the future and render this issues harder to grasp for other users encountering a similar issue.

@inolen
Copy link
Contributor Author

inolen commented Sep 17, 2017

Thanks a lot for the response! Another child with BeginChild sounds interesting - I'll give that a shot tonight.

I broke away from the drawlist primarily to handle the scrolling of the discs there.

Re #983, using another window for the black quad also seemed interesting, but ImGuiWindowFlags_NoBringToFrontOnFocus and ImGuiWindowFlags_NoFocusOnAppearing didn't quite offer what I needed. When not using them, if I rendered the black quad window last it would cover the screen, but if I clicked in that area it would end up coming to the front on top of the main menu bar which created an odd experience. What I really wanted was a window flag to bring it to front on appearing (not necessarily focus on appearing, as I wanted to enable ImGuiWindowFlags_NoBringToFrontOnFocus such that it wouldn't come to the front when clicked on).

P.S. edited the issue and attached the image through github, will keep that in mind.

@ocornut
Copy link
Owner

ocornut commented Sep 17, 2017

I broke away from the drawlist primarily to handle the scrolling of the discs there.

But the scrolling is essentially just offsetting stuff, it may be easier to just handle all of that yourself with ImDrawList as a simple drawing api (with basic clipping for your covers if necessary). Right now there's nothing in your app that looks remotely like a window or the typical use of ImGui.

(I did the same my game The Dragon's Trap essentially piped all its rendering through ImDrawList, without relying on ImGui stuff for the game itself).

Re #983 yeah I realize it doesn't answer "Controlling Z order", just linking the threads because the initial request is the same. If we expose absolute and arbitrary Z values it means the program needs to allocate/know its Z values for the whole application, which might occasionally hinder code sharing or reuse. But I suppose there's no way out of that, might bite the bullet as well.

@mikejsavage
Copy link
Contributor

I found a simple and not too disgusting way to add Z ordering to Imgui.

imgui_user.h: (needs -DIMGUI_INCLUDE_IMGUI_USER_H)

enum WindowZOrder {
        WindowZOrder_Chat,
        WindowZOrder_Scoreboard,
        WindowZOrder_Menu,
        WindowZOrder_Console,
};

namespace ImGui {
        void Begin( const char * name, WindowZOrder z_order, ImGuiWindowFlags flags );
};

Somewhere else:

namespace ImGui {
        void Begin( const char * name, WindowZOrder z_order, ImGuiWindowFlags flags ) {
                ImGui::Begin( name, NULL, flags );
                ImGui::GetCurrentWindow()->BeginOrderWithinContext = z_order;
        }
}

and before you call ImGui::Render():

ImGuiContext * ctx = ImGui::GetCurrentContext();
std::stable_sort( ctx->Windows.begin(), ctx->Windows.end(),
        []( const ImGuiWindow * a, const ImGuiWindow * b ) {
                return a->BeginOrderWithinContext < b->BeginOrderWithinContext;
        }
);

ImGui::Render();

BeginOrderWithinContext isn't used for anything except debug prints so it's ok to clobber it.

@caxapexac
Copy link

ImGui::GetCurrentWindow() isn't working anymore in the @mikejsavage 's solution

Is there any way to just make Begin() to move vertices at the end of draw buffer?

I mean there is ImGuiWindowFlags_NoBringToFrontOnFocus which moves it
I need inverse behaviour

@caxapexac
Copy link

I'm trying to use https://github.com/patrickcjk/imgui-notify
But it seems abandoned
It doesn't render notification on top in docking branch (even when I call render at the end of client code)

This function tries to render on top https://github.com/patrickcjk/imgui-notify/blob/v2/example/src/imgui_notify.h#L237

@caxapexac
Copy link

Can BringWindowToDisplayFront help?

@caxapexac
Copy link

Oh wow it magically solved everything
Why just nobody said about it?

flags can be ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoFocusOnAppearing
(in my case this is toast notifications)

ImGui::Begin(window_name, NULL, flags);
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow()); // needs imgui_internal.h
// something
ImGui::End()

imgui-notify specific
I've added BringWindowToDisplayFront right after Begin inside ImGui::RenderNotifications()

zbuffer
;

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

No branches or pull requests

4 participants