Nifty Gui - problem with interactOnClick

Hi all,



I have this problem when using Nifty Gui. The mouse over event (setInteractOnMouseOver) works fine, but when I try the on click (setInteractOnClick), it doesn’t respond.



Actually, depending on the panel I show, or the onclick doesn’t respond, or the onclick responds after the second click.



This problem occurs once I have started moving the chase camera from my game… As long as I haven’t moved the chase camera, all is responding fine.



I have no clue what I can do to fix this, since the mouse over event works well…



The following image is my skill bar at the bottom of the game which doesn’t respond to the onclick event after moving the chase camera : http://i.imgur.com/n8Brb.png



The skill bar is all created using Java, except the main panel and layer, which comes from xml.





[xml]

<layer id=“bottomSkills” childLayout=“absolute” >

<panel id=“skillsContainer” align=“center” width=“100%” height=“50px” valign=“bottom” backgroundColor="#0000" childLayout=“absolute” >

</panel>

</layer>

[/xml]



Any help would be greatly appreciated !

Well, here are the behavior :

1- As long as I do not “click” in the screen, my skill bar receives the onClick fine

2- The moment I click on the screen, it doesn’t respond at all… (the onmouseover behavior that works is for another panel)



The way I create the skill bar is as followed :

  • During the simpleUpdate, if I detect that the skill bar needs to be refreshed, I do the following :

    [java]

    if (refreshSkillsBar) {

    Element skillsContainer = screen.findElementByName(“skillsContainer”);



    for (Element element : skillsContainer.getElements()) {

    element.markForRemoval();

    }



    for (int i = 0; i < 10; i++) {

    String image = ActionKeyManager.getInstance().getActionKeyImage(i);

    ItemElement element = new ItemElement(nifty, screen, skillsContainer, 250 + i * ItemElement.SIZE, 650, image, (i + 1 == 10 ? 0 : i + 1) + “”, “itemClicked(” + (i+1) + “)”, null, “#333f”);

    }



    refreshSkillsBar = false;

    }

    [/java]



    I have created the class ItemElement like followed (note that it is a child of PanelCreator):



    [java]

    public class ItemElement extends PanelCreator {

    private static int PanelId = 0;

    private String panelId;

    public static int SIZE = 44;



    public ItemElement(Nifty nifty, Screen screen, Element container, int posX, int posY, String image, String textOver, String callBackOnClick, String callBackOnHover, String backgroundColor) {



    if (callBackOnClick != null) {

    setInteractOnClick(callBackOnClick);

    }



    if (callBackOnHover != null) {

    setInteractOnMouseOver(callBackOnHover);

    }



    if (backgroundColor != null) {

    setBackgroundColor(backgroundColor);

    }



    Element element = createContainer(nifty, screen, container, posX, posY, image);



    if (textOver != null) {

    setTextOver(nifty, screen, textOver);

    }



    if (callBackOnClick != null) {

    element.getElementInteraction().getPrimary().setOnClickMethod(new NiftyMethodInvoker(nifty, callBackOnClick, screen.getScreenController()));

    }

    }



    public String getId() {

    return panelId;

    }



    private void setTextOver(Nifty nifty, Screen screen, String text) {

    LabelBuilder nameLabel = new LabelBuilder(“key”, text);

    nameLabel.set(“x”, “23px”);

    nameLabel.set(“y”, “22px”);



    Element panelElement = screen.findElementByName(panelId);

    nameLabel.build(nifty, screen, panelElement);

    }



    private Element createContainer(Nifty nifty, Screen screen, Element container,

    int posX, int posY, String filename) {



    setPadding(“2px,2px,2px,2px”);

    setVisibleToMouse(“true”);



    setWidth(SIZE + “px”);

    setHeight(SIZE + “px”);

    setChildLayout(“absolute”);

    setX(posX + “px”);

    setY(posY + “px”);



    panelId = “” + PanelId++;

    setId(panelId);



    create(nifty, screen, container);



    Element panelElement = screen.findElementByName(panelId);



    if (filename != null) {

    ImageCreator image = new ImageCreator();

    image.setFilename(filename);

    image.setX(“0px”);

    image.setY(“0px”);

    image.setWidth(“40px”);

    image.setHeight(“40px”);

    image.setId("" + PanelId++);

    image.create(nifty, screen, panelElement);

    }



    return panelElement;

    }

    }

    [/java]



    So that’s pretty much it… any clues ?
or the onclick responds after the second click.


Can you describe that a little more detailed? It happened to me and some others here a while ago that after clicking into the scene nifty doesn't take events anymore. This special case you mentioned did not happen to me and might help finding out where the error happens.(If it's not fixed already in a newer version). I'm using annotations for sending the events maybe that makes the difference.

