Using Layouts with Lemur

Hi,

I’ve been experimenting with Lemur and it seems very good so far, however I’m running into one thing that’s stumped me.

I’m trying to create a window centered on the screen, so to do that I thought I’d create a Container filling the screen with the BorderLayout and then add the popup as a Container inside that.

However when I try it the window just appears in the upper left corner. I’ve tried using both SpringGridLayout and BorderLayout for the outer Container and I’;ve also tried calling setSize on it.

(I’ve scaled the GUI node so it is always 1280x720)

    final Container guiWrapper = new Container();
    guiWrapper.setLocalTranslation(0, 720, 0);
    guiWrapper.setSize(new Vector3f(1280, 720, 1));
    guiNode.attachChild(guiWrapper);

    SpringGridLayout layout = new SpringGridLayout(Axis.X, Axis.Y, FillMode.Proportional, FillMode.Proportional);
    guiWrapper.setLayout(layout);
    
    final Container introWindow = new Container();
    guiWrapper.addChild(introWindow);

    introWindow.addChild(new Label("Gem Gnolls attack!"));
    Button clickMe = introWindow.addChild(new Button("Defend Yourself!"));
    clickMe.addClickCommands(new Command<Button>() {
        @Override
        public void execute( Button source ) {
            guiWrapper.detachChild(introWindow);
        }
    });        

Is there something I’m missing here?

If I just want a popup style window centered on the screen how do I do that in Lemur?

Thanks,
T

1 Like

Perhaps something like this?

final Container guiWrapper = new Container();
guiWrapper.setLocalTranslation(0, 720, 0);
guiWrapper.setSize(new Vector3f(1280, 720, 1));
guiWrapper.setLayout(new SpringGridLayout(Axis.X,Axis.Y));
guiNode.attachChild(guiWrapper);

final Container introWindow = new Container();
introWindow.setInsetsComponent(new DynamicInsetsComponent(0,0,0,0));
guiWrapper.addChild(introWindow,0,0);

introWindow.addChild(new Label("Gem Gnolls attack!"));
Button clickMe = introWindow.addChild(new Button("Defend Yourself!"));
clickMe.addClickCommands(new Command<Button>() {
    @Override
    public void execute( Button source ) {
        guiWrapper.detachChild(introWindow);
    }
});
1 Like

That doesn’t seem to have made any difference:

Capture

I’m going to bed now but I’ll fiddle with inset settings in the morning.

1 Like

You can do it like this :

    /**
     * Apply standard scale and shift window to center
     *
     * @param window
     */
    public void applyStandardTransform(Container window) {
        // Apply standard scale
        window.setLocalScale(1.2f * getStandardScale()); 
        
        int width = getApplication().getCamera().getWidth();
        int height = getApplication().getCamera().getHeight();

        Vector3f prefSize = new Vector3f(window.getPreferredSize());
        prefSize.multLocal(1.2f * getStandardScale());
        // Position window to center
        window.setLocalTranslation((width - prefSize.x) / 2, (height + prefSize.y) / 2, 0);
    }

    public float getStandardScale() {
        int height = getApplication().getCamera().getHeight();
        return height / 720f;
    }

setSize() is not what you want… setPreferredSize() is.

setSize() is what the layouts call to set the size and it’s what the GUI control itself will call the first time a root-level window is displayed… based on the preferred size.

And note, if you want a true pop-up window that blocks input to other controls behind it then there is an app state for that and a convenience method to get it.
http://jmonkeyengine-contributions.github.io/Lemur/javadoc/Lemur/com/simsilica/lemur/GuiGlobals.html#getPopupState()

http://jmonkeyengine-contributions.github.io/Lemur/javadoc/Lemur/com/simsilica/lemur/event/PopupState.html#showModalPopup(com.jme3.scene.Spatial)

I think it makes you position the window yourself, though… because you might not want it centered in the general case (like popup menus and such).

Edit: I think it’s also demonstrated in the demos app… but even if not it’s a useful project to look at anyway:

Thanks @pspeed, I called setPreferredSize and it worked perfectly. It’s a shame setSize is public really (I assume it needs to be?) since it’s easy to cause confusion that way.

For now I’m just messing around trying a few concepts out, but that modal popup does look perfect for when I properly implement this in the future. Thanks.

Thanks, I meant using the Lemur styles/etc but that’s still a useful snippet.

What’s the *1.2 for?

Yes, it needs to be… and you can call it after you have your GUI attached and rendered and it will work as expected. (useful for animation)

It’s just that when a root GUI element is first displayed it will auto size itself. (And laid out components will of course have their setSize() called whenever the layout happens.)