I recently started a thread in which we ended up discussing the possibility of adding support for navigating DirectGUI via keyboard or gamepad. Built-in support seems likely to be some time away, so, for my current main project, I want to look at implementing such support on my end.
I have ideas for the actual navigation–how to handle moving between UI-elements. What I’m rather uncertain about is the question of how to highlight the currently-selected item.
The ideal, I would imagine, would be to have DirectGUI elements highlight as though the mouse were hovering over them–that would at least be consistent with mouse-interaction. But, as I mentioned in the thread linked-to above, DirectGUI (or DirectButton, at least) seems to be implemented in a way that runs counter to that.
Which is where I find myself uncertain.
I do have two potential expedients in mind:
First, I could add an indicator-image of some sort that shows up when a non-mouse input-device is used, and vanishes when the mouse is moved. This would be placed near the selected UI-element to convey that selection.
Second, I could (perhaps–I’m not sure that it would work) just warp the mouse to the selected UI-element, hoping that DirectGUI would treat that as a mouse-over.
Mouse cursor is nothing to do with, as far as I know, it is uncontrollable. However, it is possible to emulate a cursor — a collision ray for the gui elements. Which will be handled by an X, Y gesture.
You can warp the mouse-cursor, I do believe. (It’s part of how I usually implement first-person controls, warping the cursor back to the centre of the screen.) Warping the mouse to the centre of the screen, for example, may be done like so:
if base.mouseWatcherNode.hasMouse and base.win.hasSize():
base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2)
(That uses Python 2.7 code; in Python 3 I would presumably want to use “//” instead of “/”.)
I suppose that I could have the gamepad thumbstick move an emulated cursor–but I’m not sure that doing so answers the question of how to make a given UI-control highlighted.
Yeah, I think that DirectGUI is implemented under the assumption that it will be operated by mouse. :/
It’s possible to have a selected GUI-item (maintained in your own code), and to call its command-function or give it focus, I believe. It’s the highlighting that’s the tricky part… :/
That is to say, you can do this:
# Under some condition:
self.currentMainMenuControl = self.startGameButton
# When a button is pressed:
That, in my experience, is a little trickier than you might expect.
I actually dealt with much the same in a side-project of mine recently: the view would start off looking at the sky because the “start game” button happened to be above the centre-point. I ended up not only resetting the mouse-position, but waiting a few frames before doing so, if I’m not much mistaken.