[SOLVED] Need help with horizontal ListBox

Hi friends

In my case I rotated ListBox horizontally

So I need to rotate back elements inside ListBox, but I have some problems here,
here I am trying to rotate back the first element (elemnts are lemur button) and resize it, but

Rotation works ok, but the button does not move or resize. (Seems like they are being controlled by listbox layout)

see the code :

                 for (int i = 1; i <= 2; i++) {
                    Texture icon = getApplication().getAssetManager().loadTexture(new TextureKey("/editor-128.png"));
                    InventoryItem invItem = new DefaultInventoryItem("Editor", icon);
                    ((Button) invItem.getView()).setColor(ColorRGBA.Red);
                    //Add items to ListBox
                    systemTray.getModel().add(invItem);

                }
                // Grab first element in list box
                Button cell = (Button) ((InventoryItem) systemTray.getModel().get(0)).getView();
                //Rotation works fine (some how)
                cell.getControl(GuiControl.class).getNode().rotate(new Quaternion().fromAngleNormalAxis(FastMath.HALF_PI, Vector3f.UNIT_Z.clone()));
                //Transform not work
                cell.getControl(GuiControl.class).getNode().move(0, -cell.getPreferredSize().y, 0);
                //Setting PreferredSize not work
                //swap height and width 
                cell.getControl(GuiControl.class).setPreferredSize(new Vector3f(cell.getPreferredSize().y, cell.getPreferredSize().x, cell.getPreferredSize().z));

There is another easy solution, to just hardcode the text on icon image using an Image editor, then rotate it 90 degree counter-clockwise. But I don’t like to hardcode it.

Appreciate any help

Yes, the list controls the placement. I’m not sure how else that could work. If you rotate the children it would need to be in such a way that positioning would still be the same… you can’t move() them because the list box will put them where it thinks they should be. None of the layouts take rotation into account… but neither do they set it.

I assume you’ve done this just by rotating the ListBox?

Given that list box is just a combination of a grid panel and a scroll bar, you might actually have an easier time forking list box and making it use a column based grid (just swap row for column, etc.) then a horizontal scroll bar. It may be that the row click calculation needs to be redone, too, but maybe not. I don’t know how hard it would be to make the base ListBox switchable.

Yes I am giving a HALF_PI rotation to the container which contains the listbox.

I will look into it to see If I can do something.
But it would be better to have this built in to ListBox, you know just for everybody to obey the same standards.

Yes, of course. Or to have a gridpanel wrapper that supports both horizontal and vertical scrolling.

…but right now if you wait for me to do it then it could be a while. :slight_smile: So I offer advice for self-help in the mean time.

1 Like

Thanks for the hint,
It was too easy to create a basic one.

/**
 * Item box supports slider.
 * 
 * @author Ali-RS <ali_codmw@yahoo.com>
 */
public class ItemBox3D extends Container {

    private ArrayGridModel<Panel> model;
    private GridPanel grid;
    private Button next;
    private Button previous;
    private Slider slider;
    private VersionedReference<Double> sliderIndex;

    public ItemBox3D(ArrayGridModel<Panel> model) {
        this.model = model;
        this.grid = new GridPanel(model);

        BorderLayout layout = new BorderLayout();
        getControl(GuiControl.class).setLayout(layout);

        layout.addChild(BorderLayout.Position.Center, grid);

        next = new Button(" > ");
        next.setTextHAlignment(HAlignment.Center);
        next.setTextVAlignment(VAlignment.Center);
        layout.addChild(BorderLayout.Position.East, next);
        next.addClickCommands(new Command<Button>() {
            @Override
            public void execute(Button source) {
                scroll(1);
            }
        });

        previous = new Button(" < ");
        previous.setTextHAlignment(HAlignment.Center);
        previous.setTextVAlignment(VAlignment.Center);
        layout.addChild(BorderLayout.Position.West, previous);
        previous.addClickCommands(new Command<Button>() {
            @Override
            public void execute(Button source) {
                scroll(-1);
            }
        });

        this.slider = new Slider(Axis.X);
        layout.addChild(BorderLayout.Position.South, slider);
    }

    @StyleAttribute(value = "visibleItems", lookupDefault = false)
    public void setVisibleItems(int row, int column) {
        grid.setVisibleRows(row);
        grid.setVisibleColumns(column);
        slider.setModel(new DefaultRangedValueModel(0, model.getColumnCount() - column, 0));
        this.sliderIndex = getSlider().getModel().createReference();
    }

    public Slider getSlider() {
        return slider;
    }

    public GridPanel getGridPanel() {
        return grid;
    }

    protected void scroll(int amount) {
        double delta = getSlider().getDelta();
        double value = getSlider().getModel().getValue();
        getSlider().getModel().setValue(value + delta * amount);
    }

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

        boolean indexUpdate = sliderIndex.update();
        if (indexUpdate) {
            grid.setColumn(sliderIndex.get().intValue());
        }
    }

}

Calling it 3D because going to add 3D elements into cells, also going to add support for D&D stuffs.

Thanks for the help.

btw, this is not clear enough for me, can you please explain what this annotation is doing?
@StyleAttribute(value = "visibleItems", lookupDefault = false)

1 Like

It’s for the styling support. When you create a new element then it usually applies styles. (Yours doesn’t because you never call the super class.) You should take a look at things like ListBox to see how they call the protected super constructor and then apply styles. It will be nicer for you if you ever want to have styling on your container.

That line is specifically saying that when the “visibileStyles” attribute is set in styling that it will call that method to set it.

1 Like

I see.
I reread the documentations for Styling on wiki page and it get more clear now.
I will fix that on my ItemBox3D class.

Thanks for the help.