Nifty: how to intercept mouse clicks

Not sure why this is not done by default but if I have a nifty screen, I can still click through it (and do other stuff in jME) which probably messes up other things by mistake. How can I make the Nifty screen NOT clickable through?



So if I have a nifty screen with buttons on it , if I click the screen (not the buttons) the event isn’t intercepted by the screen and messes up other stuff behind the screen (say camera position) - does that make any sense? sorry couldn’t find a better way of explaining this.

Put a visibleToMouse layer at the back of the nifty screen.



It’s done like that so you can have a HUD over the screen and still interact with the screen.

2 Likes

ok it’s not working as I expected, here’s my code:



[java]



<?xml version=“1.0” encoding=“UTF-8”?>

<nifty xmlns=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance

xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd”>

<useStyles filename=“nifty-default-styles.xml” />

<useControls filename=“nifty-default-controls.xml” />

<screen id=“start” controller=“bla bla bla”>

<layer id=“background”>

<!-- <panel id=“menu_bar” width=“100%” height=“25px” backgroundColor="#00f8" /> -->

</layer>

<layer id=“foreground” backgroundColor="#0000" childLayout=“horizontal” >



<panel id=“panel_left” width=“80%” height=“100%” childLayout=“vertical” >

<!-- spacer -->

</panel>

<panel id=“panel_right” width=“20%” height=“100%” childLayout=“vertical”

backgroundColor="#00f8">

<panel id=“panel_top_right” width=“100%” height=“50%” childLayout=“vertical”>



</panel>







</panel>



</layer>

</screen>

</nifty>

[/java]



where do I place visibleToMouse = true ? I tried all over and it’s always the same thing



I even created a parent layer for everything and still… no luck



thanks

Return false from any method you want to consume the mouse event.

not sure I quite understand you… return false where? in my java hud controller class? I don’t get it… sorry





edit:

just making sure my question was undersood correctly. I want the GUI portion of the screen to be affected by the mouse clicks but consuming the mouse event and not allow it to go beyond it and affect other things in jME



does visibleToMouse = true do that?

It’s really worth reading the Nifty manual. It covers what you are talking about.

[xml]<layer id=“background” visibleToMouse=“true”>[/xml]



should work I expect, I’ve never tried it.

Sorry, I don’t use XML to define Nifty… so… it would be something like:



interactOnClick=“consumeEvent()”

interactOnRelease=“consumeEvent()”



depending on which you want to catch. I really can’t remember if there is a way to differentiate between left/right click… but I got it working somehow. Actually, come to think of it… there is a way… I know I am using both left/right click/release and mouse wheel for scrolling hovered elements. The above can be set on any type of element.



somewhere in your controller class:



// Not sure if this actually needs to be public or can be protected/private

public boolean consumeEvent() {

return false;

}



Anyways… this is the only method that I know of for consuming events that works. And PLEASE don’t request that Nifty do this automatically… that was a nightmare lol



Ok… I remember how I got right-click, mouse wheel interaction to work (and it is some SERIOUS hackery… as is a ton of my work-arounds for get nifty to create movable/resizable windows, right-click context menuing, etc, etc) I’m doing my own check against mouse focus as part of the main game loop… this is limited to the class types I define (all the controls I use are custom). I’m intercepting events and deciding what to hand off to Nifty and what to handle myself… and then hand off to nifty by spoofing events that Nifty actually does understand. Part of this whole process was to allow Nifty to consume events from that point forward because handling it outside of this method would be kinda redundant and silly… mostly silly. Anyways… long story short… this was answer I got from void when asking the same question. There may/may not be another method of doing this now… but this has worked for forever and I’ve never had an issue with it… UNTIL SOMEONE CHANGED THIS TO AUTOMATICALLY BE HANDLED BY NIFTY >.< Worst 2 weeks of my JME life.

@sploreg - it’s not in the manual I already looked it up



@t0neg0d - your method although logical doesn’t work because (1) that means i’m going to have to put that interaction in every single control (but then how about the panels) and (2) in a control like this:

[java]<control name=“button” label=“Plan” id=“btnPlan” align=“center” valign=“bottom” >

