jMonkeyEngine-Contributions / Lemur

Lemur is a jMonkeyEngine-based UI toolkit.
http://jmonkeyengine-contributions.github.io/Lemur/
BSD 3-Clause "New" or "Revised" License
116 stars 32 forks source link

Label/TextComponent revalidate layout when height changes #30

Closed pspeed42 closed 8 years ago

pspeed42 commented 8 years ago

For some reason a panel is not resizing itself when text contains multiple lines. They end up overlapping: http://hub.jmonkeyengine.org/t/lemur-multiple-multiline-text-blocks/35347

I was pretty sure the layout would be revalidated when text changes but it needs to be checked. Could be related to the layout used.

It's related to how Label interacts with BitmapText to determine preferred size. We clear the text box constraints to determine preferred size but then if the size is constrained we don't re-evaluate the height. Actually there may be no good way to do that... but I'll check.

Here is a full example that illustrates the issue:

package problems;

import com.jme3.app.*;
import com.jme3.math.*;

import com.simsilica.lemur.*;
import com.simsilica.lemur.component.*;

public class MultilineText extends SimpleApplication {

    public static void main( String... args ) {
        MultilineText main = new MultilineText();
        main.start();
    }

    public void simpleInitApp() {

        GuiGlobals.initialize(this);

        Container window = new Container(new SpringGridLayout(Axis.Y, Axis.X, FillMode.Last, FillMode.Last));
        guiNode.attachChild(window);

        window.setLocalTranslation(500, 500, 200);
        window.setPreferredSize(new Vector3f(400, 70, 0));

        Label label1 = window.addChild(new Label("Line1 with lots of text that may wrap\nLine2 also with even more text that may wrap even further."));
        Label label2 = window.addChild(new Label("#############"));
        Label label3 = window.addChild(new Label("Line1 with lots of text that may wrap\nLine2 also with even more text that may wrap even further."));                
    }

}
pspeed42 commented 8 years ago

Label gets a new stylable attribute that lets you set the maximum width of a label.

Lemur layout follow a simple two pass approach: 1) calculate preferred size, 2) layout the components based on actual size. This doesn't give components a chance to change one size because another was constrained... of course, it also avoids the massive iteration that must happen to resolve those situations. It also avoids having to detect which constraints are unsolvable.

Setting the max width of a label is a way around the issue as it it's a good indicator that the label should wrap at a certain width. Vertical sizing can then be properly calculated as part of preferred size calculation.

pspeed42 commented 8 years ago

https://github.com/jMonkeyEngine-Contributions/Lemur/commit/7838bcb088f6957b73f2bdd56cad5fa74cd2d1ff