I’m developing an application for the XBox using XNA, with a custom made UI framework.
For this I developed a navigation system, the navigation system works as followed:
The system exists of pages, each page contains child UI elements, which all have
one or more PageTabs as I called them.
The pagetabs are objects, having 2 properties, X and Y.
(I know I could have used Point, but the pagetab class has some methods also)
Based on the current state of the system, I check for input, and I raise events on elements with the right pagetab.
So I have this array:
pages[]{
Start,
Exit,
Settings,
…}
Then, I use an enum for my state, like Start, and access the page navigatable elements like this:
pages[Start].Navigatables[]
This is an array containing all the pagetabs of the page. When you go down, Y gets increased, and vice versa. Same for X
This works great, it keeps the max & min Y&X values in mind, so something always get selected.
However, this system has one major flaw, it can only box input for 1 state.
But say I am for example on the start page,
so my state is Start, and I have a popup, with 2 buttons, pagetabs:
(1,1) & (2,1)
The system as it currently is designed, will look for ALL elements in the current state with the selected pagetab, but I need to make it so that if the popup is visible, only the popup accepts navigation, and everything else won’t react to user input (gamepad).
I was thinking of adding an extra List to the PageTab class, which contains ‘substates’ on which the element may accept input, but there must be a better way, ain’t there?
I hope I explained it good enough, if you need more info I’ll be glad to provide it.
I went with the extra Z-index approach.
Using a different Z-index for some elements and catching this input works like a charm.
I also added a flag: IndependentNavigation, which makes sure some elements are Z-index-independent (so one could click somewhere different when a dropdown is opened for example)