Where does “callBackOnClick” come from?

From my GameController (child of ScreenController).



I don’t think it’s a problem of how I create the onClick event though, since it works well as long as I don’t click on the screen with my mouse elsewhere.



Thanks !

This is a known issue, I’ve already saw another guy with the same issue before. Maybe it might be a conflict with the input manager…idk.

Grrr… any work around known ? I can rewrite the gui if needs be…

Well, you must read this thread http://hub.jmonkeyengine.org/groups/gui/forum/topic/nifty-window-not-accepting-input-after-clicking-into-the-scene/.

Alright, thanks… I guess I’ll wait for the next stable build as well…

I have tried to look for a solution for the problem and found that the following lines triggers it.



The following comes from ChaseCamera.java and I think the problem comes from the cursor not being recalculated correctly when there is a rotation.



[java]

public void onAction(String name, boolean keyPressed, float tpf) {

if (dragToRotate) {

if (name.equals(ChaseCamToggleRotate) && enabled) {

if (keyPressed) {

canRotate = true;

//inputManager.setCursorVisible(false);

} else {

canRotate = false;

// inputManager.setCursorVisible(true);

}

}

}

}[/java]



I have put in comment the inputManager.setCursorVisible() lines and now the GUI interacts as expected 100% of the time. Though the downside is that the cursor is not being recalculated when I rotate…



Does any of you have a hint of what I could do next ? Perhaps I can “manually” reposition the cursor when dragging ?

You can map keys/mouse buttons multiple times. That’s allowed and supported.



Most likely what happens is the mouse click isn’t consumed or wrongly consumed, or something like that. There’s also the possibility that if a listener has two mappings for the same key does something stopping the other mapping from working correctly after.



I haven’t checked the code, but that’s where I’d look.

A Ha!!



So I’ve discovered that if you change the key mapping of drag to rotate (in FlyByCamera or ChaseCamera) from

[java]inputManager.addMapping(“FLYCAM_RotateDrag”, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));[/java]

to something like:

[java]inputManager.addMapping(“FLYCAM_RotateDrag”, new KeyTrigger(KeyInput.KEY_V));[/java]



Then you can rotate with the V key and clicking into the scene does not prevent you from interacting with Nifty.



This leads me to the conclusion that the problem lies with multiple things being mapped to MouseInput.BUTTON_LEFT



Is this explicitly not allowed? Can anyone think of a solution?

Is there any chance that you are moving the scene and then nifty is reading the location from before you moved it (all inside the same frame) and hence gets confused?



As a test try copying the flycam implementation and starting off with just a blank listener gradually add more code back in until you find the specific operation that triggers the problem.

I am fighting with the same problem. After clicking the scene nifty does not recognize mouse clicks anymore. That it could be a problem with dragable seems to be true.



In one screen with only a flycam and dragable=false I do not have that problem. It occurs only in scenes with a chasecam.

Here i was thinking it was just bad coding on my part. So, anyone figured out how to solve this? I mean, i could use drag-to-rate rebinding for now, but long term that’s not a solution :confused: