Nifty popup forwards typed-in keys in a textfield

I’ve got a popup where you can rename stellar objects but as you type the new name, all bound keys to inputManager are triggered. Is there something I’m not seeing here?



The forum posts didn’t offer anything sadly. I could hack that by resetting all bound keys while that popup is visible but… yeah. There has to either be a proper way to do this.



Why are keys typed in a textfield forwarded to jME3 anyway?

@void256?

Nifty currently seems to only handle key down events and not key up events. This means that Nifty will return handled = true when you have pressed the key and handled = false when you release the key again.



Might this be the issue?



Besides that I’m not used to the InputManager in jme and what you can do with it :confused:

void256 said:
Nifty currently seems to only handle key down events and not key up events. This means that Nifty will return handled = true when you have pressed the key and handled = false when you release the key again.

Might this be the issue?

My methods bound to keys are only triggered when the keys are released.

I was under the impression that if a click/keystroke or any interaction with a Nifty element or control was being processed it wouldn't forward those events.

I also just tested that keypress/keyrelease and every time I release a key that is bound the event gets triggered. Holding it down doesn't trigger it (behaving as it should).

So in short what you describe might be the problem. My question is, with a control that takes keyboard input, shouldn't nifty NOT forward that event at all? The same goes with any element or control that implements interaction. Or am I seeing this from the wrong side?

No, I think you’re right! :slight_smile:



I’ve checked it again and when Nifty translates the physical keyboard input event (the one it got from jme) into the logical input event (f.i. NiftyInputEvent.Activate or a character key event, basically the event thing that Nifty handles inside) it will currently only check for key down events. Unfortunately a key-release event is translated into “null” because currently there is no logical event that I can think of that will be triggered specifically when a key is being released.



Further down the processing this logical event “null” is handled as “not processed”. This is true to some degree because the (physical) key release event was not translated into a logical event and therefore there is nothing to be handled. So Nifty did not at all handle the key release event.



But all of this happens deep inside of Nifty and since the event travelled that far means that it was send to an element/control that had the keyboard focus and therefore should be handled no matter if it was a key down or a key release event. I think simply acknowledging the key release event as well will be more appropriate and will probably be not so confusing :slight_smile:



I’ll try to fix that for 1.3.1.

Cool stuff! Thanks. :smiley:



While I wait for that to be implemented I’ll just skip renaming stuff or use unbound keys. :slight_smile:

@madjack: what about a simple button? it usually reacts to space and return keys only. if the keyboard focus is on a button and I would press, let’s say the key “a” you don’t want the button (which means Nifty) to handle that event, right?

That’s hard to say really, but as a general rule I would say that if it’s a popup, since they’re “modal”, you don’t want to forward anything. Keys and such should be gobbled up. That’s my take on this.



But, as far as normal controls and elements go, I would say that if that element isn’t made to process a certain key, it should forward it. Take a button for example; you can’t do anything with it if you don’t press “Enter”, “Space” or “click on it”. So if someone hits “a” it should forward that key.



Then again… if a screen contains an input control and it’s focused it, obviously, it should eat that key up, but it’s not the same thing we’re talking about.



I think the best solution would be to add a tag along the line of forwardInteractions=“true/false” that could be linked to pretty much anything. Screen, layer, panel, control, element. That way you give complete control to users. Of course if used with a control or an element other than screen, layer or panel, then it would only stop interaction when that “element” has the focus. When true with layer or panel, then it should not forward those events when they’re visible.



As an example, take my basic GUI. By default I don’t want nifty to use any of the keystrokes since what’s on the screen is pretty much decoration and information for the user, but on certain popups or panels (that act like popups) I don’t want those to pass anything down, whatever key/click is used. Setting it to false would then do things the way you do them right now. But I honestly think it should be turned on by default. That way any interaction isn’t forwarded at all. The drawback is that if you turn that on for a small panel, all input would eaten by nifty, but there’s always a tradeoff.



I also think that using something like “forwardInteractions” would simplify your life too… I might be wrong on that one though. :wink:



If doing something like this isn’t to your liking then if a control isn’t made to use certain keystrokes it should ignore them and pass them down. I would much rather you use my suggestion though. :wink:



Hopefully that makes sense. :smiley:

Ok, the simplest, most straightforward solution would look like this:


  1. A NiftyControl has the keyboard focus
  2. All keyboard events are consumed by Nifty no matter if the control does actually care about the event or if it was a key up event



    Together with the suggested new booleans to globaly toggle if events will be forwarded to Nifty at all this seems like a good, simple way to handle those things.



    The only drawback would be, that when a control has the keyboard focus you won’t be able to execute a game shortcut anymore. For instance a control does not handle the cursor left key but your game does. When this control has the keyboard focus you’re game cursor left key would still work with the current Nifty. With the new change in this cursor-left key would be consumed by Nifty and it will never reach your game (unless you toggle forwarding the event to Nifty with the new boolean). Can you live with that? :slight_smile:

I obviously sent my message before I’ve read your suggestion :smiley:



You want to be able to control at the Nifty element level (screen, panel, control, whatever) if Nifty should handle events or if it should forward them to the game?

Yeah. I can live with that. No contest.



You know as you build your screen/element/etc that if you toggle this On (if it’s not on by default) it’ll act that way, so you either find a way to cope with it or you post a bitching reply. :wink:



Seriously though, I think that would work. But I have another suggestion for you. Since the jME community is probably your biggest user base, I think it would be a really good idea to start a new thread and propose to everyone what we’ve just talked about (or link this post here in that new thread) because there won’t be any exposure to other users in this thread. I’m only one man and I’m sure other could chime in with ways to handle this.



