How to make a 2-dimensional slider?

this is my first time uploading a video, so be gentle, lol, and any tip is appreciated.

2 Likes

Thank you for all these details! (and great video ! :p)

I am currently working on two small problems encountered:

  • the fact that the analog slider does not come back to the center when I release it
  • the fact of positioning the panels according to the windows and not the screen itself. I may not be very clear … But for example if I reduce the size of my application window, if my panel is too far to the right, I will not see it. So for the moment I am trying to recover the size of the window to send it a% at the level of its position, I don’t know if this is possible…

In fact it is rather 3 worries because working on a project involving nifty at the start, I will have to redefine sliders with Lemur to read them back to the joystick (because we must also realize them alongside in vertical sliders ^^)

Thank you so much @pankey :slightly_smiling_face:

1 Like

I saw that, but once the application launched, I have the impression that if we reduce the size of the window, the proportion is not preserved unfortunately

i didnt make it to return to the origin, i made something like that to the joystickpanel, but you can do this

    if(!this.slider.isDragging()){
        this.slider.setAnalog(0, 0);
    }

that will return your stick to a place you want when is not touched, just put that code on an update method

i dont know if i understand correctly, i think 2 things with this

  1. you can also do

     slider.setLocalTranslation(0, 0, 0);
    

that way you can position the panel normaly , or

2.if you want to keep the proportion position, and you have changed the screen resolution( i havent done that, and didnt knew it could be done, lol) you have to tell that to the ScreenGuiUtils class, since that static class is the one doing that proportion calculation( but i think i doesnt need to because it still have the reference of the application and the appsettings, but i dont really know), so if you change the resolution you might have to call this after

    ScreenGuiUtils.initialize(this);//this is meant to be an application class
    slider.setLocalGuiTranslation(50, 0, 0);

this part i dont understand what is the problem, i used nifty for a while but didnt like it, so i turn to lemur and is more frexible and more powerfull in my opinion

1 Like

I was talking about the resizable option with AppSettings class. With nifty the position of my panels remained permanently proportional to the size of the “window”. I will read the doc to see if I can find out how it’s done.

Thank you very much for all your answers. I will continue to work on it in more detail in the coming days.

I think i finally get what your saying, well never had thought of this, but is better to see this flaw now rather then later, ill eventually add something inside each panel class to prevent the movement of the panel when someone resize the window, here is and example of easy fix of the problem

/**
 *
 *
 *  @author    Pankey
 */
public class Main extends SimpleApplication {
    JoystickPanel joy;
    JoystickPanel joy1;
    JoystickPanel joy2;
    JoystickPanel joy3;
    JoystickPanel joy4;
    AnalogSlider slider;
    Geometry geom;
    int lastwidth;
    int lastheight;
    
    public static void main( String... args ) throws Exception {
        Main main = new Main();
        AppSettings settings = new AppSettings(true);
        settings.setResizable(true);
        main.setSettings(settings);
        main.start();
    }
    private Vector2f analgoPos;

    public Main() {
        //super( new StatsAppState(), new DebugKeysAppState(), new TestGuiNodeState());
        super(
                 new StatsAppState()
                ,new DebugKeysAppState()
        );
    }

    @Override
    public void simpleInitApp() {
        this.setDisplayStatView(false);
        //this.setDisplayFps(false);
        this.setShowSettings(false);
        GuiGlobals.initialize(this);
        ScreenGuiUtils.initialize(this);

        GuiGlobals.getInstance().getStyles().setDefault(new TestPhysicControlStyle("TestPhysicControlStyle"));

        Box box = new Box(1, 1, 1);
        geom = new Geometry("box", box);
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);

        Texture texture = assetManager.loadTexture("Textures/Monkey.png");
        mat.setTexture("ColorMap", texture);

        geom.setMaterial(mat);
        geom.setLocalTranslation(0, 2, 0);
        rootNode.attachChild(geom);

        Box floor = new Box(100, 1, 100);
        Geometry floorgeom = new Geometry("box", floor);
        Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat2.setColor("Color", ColorRGBA.Blue);

