The game engine needs to accept input from several devices, mainly Xbox, Windows and WP7. For each of them a different input controller must be used.
The input device is an independent class, it has no power to actually do anything or change anything. Instead what happens is it interprets the input of the user using various means (selection boxes, touches, radial menus, etc.) depending on the device. Once it knows what the action is (select units in rectangle, interact with clicked position, etc.) it sends a message with all the relevant data, to be caught and acted upon by whoever is responsible.
Having a system like this prevents having lots of cases for the different controllers distributed all through the code, and also avoids duplication of work.
The basic idea is that the primary input of the user gets transformed into some kind of command with data that then the engine then interprets homogenously, without knowing who sends the message. Adding new input devices is therefore trivial, as the engine just receives messages of commands to execute.
As for the GUI elements themselves, they hang from the input device they are designed for (no sense having a selection box in the Xbox for example), and the input device object is always on the top of any other nodes so it gets the input / drawn first. The input device has a GUINode that is active at the moment. That’s the one which attempts to answer to the user event (say a keypress), if it consumes the event, that’s it. If not, we send a message to the system, to see if any other node wants anything to do with that event.
Having the GUINodes independent of the InputDevice class makes it so if we want a standard GUI element (say a minimap), we just add the MiniMapGUINode to the InputDeviceNode, and we know it’s going to be on top, whereas if we want something more local (for example a speech bubble) we add it to the player node, and it’s going to be in the proper Z height, at the same as the player.