-
-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
Can not open modal popup from menu / Issue with ID stack #331
Comments
Is that exactly the code you are actually using/testing with ? Popup Identifiers have to be part of the ID stack to clear ambiguity and allows a same popup to work from different items sources. So your calls OpenPopup() and BeginPopupModal() have to be in the same level of the ID stack. I imagine your MenuItem() is inside a BeginMenu/EndMenu pair in your code and that adds to the popup stack? Now there is another problem here is that MenuItem() will close your current popup as well. If you understand those things you should be able to come up with a workaround very easily, it is likely that your real code is misplaced (you aren't pasting the full code here). But I still would like to improve the situation here.
|
The exact code I use is complicated, therefore I did not paste it here. However I tried to find the simplest code to reproduce the problem, here it is: ImGui::NewFrame();
if (ImGui::BeginMainMenuBar())
{
if (ImGui::BeginMenu("menu"))
{
if (ImGui::MenuItem("menu item"))
{
ImGui::OpenPopup("popup");
}
if (ImGui::BeginPopupModal("popup"))
{
ImGui::Text("Lorem ipsum");
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
ImGui::Render(); Just to be sure I tried to place BeginPopupModal from the example in every possible place, nothing works. The only solution I found is this, however I hope there is something better: ImGui::NewFrame();
bool b = false;
if (ImGui::BeginMainMenuBar())
{
if (ImGui::BeginMenu("menu"))
{
if (ImGui::MenuItem("menu item"))
{
b = true;
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
if (b)
{
ImGui::OpenPopup("popup");
}
if (ImGui::BeginPopupModal("popup"))
{
ImGui::Text("Lorem ipsum");
ImGui::EndPopup();
}
ImGui::Render(); I've pulled the source code of ImGui yesterday. |
Your first example can't work anyway because the The second example is correct and exactly what I have mentioned, the ID will match. Now I think what would be desirable is to make this example work (currently it won't because the opened popup identifier will be "mainmenubar+popup" and the begin is on "popup", this why I was suggesting a way to alter how the popup is using - or not - the id stack.
|
Now I understand why the first example does not work. Can there be some special way/flag in OpenPopup so that your example works? For example: ImGui::OpenPopup("some_id", FlagPutInRoot)
// somewhere else in root
if (ImGui::BeginPopupModal("popup"))
{ |
Yes I would like to solve that but it would need to be solved in a generic manner not only for popup. I don't know how and when yet (considering there is a workaround for popups it isn't a top priority). |
Ok, I will use the workaround until it's solved. Thank you. |
Hello, I also encoutered this "problem". I have a humble idea, what if when label contains for example 4# at the begining like: |
This is probably a good solution to solve this specific problem (aside from the fact that the amount of # characters may start to be a little worrying). My concern is that it doesn't provide a clear solution to identifying any widget without relying on global id, so it may be good for popup but not for other things. At this point my tendency is to sit on ideas until I can tackle a wider set of related problems all-together to avoid making too many short-term mistakes. So I'd be happy if you want to think about or discuss about identifiers in general and see where it can lead us. Interestingly, for an hypothetical ActivateWidget() function, appending strings without any separator would work (syntactically we could allow a separator such as '/' to make them more readable) but we might still need a way to pass on chain of identifiers involving integers/pointers. |
Aha, just wanted to say that took me a while to understand why the popups didnt work after a MenuItem() as well. |
I stumbled upon the same issue, I kind of understand why this is happening and I was wondering if we could find a temporary solution. Would it be possible to open a modal popup using a variable?
I ended up going back using a Button which kind of works(parent popup stays open), however I can't close the parent popup when I close the modal, ideally I'd like to call
|
I had a similar situation trying to write a Save File Menu Item. It opens up a modal popup for you to write the full path for the file to be saved(temporary until I figure out a good way to incorporate proper File Dialogs) and that ,if the file already exists ,in turn has to open up a stacked modal popup that asks for permission to overwrite. Instead an enum with the states of this situation worked on the first try. Much cleaner and more straightforward. |
In the case of MenuItems...if you've got many modals and possibly stacked as well, having an enum with the full flow in states for each different operation makes it easier to handle multiple modals code in the same scope with minimal variables. You basically have one variable for all the modals and the menu item they get triggered by for each operation without affecting the others. |
I was about to open an issue regarding the same problem, good thing I've searched first. |
My solution to this is to use a lambda. A function pointer can be set at any state (even inside a menu click) and in the end of your code you simply need to call it. Not sure if this has perfomance issues I may be overlooking though, otherwise its pretty handy: {
} |
I found a temporary solution to this bug for anyone waiting for a fix. Hopefully ocornut fixes it soon.
|
A tricky bit with the solution in #331 (comment) is that if you want to set size/position on the popup with if imgui.IsKeyDown(sdl.SCANCODE_ESCAPE) {
imgui.OpenPopup("Menu")
imgui.SetNextWindowSize(imgui.Vec2{X: 400, Y: 0})
imgui.SetNextWindowPosV(imgui.Vec2{X: float32(wd) / 2, Y: float32(ht) / 2}, 0, imgui.Vec2{X: .5, Y: .5})
}
// --------- No windows in here, or else! -----------
if imgui.BeginPopupModalV("Menu", nil, imgui.WindowFlagsNoScrollbar|imgui.WindowFlagsNoResize) {
if imgui.ButtonV("Quit", imgui.Vec2{X: -1, Y: 0}) {
running = false
}
if imgui.ButtonV("Return", imgui.Vec2{X: -1, Y: 0}) {
imgui.CloseCurrentPopup()
}
imgui.EndPopup()
} (this is go, but it maps pretty directly to the c++) Or am I missing a trick somewhere? |
Just came here to say I also ran into this problem, and experienced the current behavior when opening a popup from a MenuItem to be very confusing and non-discoverable from the demo application. I'm using the workaround proposed by @nem0 in 2015, which works, but it kind of ruins the nice immediate property of the rest of the ImGui API by having to explicitly track menu activation state using a boolean and defer the logic of the modal itself to some point after where it is triggered (which could be somewhere way down the source code if you have a long menu). In my case I just want to open a 'confirm quit yes/no?' dialog triggered from the 'Quit..' menu item in the main menu bar, which seems like a very common use case. Would be nice if there would be a better solution. |
Computing the popup ID ahead of time should help.
In the unpublished TestEngine we use path names for identifier and we intend to provide that same functionality in Core eventually. They should also help with this situation. The gist of how those path works is:
“some_id”
“../some_id” // id base seed is one level before.
“../something/some_id” // replace parent level with another base
“/some_id” // id base seed using window base seed
“//some_id” // id base seed is 0
|
That sounds like a nice solution, I will keep watching this issue so I can adapt my code when this is available, thanks! |
Hi, I came up with a different work-around to this after struggling like OP has. I use PushOverrideID from the internal api:
This will work in any context :) hope this helps someone. |
does this still not work still after almost 10 years or am i missing some new api?
and honestly the approach above works but is silly |
The issue is open because the status quo hasn't changed yet. |
This works:
This does not:
This happens
The text was updated successfully, but these errors were encountered: