This project is read-only.

Hiding/Showing GUI on the fly

Nov 19, 2012 at 3:20 AM
Edited Nov 19, 2012 at 4:09 AM

Just started playing around with Nuclex and came across something that doesn't seem to be explained anywhere. Simply put: I want to be able to hide and show the GUI (I'm only using GUI, Input and associated dependencies) at the press of a button. At first I used GuiManager.Visible but that simply makes the GUI invisible and the user interactions still work if you know where to click. My solution is now to add or remove the GuiManager and InputManager components on input, see below:

            if (previousKeyState.IsKeyUp(Keys.E) && keyboardState.IsKeyDown(Keys.E))
            {
                editing = !editing;

                if (editing)
                {
                    Components.Add(this.gui);
                    Components.Add(this.input);
                }
                else
                {
                    Components.Remove(this.gui);
                    Components.Remove(this.input);
                }
            }

 

Is this the standard way of doing it or have I missed something? There is a bug with this method. If you put this code into the GUI demo you can click when the interface is hidden but when it comes back the clicks will be processed. Steps to reproduce: move mouse over quit button, press E to hide the interface, then click, then press E again. I debugged into the code and found that the mouse clicks were still captured in the mouse event queue even though the components had not been receiving update calls. Is there a way to flush/purge or ignore input events?

Additionally how do I hide/show windows? The demo destroys windows and creates new ones. In some cases I wish to retain the state of the window even while hidden.

Nov 19, 2012 at 4:36 AM
Edited Nov 19, 2012 at 4:40 AM

In the mean time I temporarily wrote a function for InputManager called FlushInput() until I get an answer. FlushInput() purges all input events from all devices. It's probably a handy addition to the code base. How do I go about incorporating my code back into the nuclex project? Or is it a single developer project?

Dec 14, 2012 at 8:14 AM

Usually this is done by not routing input to the GUI (there's a special interface through which the GUI receives its input that you can pass through your own code to decide whether the GUI should receive and process input). See the IInputCapturer and DefaultInputCapturer classes.

For cases where the GUI is on screen and the game accepts input at the same time, there are some properties (IsMouseOverGui and IsInputCaptured) to decide whether a mouse click was picked up by the GUI or whether is was outside of any window, meaning is belongs to the game.

The repository currently has only one committer, me ;-) - I do accept interesting patches, but I think your method isn't such a good idea to have. Flushing the input queue will eat KeyUp and ButtonRelease notifications and wreak all kinds of havoc. One could extend the method to look at which keys are currently down and send release notifications after clearing the queue, but that would trigger a button press, for example, if the mouse was just holding a button down while the player pressed "E" (in your case). The IInputCapturer and DefaultInputCapturer classes already cover this scenario in a cleaner way, imho.