Disabling a DirectGUI and all children

When using DirectGUI, is there a simple way to disable a GUI element and all sub-components thereof? If not, is there some other way (aside from manually deactivating all appropriate GUI elements) of creating a modal dialogue (that is to say, one that, when visible, prevents all other GUI elements shown before it from taking interactions, and which re-activates them on being hidden or destroyed)?

I’m attempting to create a simple GUI that pops up over another GUI, the latter of which contains a number of buttons. The obvious way of making this pop-up modal is to iterate over all of the buttons in the underlying GUI and set their state, but I’m hoping for a less clunky solution.

(I suppose that I could look at one of the other GUI solutions mentioned in these fora, but I’ve constructed a fair bit of GUI in DirectGUI thus far, and am hesitant to re-work what I have in another system.)

Just make your dialog DirectFrame or NodePath parent of the elements within it, and then use show() and hide() to activate and deactivate the entire dialog.

As for deactivating elements below your dialog, have you tried making a DirectFrame on top of them that covers the whole screen and eats the mouse events?

The DirectDialog classes support passing fadeScreen=0.5 to the constructor; this puts a blank card (of the specified alpha value) behind the dialog to eat mouse events, exactly as rdb suggests.

It uses base.transitions.fadeScreen() to do this; you can simply call this function directly as well.


Ah, thank you both!

I think that I’ll start by looking into making my pop-up a DirectDialog instead of a DirectFrame; if that fails me, I’ll likely look into putting up the event-eating card/frame. Indeed, such a frame may come in handy in other parts of my game, so thank you either way!

(And I am indeed already using show() and hide() as part of the invocation and dismissal of my dialogue.)

One question about the event-eater, if I may: do they stack well? Would it, for example, be feasible to build a heirarchy of menus that each override any previous, regardless of order of invocation, simply by making the base GUI element of each a DirectDialog or adding event-eaters for each?

[edit 2]
All right, some experimentation reveals that using a DirectDialog works well, as long as whatever is below it is not itself a DirectDialog.

Given this, perhaps I should look to using a GUI stack, making my GUI roots all DirectDialogs and hiding whatever GUI is covered by the most recent GUI.

Am I missing a better option, or does this sound reasonable? If the latter, does such a thing exist somewhere in Panda, or should I implement it myself? (It shouldn’t be difficult at all, I daresay, but I’d rather use an extant implementation if available, I think.)