        Texture texture2 = assetManager.loadTexture("Textures/Monkey.png");
        mat2.setTexture("ColorMap", texture2);

        floorgeom.setMaterial(mat2);
        floorgeom.setLocalTranslation(0, 0, 0);
        rootNode.attachChild(floorgeom);

        //Center
        //TopRight
        //TopLeft
        //BotRight
        //BotLeft
        slider = new AnalogSlider(Move.All,GuiOrigin.BotLeft,"TestPhysicControlStyle");
        slider.setAnalog(0, 0);
        slider.setAlpha(0.8f);
        this.analgoPos = this.slider.getAnalog();
        slider.setLocalGuiTranslation(75, 0, 0);
        this.guiNode.attachChild(slider);

        joy1= new JoystickPanel(Move.All,"TestPhysicControlStyle");
        joy1.setLocalGuiTranslation(10, 50, 0);
        this.guiNode.attachChild(joy1);

        joy2= new JoystickPanel(Move.All,"TestPhysicControlStyle");
        joy2.setLocalGuiTranslation(20, 70, 0);
        this.guiNode.attachChild(joy2);

        joy3= new JoystickPanel(Move.All,"TestPhysicControlStyle");
        joy3.setLocalGuiTranslation(80, 50, 0);
        this.guiNode.attachChild(joy3);

        joy4= new JoystickPanel(Move.X,"TestPhysicControlStyle");
        joy4.setLocalGuiTranslation(70, 70, 0);
        this.guiNode.attachChild(joy4);

        this.lastwidth = this.settings.getWidth();
        this.lastheight = this.settings.getHeight();

    } 

    @Override
    public void simpleUpdate(float tpf) {
        if(this.slider.isDragging() && this.slider.getDragLocalTranslation() != null){
            this.analgoPos = this.slider.getAnalog();
        }
        if(this.settings.getWidth() != this.lastwidth || this.settings.getHeight()!= this.lastheight){
            this.lastwidth = this.settings.getWidth();
            this.lastheight = this.settings.getHeight();
            slider.setLocalGuiTranslation(75, 0, 0);
            slider.setLocalGuiSize(new Vector3f(25,25,1));
            slider.setAnalog(this.analgoPos);
            joy1.setLocalGuiTranslation(10, 50, 0);
            joy2.setLocalGuiTranslation(20, 70, 0);
            joy3.setLocalGuiTranslation(80, 50, 0);
            joy4.setLocalGuiTranslation(70, 70, 0);
            joy1.setLocalGuiSize(new Vector3f(10,10,1));
            joy2.setLocalGuiSize(new Vector3f(10,10,1));
            joy3.setLocalGuiSize(new Vector3f(10,10,1));
            joy4.setLocalGuiSize(new Vector3f(10,10,1));
        }
        if(this.joy1.isDragging() && this.joy1.getDragLocalTranslation() != null){
            Vector3f joy1pos = new Vector3f(this.joy1.getDragLocalTranslation().x,this.joy1.getDragLocalTranslation().y,1);
            this.getCamera().setLocation(this.getCamera().getLocation().add(joy1pos.mult(0.0001f)));
        }
        if(this.joy2.isDragging() && this.joy2.getDragLocalTranslation() != null){
            Vector3f joy2pos = new Vector3f(this.joy2.getDragLocalTranslation().x,1,-this.joy2.getDragLocalTranslation().y);
            this.geom.move(joy2pos.mult(0.0001f));
        }
        if(this.joy3.isDragging() && this.joy3.getDragLocalTranslation() != null){
            this.rotateCamera(-this.joy3.getDragLocalTranslation().x, Vector3f.UNIT_Y);
            this.rotateCamera(this.joy3.getDragLocalTranslation().y, Vector3f.UNIT_X);
        }
        if(this.joy4.isDragging() && this.joy4.getDragLocalTranslation() != null){
            this.geom.rotate(0, this.joy4.getDragLocalTranslation().x*0.0001f, 0);
        }
    }

    public void rotateCamera(float value, Vector3f axis){

        Matrix3f mat = new Matrix3f();
        mat.fromAngleNormalAxis(0.00001f * value, axis);

        Vector3f up = cam.getUp();
        Vector3f left = cam.getLeft();
        Vector3f dir = cam.getDirection();

        mat.mult(up, up);
        mat.mult(left, left);
        mat.mult(dir, dir);

        Quaternion q = new Quaternion();
        q.fromAxes(left, up, dir);
        q.normalizeLocal();

        cam.setAxes(q);
    }
}

