martes, 1 de septiembre de 2015

Templated Nifty XML with FreeMarker

I finally managed to add a most missed feature (in my opinion) in nifty-gui, though I had to add it on top of my nifty-flow add-on.

Benefits, quite clear to me, for (more or less) the same screen, let me show you the comparison on code and difference in the paradigm. It also allows you to focus in a single way of working and not needing to learn two ways of making the same job, including style. I hate working on front end.

OLD VERSION, Using Java Builder because there's a dynamic number of lists to render.

public final class SelectKeyboardControlsScreenGenerator implements ScreenGenerator {

    @Autowired    private Nifty nifty;
    @Autowired    private SelectKeyboardControlsScreenController controller;
    /**     * Singleton     */    @Autowired    private GameConfiguration gameConfiguration;

    @Override    public void buildScreen(String screenUniqueId) {
        if (nifty.getScreen(screenUniqueId) != null) {
            nifty.removeScreen(screenUniqueId);
        }
        buildScreenNow(screenUniqueId);
    }

    public void buildScreenNow(String screenUniqueId) {

        Collection<KeyboardCommandStateListener> keyListeners
                = gameConfiguration.getPreGameModel().getByType(KeyboardCommandStateListener.class);

        //sorting commands in alphabetical order of command name        List<KeyboardCommandStateListener> sortedCommands = newArrayList(keyListeners);
        Collections.sort(sortedCommands, new Comparator<KeyboardCommandStateListener>() {
            @Override            public int compare(KeyboardCommandStateListener o1, KeyboardCommandStateListener o2) {
                return o1.toString().compareTo(o2.toString());
            }
        });

        final PanelBuilder outerPanelBuilder = new PanelBuilder("PartitionPanel") {
            {
                height("80%");
                childLayoutHorizontal();
            }
        };

        final PopupBuilder popupBuilder = new PopupBuilder("popup") {
            {
                text("some text");
            }
        };

        List<List<KeyboardCommandStateListener>> partitionedSorted = Lists.partition(sortedCommands, 4);

        int partitionIndex = 0;
        for (List<KeyboardCommandStateListener> currentPartition : partitionedSorted) {

            final PanelBuilder partitionPanelBuilder = new PanelBuilder("Partition" + partitionIndex++ + "Panel") {
                {
                    height("80%");
                    childLayoutVertical();
                }
            };

            for (final KeyboardCommandStateListener currentCommandListener : currentPartition) {
                final PanelBuilder commandNamePanelBuilder = new PanelBuilder(currentCommandListener.toString() + "Panel") {
                    {
                        childLayoutHorizontal();

                        text(new TextBuilder("text") {
                            {
                                text(currentCommandListener.toString());
                                style("nifty-label");
                                alignCenter();
                                valignCenter();
                                height("10%");
                                margin("1%");
                            }
                        });

                        control(new ListBoxBuilder(currentCommandListener.toString()) {
                            {
                                displayItems(4);
                                selectionModeSingle();
                                optionalHorizontalScrollbar();
                                optionalVerticalScrollbar();
                                alignCenter();
                                valignCenter();
                                height("10%");
                                width("10%");
                                margin("1%");
                            }
                        });

                    }
                };

                partitionPanelBuilder.panel(commandNamePanelBuilder);
            }

            outerPanelBuilder.panel(partitionPanelBuilder);
        }

        Screen screen = new ScreenBuilder(screenUniqueId) {
            {
                controller(controller); // Screen properties
                // <layer>                layer(new LayerBuilder("Layer_ID") {
                    {
                        childLayoutVertical(); // layer properties, add more...
                        // <panel>                        panel(outerPanelBuilder);
                        // </panel>                        panel(new PanelBuilder("Panel_ID") {
                            {
                                height("20%");
                                childLayoutHorizontal();
                                control(new ButtonBuilder("PreviousButton", "Back") {
                                    {
                                        alignCenter();
                                        valignCenter();
                                        interactOnClick("back()");
                                    }
                                });

                                control(new ButtonBuilder("NextButton", "Next") {
                                    {
                                        alignCenter();
                                        valignCenter();
                                        interactOnClick("next()");
                                    }
                                });

                                control(new LabelBuilder("RepeatError") {
                                    {
                                        alignRight();
                                        valignCenter();
                                        text("");
                                        width("50%");
                                        color(new Color("#ff0"));
                                    }
                                });

                            }
                        });

                    }
                });
                // </layer>            }
        }.build(nifty);
    }


