Reputation: 1
I'm having heavy problems with Nifty-GUI's event handling and searched the internet for solutions, but didn't really find any (I want to avoid implementing my own InputSystem). The issue is that, as soon as I start to use nifty with my application, LWJGL seems to not get any keyboard inputs anymore. I already tried several things like nifty.setIgnoreKeyboardEvents(true)
, but it doesn't change anything. I'm aware that I'm probably doing something wrong, but I hope someone here can help me.
These are the relevant code excerpts:
The UI class is responsible for setting up nifty. It's instantiated in another class called Graphics (which implements Runnable, should that be important), but only after LWJGL and OpenGL have been initialised.
public class UI {
private Nifty nifty;
public UI() {
initUI();
}
private void initUI() {
LwjglInputSystem inputSystem = initInput();
nifty = initNifty(inputSystem);
nifty.setIgnoreKeyboardEvents(true);
nifty.fromXml("resources/ClientStartScreen.xml", "start",
new ClientStartController());
}
private LwjglInputSystem initInput() {
try {
LwjglInputSystem inputSystem = new LwjglInputSystem();
inputSystem.startup();
inputSystem.niftyHasKeyboardFocus = false;
inputSystem.niftyTakesKeyboardFocusOnClick = false;
return inputSystem;
} catch(Exception e) {
System.out.println("[ERROR:] Input System could not be"
+ "initialised.");
System.out.println(e.getMessage());
return null;
}
}
private Nifty initNifty(LwjglInputSystem inputSystem) {
try {
return new Nifty(new BatchRenderDevice(
LwjglBatchRenderBackendCoreProfileFactory.create()),
new NullSoundDevice(), inputSystem,
new AccurateTimeProvider());
} catch(Exception e) {
System.out.println("[ERROR:] Nifty could not be initialised.");
System.out.println(e.getMessage());
return null;
}
}
public Nifty getNifty() {
return nifty;
}
}
The screen I'm using is the minimal example, so there should be no issue here:
<?xml version="1.0" encoding="UTF-8"?>
<nifty xmlns="http://nifty-gui.lessvoid.com/nifty-gui">
<useStyles filename="nifty-default-styles.xml" />
<useControls filename="nifty-default-controls.xml" />
<screen id="start"
controller="htw.gt3.trappers.client.screens.ClientStartController">
<layer childLayout="center">
<text id="hellouser" font="aurulent-sans-16.fnt" color="#ffff"
text="Hello user!" />
</layer>
</screen>
</nifty>
And the controller doesn't do anything, there are only the empty overwritten methods.
I'm using a separate class taking care of the input. It's part of the game's main loop (which is part of the Graphics class). The relevant method that's called in the loop starts as follows:
public void checkInput() {
while(Keyboard.next()) {
if(!Keyboard.getEventKeyState()) {
if(Keyboard.getEventKey() == Keyboard.KEY_UP) {
However, the game never enters the while loop because, as I said, Keyboard doesn't receive any events as they're probably consumed by nifty before. Note that my code works properly when I don't use nifty - so when I don't create a UI object in my Graphics class and just stay with my black screen without anything on it, my input works fine.
The main loop looks like this:
boolean niftyDone = false;
while(!Display.isCloseRequested() && !niftyDone) {
controls.checkInput();
Display.update();
Display.sync(60);
if(ui.getNifty().update()) {
niftyDone = true;
}
ui.getNifty().render(true);
}
I really rely on your help here - hopefully someone knows what the issue could be.
Upvotes: 0
Views: 219
Reputation: 1356
As long as Nifty is active - you call nifty.update() - it currently will read the Keyboard events from LWJGL which means they will not be available to you anymore. This is done in the processKeyboardEvents() method in the LwjglInputSystem ... and ... there is nothing you can do about that at the moment.
However, if you set nifty.setIgnoreKeyboardEvents(true) OR Nifty didn't process the event (!) then Nifty will still read them from LWJGL BUT it will internally store them in a Queue and you can read and process them later yourself!
You can call the methods hasNextKeyboardEvent() and nextKeyboardEvent() to read the events. You can find the methods in the LwjglInputSystem class here: https://github.com/void256/nifty-gui/blob/1.4/nifty-renderer-lwjgl/src/main/java/de/lessvoid/nifty/renderer/lwjgl/input/LwjglInputSystem.java#L88
This way you can still handle the keyboard events that Nifty didn't process :)
PS: Of course, the more general issue is that someone wins reading the keyboard events from LWJGL. It's either your game but then Nifty won't get them - or you would need to forward them to Nifty on your own ... OR it's Nifty that reads the event and then they are not available to your game using the regular Keyboard.next() approach.
We decided to use the second option since in many cases people will only use the GUI (menu screens, etc) without the game code being active at the same time. So in these cases it would have added more work to the user to forward the events manually but with the current solution it kinda works out of the box without additional work.
But for cases you need both, I think the solution above should work just fine.
Upvotes: 0