Hi,

I’ve tried what you sent before, but instead of moving the slider to its new position, the slider only diseapear.

thats weird, i only set the slider location, size and stick position after the width or height was changed, this is how it looks to me

Edit: well, i do have a different a style for this last example, but it shouldnt had moved your panel outside the window

I tried the exact same Main class as you, but it didn’t work. Maybe there is a link with the TestStyle class. Can I see TestPhysicControlStyle please ? :slight_smile:

Sorry about that, here is the style TestPhysicControlStyle that i used on the last example

   /**
     *
     * @author Pankey
     */
    public class TestPhysicControlStyle {

        public TestPhysicControlStyle(String style){
            Styles styles =GuiGlobals.getInstance().getStyles();
            Attributes attrs;

            Vector2f fullSize = ScreenGuiUtils.getScreenGuiUtils().setSize(100, 100);
            Vector2f sliderbar = ScreenGuiUtils.getScreenGuiUtils().setSize(10, 10);
            Vector2f sliderstick = ScreenGuiUtils.getScreenGuiUtils().setSize(100, 20);
            Vector2f tittle = ScreenGuiUtils.getScreenGuiUtils().setSize(40, 15);
            Vector2f label = ScreenGuiUtils.getScreenGuiUtils().setSize(40, 30);
            Vector2f button = ScreenGuiUtils.getScreenGuiUtils().setSize(20, 10);
            Vector2f photoslider = ScreenGuiUtils.getScreenGuiUtils().setSize(40, 40);
            Vector2f list = ScreenGuiUtils.getScreenGuiUtils().setSize(22, 10);

            Texture monkey = GuiGlobals.getInstance().loadTexture("Textures/Monkey.png",false,false);
            Texture blood = GuiGlobals.getInstance().loadTexture("Textures/blood.jpg",false,false);
            Texture black = GuiGlobals.getInstance().loadTexture("Textures/black.jpg",false,false);
            Texture white = GuiGlobals.getInstance().loadTexture("Textures/white.png",false,false);

            QuadBackgroundComponent labelC = new QuadBackgroundComponent (white);
            labelC.setAlpha(0.5f);

            attrs = styles.getSelector("container", style);
            attrs.set("background", new QuadBackgroundComponent (monkey));
            attrs.set("preferredSize", new Vector3f(button.x,button.y,1));

            attrs = styles.getSelector("tittle", style);
            attrs.set("background", labelC);
            attrs.set("alpha", 0.8f);
            attrs.set("color", ColorRGBA.Blue);
            attrs.set("preferredSize", new Vector3f(tittle.x,tittle.y,1));
            attrs.set("textVAlignment", VAlignment.Center);
            attrs.set("textHAlignment", HAlignment.Center);
            attrs.set("fontSize", 25);

            attrs = styles.getSelector("label", style);
            attrs.set("background", labelC);
            attrs.set("alpha", 0.8f);
            attrs.set("color", ColorRGBA.Blue);
            attrs.set("preferredSize", new Vector3f(label.x,label.y,1));
            attrs.set("textVAlignment", VAlignment.Center);
            attrs.set("textHAlignment", HAlignment.Center);
            attrs.set("fontSize", 25);

            attrs = styles.getSelector("button", style);
            attrs.set("background", labelC);
            attrs.set("alpha", 0.8f);
            attrs.set("color", ColorRGBA.Blue);
            attrs.set("preferredSize", new Vector3f(button.x,button.y,1));
            attrs.set("textVAlignment", VAlignment.Center);
            attrs.set("textHAlignment", HAlignment.Center);
            attrs.set("fontSize", 25);

            attrs = styles.getSelector("joystick", style);
            attrs.set("background", new QuadBackgroundComponent (monkey));
            attrs.set("guiSize", new Vector3f(10,10,1));

            attrs = styles.getSelector("joystick.stick", style);
            attrs.set("background", new QuadBackgroundComponent (monkey));
            attrs.set("guiSize", new Vector3f(50,50,1));

            attrs = styles.getSelector("analogslider", style);
            attrs.set("background", new QuadBackgroundComponent (monkey));
            attrs.set("guiSize", new Vector3f(25,25,1));

            attrs = styles.getSelector("analogslider.stick", style);
            attrs.set("background", new QuadBackgroundComponent (black));
            attrs.set("guiSize", new Vector3f(50,50,1));

            attrs = styles.getSelector("stick", style);
            attrs.set("background", new QuadBackgroundComponent (monkey));
            attrs.set("guiSize", new Vector3f(50,50,1));

            attrs = styles.getSelector("flexiblelist", style);
            attrs.set("flexible", false);
            attrs.set("order", GuiOrder.x);
            attrs.set("listType", ListType.DuoImage);
            attrs.set("listVisibility", ListVisibility.All);
            //attrs.set("guiSize", new Vector3f(50,50,1));
            attrs.set("initialGuiSize", new Vector3f(20,20,1));
            attrs.set("alpha", 0.9f);     
            attrs.set("guiTranslation", new Vector3f(0,0,1));
            attrs.set("gridPosition", new Vector2f(0,0));
            attrs.set("gridSize", new Vector2f(3,3));
            attrs.set("listStart", 0);
            attrs.set("listEnd", 3);
    //        attrs.set("gridStart", new Vector2f(0,0));
    //        attrs.set("gridEnd", new Vector2f(3,3));
            attrs.set("background", new QuadBackgroundComponent (monkey));

            attrs = styles.getSelector("list", style);
            attrs.set("isSelected", false);
            attrs.set("alpha", 0.8f);
            attrs.set("touchTexture", black);
            attrs.set("untouchTexture", blood);


            attrs = styles.getSelector("photoslider", style);
            attrs.set("visibleGridSize",  new Vector2f(0,0));
            attrs.set("rootpath",  "Hand/Numbers/0");
            attrs.set("background", new QuadBackgroundComponent (monkey));
            attrs.set("preferredSize", new Vector3f(photoslider.x,photoslider.y,1));

            attrs = styles.getSelector("photoslider.analogslider", style);
            attrs.set("background", new QuadBackgroundComponent (blood));
            attrs.set("guiSize", new Vector3f(10,100,1));

            attrs = styles.getSelector("photoslider.analogslider.stick", style);
            attrs.set("background", new QuadBackgroundComponent (monkey));
            attrs.set("guiSize", new Vector3f(100,10,1));

            attrs = styles.getSelector("photoslider.flexiblelist", style);
            //attrs.set("flexible", true);
            attrs.set("order", GuiOrder.xy);
            attrs.set("guiSize", new Vector3f(50,50,1));
            //attrs.set("initialSize", new Vector3f(list.x,list.y,1));
            //attrs.set("alpha", 0.9f);     
            //attrs.set("guiTranslation", new Vector3f(0,0,1));
            attrs.set("gridPosition", new Vector2f(0,0));
            attrs.set("gridSize", new Vector2f(3,3));
            attrs.set("listStart", 0);
            attrs.set("listEnd", 5);
    //        attrs.set("gridStart", new Vector2f(0,0));
    //        attrs.set("gridEnd", new Vector2f(1,1));
            attrs.set("background", new QuadBackgroundComponent (monkey));
        }
    }

you can also print the new location of the panel on the update method to see where the panel had went

System.out.println(slider.getLocalGuiTranslation());
System.out.println(slider.getGuiSize());

We arrived to move the slider as we wanted ! Thanks for your answers.
I was wrong on the function which makes the stick on the center when we release it.

1 Like