It’s up to you. :slight_smile:

void256 said:
I obviously sent my message before I've read your suggestion :D

You want to be able to control at the Nifty element level (screen, panel, control, whatever) if Nifty should handle events or if it should forward them to the game?

At first I was only thinking in terms of panels and screens, but I included other elements too. I'm not entirely sure that would be a great idea actually...
void256 said:
Together with the suggested new booleans to globaly toggle if events will be forwarded to Nifty at all this seems like a good, simple way to handle those things.

LOL I thought that was a direct correlation to my post. :P

Ok, what about:


  1. When a control has the keyboard focus it “captures” all keyboard events. There are no exceptions. Every keyboard event sent will be consumed by Nifty.


  2. You’ll get a way to remove the keyboard focus. When no Nifty element has the keyboard focus all events will be forwarded to your game.


  3. You can get focus to a control either by Java or by clicking the control with the mouse.



    Together with the global boolean to completly disable or enable processing of keyboard events you should be all set, right?
Together with the global boolean to completly disable or enable processing of keyboard events you should be all set, right?


This would mean, that even when a control has the keyboard focus and should "capture" all events you can still override that with setting the global boolean to "don't process keyboards events nifty no matter what".
void256 said:
Ok, what about:

1. When a control has the keyboard focus it "captures" all keyboard events. There are no exceptions. Every keyboard event sent will be consumed by Nifty.

I have a problem with that. Nifty will automatically put the focus on an element if I don't select one myself (usually the first control), so by default anything visible containing a control will suck all events into the void (no pun intended). Check the picture at the end.


2. You'll get a way to remove the keyboard focus. When no Nifty element has the keyboard focus all events will be forwarded to your game.

That's fine but what happens if the scrollbar get the focus? Or a listbox? Those should only process up/down (mouse wheel). Not keystrokes. Would those count as "elements"? Or would that be things you can interact with like buttons, checkMarks, radiobuttons or things you can change the "state" of?


3. You can get focus to a control either by Java or by clicking the control with the mouse.

Or with an
[xml]
<effect>
<onHover="focus"> [/xml]
or something like that...


Together with the global boolean to completly disable or enable processing of keyboard events you should be all set, right?

I don't like the "global boolean" if it means it's tied to a screen and nothing else. If it's tied to a screen, layer or panel, yeah (that's pretty much what I was suggesting in my previous post). But if it's only tied to the screen it'll bring a ton of problems.


This would mean, that even when a control has the keyboard focus and should “capture” all events you can still override that with setting the global boolean to “don’t process keyboards events nifty no matter what”.

I honestly would do it the other way around. The global flag gives the default behavior. Controls, elements and whatnot overriding this would only apply when these (and their children) are visible.

So, you have a screen that says: FORWARD STUFF.
But there's this panel (or whatever) that is by default hidden/invisible but when it's rendered, I want the events to NOT BE FORWARDED. I think that'd be the proper way to do this.

Here's an example.

In my game when you select a star it pops up a panel. In it 3 buttons. With #1, as soon as this is visible, all input is eaten by nifty. I don't want that. It's just information and some interaction.

Just refering to that panel on the right of your screenshot (the one with the 3 buttons).



When will you actually be able to use the TAB key to toggle between the 3 buttons?



I see only two ways:


  1. when you hover that panel with your mouse it gets somehow activated and will from now on respond to keyboard events. when you move your mouse away from the panel it will not react to keyboard events anymore.


  2. you somehow “activate” the panel with somekind of an hotkey from within your game.



    right?



    when a scrollbar gets the keyboard focus you really want it to respond to keyboard events as well (up and down cursor keys for instance). but that makes no difference at all. in Nifty an element (element is everything, it can be a panel) is focusable or it isn’t. It’s the same for each kind of control/element/panel. when it’s able to get the keyboard focus it will get the keyboard focus.
void256 said:
When will you actually be able to use the TAB key to toggle between the 3 buttons?

The short answer is, I don't. TAB will be used to give score and misc. information. Besides, it's only 3 buttons and this isn't a productivity tool where everything has to be programmed with "accessibility" in mind. But I get your point.


1. when you hover that panel with your mouse it gets somehow activated and will from now on respond to keyboard events. when you move your mouse away from the panel it will not react to keyboard events anymore.

2. you somehow "activate" the panel with some kind of an hotkey from within your game.

right?

For me #1 would be the only way to go. #2, blah. I wouldn't do that personally, but others might.

But again (I know, I know :P) I think my way is preferable. If you turn interaction off, you'll have to do it by hand. If you want to tab from button to button, you can implement it in the screen controller (input manager's bound key calls a method in the SC that tabs to next button when it has the focus. If it doesn't have the focus you do nothing or something else like display score, etc). You wouldn't have to check if something has the focus or the mouse if hovering (for that purpose evidently), by default it would act the way you've set it to act.

Here’s another example. When that info panel is opened I don’t want ANY interaction to go through. If I miss my click or click slightly of the panel, I might end up picking a different star.



Right now, to achieve that “no pick”, I have to toggle a flag that stops the “picking” part. I wouldn’t have to do that with the new system, but as with the original problem, if I hit a key (released), it gets processed. Since I have many keys bound, I have to implement multiple flag checking for each key.



We’re arguing about the same thing really, just its implementation. :slight_smile: But I wanted to give you this example too.



Is that a “Nifty” popup? or is that just a regular panel?