<interact onClick=“plan()”/>

</control> [/java]



then how do you do it? as it can only handle on interact and I don’t want to lose the plan() method.



@zarch - I wish this works but it doesn’t. This would have been the simplest.

I think this issue is more complicated than it looks like, @void256 sorry to bug you but can you give an input?



thanks

If making the layer interactive doesn’t work then just place a panel filling the layer and make that interactive.



visibleToMouse might be enough, if not then add an onClick and “consume” the event in the onClick.

I’m not just posting the manual for my health, the answer is in there. Specifically the mouse input section.

You have to set visibleToMouse=“true” and it will grab the mouse event, and items below it won’t. It has to be set on a panel, or element; so make one the size of your screen and set visibleToMouse=“true”. I have done this in many places and it does work.

What exactly do you mean by “grab the mouse events”.

intercept … for example, if left click in my game allows you to select the player and there’s a nifty GUI on the right side of the screen , I don’t want the player once he click on something inside the GUI to also be able to select a player in the game. I want ithat mouse event to be INTERCEPTED in the GUI and not pass it along to jME

anyone? I put my code up , I would appreciate the help on this one



thanks

Sorry, I’m not sure why it’s not working for you. @void256 might be able to help.

ok but doesn’t VisibleToMouse = true allows that Nifty doesn’t get affected with whatever we click the background (non gui) and not vice versa?



just to make sure i’m on the right track cz I spent WAYYY more time that I intended on this one,



if I have game that allows me to select a person using mouse left button and a HUD display GUI at the bottom. If the mouse cursor was on one of the HUD nifty controls and the user clicked it but by coincidence it also happened to be above the player, I do not want jME to allow this player to get selected (and thats what I meant by intercepting the mouse clicks thru nifty). So i don’t want jME to get affected by anything coming from the GUI (and not vice versa). Are we on the same page? just making sure.



@sploreg, I read the manual, I have my code up here, it just doesn’t work.

visibleToMouse=“true” will make Nifty intercept that click. I suggest that to trace down the issue, just have one panel in your hud. Make it large, colored but a little transparent, and put it in the middle of your screen. Then test various settings to see where the clicks are going through.

I already did for example, I have a method that outputs a string to the console whenever left click is used (in jME) and still no luck



[java]<?xml version="1.0" encoding="UTF-8"?>

<nifty xmlns="http://nifty-gui.sourceforge.net/nifty-1.3.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://nifty-gui.sourceforge.net/nifty-1.3.xsd http://nifty-gui.sourceforge.net/nifty-1.3.xsd">

<useStyles filename="nifty-default-styles.xml" />

<useControls filename="nifty-default-controls.xml" />



<screen id="start" controller="com.animation.animator3d.gui.AnimationHudController">

<!-- Main Screen -->

<layer id="background">

<!-- background is empty -->

</layer>



<layer id="foreground" backgroundColor="#0000" childLayout="vertical">

<panel id="panel_up" height="90%" width="100%" align="center" childLayout="center" >

<!-- must be able to left click in this area -->



</panel>



<panel id="panel_bottom" height="10%" width="100%" align="center" childLayout="horizontal" backgroundColor="#00f8"

visibleToMouse="true">

<!-- must NOT be able to left click in this area -->

</panel>

</layer>



</screen>

</nifty>



[/java]

@garnaout said:
@sploreg - it's not in the manual I already looked it up

@t0neg0d - your method although logical doesn't work because (1) that means i'm going to have to put that interaction in every single control (but then how about the panels) and (2) in a control like this:
[java]<control name="button" label="Plan" id="btnPlan" align="center" valign="bottom" >
<interact onClick="plan()"/>
</control> [/java]

then how do you do it? as it can only handle on interact and I don't want to lose the plan() method.

@zarch - I wish this works but it doesn't. This would have been the simplest.



I know when you use the PanelCreator you can set interaction on them... if I am not mistaken a button is just and extension of a panel. Perhaps you can do the same in XML?

If you use this method, Nifty consumes the event and it is never passed through to JME (whether or not setVisibleToMouse is true)