Reload styles on lemur

I’ve been trying to reload a lemur style. I’ve tried many workarounds but I can’t find any way. What I got so far is (for a desired panel):

Styles styles = GuiGlobals.getInstance().getStyles();

//styles.clearCache();
new StyleLoader().loadStyle(styleFile.toString(), new FileReader(styleFile));

styles.applyStyles(container, container.getElementId(), container.getStyle());

if(styles.getAttributes(container.getElementId(), container.getStyle()).get("layout")
                                                                           == null) {
     container.setLayout(layout);
} else {
    // Patch because of the layout children aren't updated correctly
    for(Node node : layout.getChildren()) {
        container.getLayout().addChild(node);
    }
}

However, it doesn’t matter how I try to patch/workaround the re-styling, I can’t achieve it.
I wanted to make an style auto-updater so I could change the style file and have the changes shown in real-time (As far as I know, it would have the limitation of that all code-made styling wouldn’t work, but is something I can afford) but I’m not sure this is currently possible with Lemur or not. If so, any help to have the styling reload well-done is welcome ;).

A simple test-case to try it:

public class TestLemurReloadStyles extends SimpleApplication {


    Container container;
    Panel inPanel;
    float time;

    public static void main(String[] args) {
        new TestLemurReloadStyles().start();
    }

    public void simpleInitApp() {
        // Lemur Gui setup
        GuiGlobals.initialize(stateManager.getApplication());
        BaseStyles.loadGlassStyle();

        GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");

        container = new Container(new SpringGridLayout(Axis.Y, Axis.X, FillMode.None, FillMode.None));

        inPanel = container.addChild(new Panel());

        inPanel.setPreferredSize(new Vector3f(50, 50, 1));
        container.setPreferredSize(new Vector3f(100, 100, 1));



        container.setLocalTranslation(300, 300, 0);
        guiNode.attachChild(container);
    }

    @Override
    public void simpleUpdate(float tpf) {
        super.simpleUpdate(tpf);

        time += tpf;

        if(time > 3) {
            System.out.println("Reloading styles");
            GuiLayout layout = container.getLayout();

            GuiGlobals.getInstance().getStyles().applyStyles(container, container.getElementId(), container.getStyle());
            GuiGlobals.getInstance().getStyles().applyStyles(inPanel, inPanel.getElementId(), inPanel.getStyle());

            if(GuiGlobals.getInstance().getStyles().getAttributes(container.getElementId(), container.getStyle()).get("layout") == null) {
                container.setLayout(layout);
            } else {
                //Patch because of the layout children aren't updated correctly
                for(Node node : layout.getChildren()) {
                    container.getLayout().addChild(node);
                }
            }

            inPanel.setPreferredSize(new Vector3f(50, 50, 1));

            time = 0;
        }


    }
}

Styles should override previously defined attributes when they are reloaded… old now unset attributes won’t be cleared, of course. Also, without the ability to completely start over some styles won’t be applied properly if they rely on only being set if no value is set. (Only a problem if you are trying to undefine something.)

Otherwise, loading a style on top of the existing styles should reset the attributes, I think. You will definitely have to clear the cache (the line you have commented out) though because for a particular element ID the style attribute map is cached the first time it is built.

Step one would be to make sure the attributes are really changing and that’s an easy enough test to make without even creating GUI elements. Just load a style, check the attribute, load a different style that resets it, then check again.

Edit: also for some GUI elements, applyStyles() might not be enough unless the style is fully defined. As I recall, some of the GUI elements manually look up some stuff before applying the styles and that’s done during construction.

Essentially you are trying to do something that it was specifically not designed to do.

I think this may be the main cause of my problems. I have a key mapping set to a textfield, so when I press “Enter” it sends the message to a text area (console), which, somehow, after applying the applyStyles() to every panel in the guinode, it stops working.

Yep… may be, after two days stuck with this I think I’ll finally give up on it and continue working off-runtime (I liked the idea of a real-time view style creation).

Anyway… (maybe something to another topic) it is possible to apply an attribute to any style through the .groovy file? ie:

selector('*') {
    fontSize = 14
}

Wild cards aren’t supported as far as I remember.

I think you can set global defaults in code but not directly through a fancy style language closure. (You could always resort to Java.)

You can use a selector for a style… which is generally a better idea.

Anyway, as I recall, the Styles object is bound directly into the scripting environment so you can always call stuff directly on it like:
styles.setDefault(someFont)

…but you are limited to default values for objects in that case. Otherwise you will have to at least stick to a style or use the default style (null). That’s what everything undefined is supposed to fall back on anyway.