NEW VERSION, two files, some preparation of data in the Generator

public final class SelectKeyboardControlsScreenGeneratorXML extends FtlTemplateGenerator {

    /**     * Singleton     */    @Autowired    private GameConfiguration gameConfiguration;

    public SelectKeyboardControlsScreenGeneratorXML(Nifty nifty) throws IOException {
        super(nifty, "/mod/common/interface_keyboardselector.xml");
    }

    @Override    protected Map injectProperties() {
        Collection<KeyboardCommandStateListener> keyListeners
                = gameConfiguration.getPreGameModel().getByType(KeyboardCommandStateListener.class);

        //sorting commands in alphabetical order of command name        List<KeyboardCommandStateListener> sortedCommands = newArrayList(keyListeners);
        Collections.sort(sortedCommands, new Comparator<KeyboardCommandStateListener>() {
            @Override            public int compare(KeyboardCommandStateListener o1, KeyboardCommandStateListener o2) {
                return o1.toString().compareTo(o2.toString());
            }
        });

        final List<List<KeyboardCommandStateListener>> partitionedSorted = Lists.partition(sortedCommands, 4);

        return new HashMap() {{ put("partitionedKeyboardCommands", partitionedSorted);}};
    }

    public void setGameConfiguration(GameConfiguration gameConfiguration) {
        this.gameConfiguration = gameConfiguration;
    }
}

PLUS the XML with some extra intelligence

<?xml version="1.0" encoding="UTF-8"?><nifty xmlns="http://nifty-gui.sourceforge.net/nifty.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:schemaLocation="http://nifty-gui.sourceforge.net/nifty.xsd http://nifty-gui.sourceforge.net/nifty.xsd">
    <useStyles filename="nifty-default-styles.xml" />
    <useControls filename="nifty-default-controls.xml" />

    <screen id="${screenUniqueId}" controller="com.navid.trafalgar.mod.common.SelectKeyboardControlsScreenController">
        <layer id="background" childLayout="center">
        </layer>
        <layer id="foreground" childLayout="vertical" style="nifty-panel-no-shadow">
            <panel id="panel_top" height="15%" width="75%" align="center" childLayout="center">  
                <text text="Select the keys..." font="Interface/Fonts/Default.fnt" width="100%" height="100%" />
            </panel>
            <panel id="panel_mid" height="70%" width="75%" align="center" childLayout="horizontal" style="nifty-panel-red">

                <panel id="panel_mid_left" width="100%" align="center" childLayout="horizontal">
                    <#list partitionedKeyboardCommands as partition>
                        <panel id="partition_${partition?counter}" width="50%" align="center" childLayout="vertical">
                            <#list partition as keyboardCommands>
                                <panel id="keyboardCommands_${keyboardCommands}" align="center" childLayout="horizontal">
                                    <control id="${keyboardCommands}" name="listBox" displayItems="4" forceSelection="true" horizontal="off" width="30%" align="left" />
                                    <text text="${keyboardCommands}" font="Interface/Fonts/Default.fnt" align="right" />
                                </panel>
                                <text text="" font="Interface/Fonts/Default.fnt" align="right" />
                            </#list>
                        </panel>
                    </#list>

                </panel>

            </panel>
            <panel id="panel_bottom" height="15%" width="75%" align="center" childLayout="horizontal">  
                <panel id="panel_bottom_right" height="50%" width="25%" valign="center" childLayout="center">  
                    <control name="button" label="Back" id="QuitButton" align="center" valign="center"                              visibleToMouse="true" > 
                        <interact onClick="back()"/>
                    </control>
                </panel>
                <panel id="panel_bottom_right3" height="50%" width="25%" valign="center" childLayout="center">  
                    <control name="button" label="Select ship" id="PlayButton" align="center" valign="center"                              visibleToMouse="true" > 
                        <interact onClick="next()"/>
                    </control>
                </panel>
            </panel>
        </layer>
    </screen>
</nifty>

Please notice the use of Freemarker commands like list or .counter.

Already uploaded to version 0.4.0 in https://github.com/albertonavarro/nifty-flow

No hay comentarios:

Publicar un comentario