Search code examples
javalibgdx

Libgdx slider - drawables are drawn the wrong size


I am drawing a slider with Libgdx using the following code:

    Pixmap pix = new Pixmap(200, 50, Pixmap.Format.RGBA8888);
    pix.setColor(Color.BLACK);
    pix.fill();
    skin.add("sliderBackS", new Texture(pix));

    Pixmap pix1 = new Pixmap(10, 70, Pixmap.Format.RGBA8888);
    pix1.setColor(Color.RED);
    pix1.fill();
    skin.add("knobS", new Texture(pix1));

    Slider.SliderStyle sliderStyle = new Slider.SliderStyle();
    sliderStyle.disabledBackground = skin.newDrawable("sliderBackS");
    sliderStyle.disabledKnob = skin.newDrawable("knobS");
    sliderStyle.background = skin.newDrawable("sliderBackS");
    sliderStyle.knob = skin.newDrawable("knobS");

    skin.add("sunSlider", sliderStyle);
    sunlightSlider = new Slider(0, 100, 1, false, sliderStyle);
    stage.addActor(sunlightSlider);

    sunlightSlider.setBounds(300, 300, 100, 10);

    sunlightSlider.setDisabled(true);
    sunlightSlider.setDebug(true);

And then else where:

    stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
    stage.draw();

But for some reason the pixmaps in the slider seem to be drawn at their actual size. This can be seen in the following picture (the green line is what it should be, from the debug):

slider wrong size For some reason the width seems to be constrained by sunlightSlider.setBounds(300, 300, 100, 10); but the height does not.

I know that I could choose the pixmap size to what ever I need, but I want to use an image from file. If I use a big image, then it overflows the bounds similarly.

I want it to look like it is above, but constrained to the green rectangle.

What am I doing wrong?


Solution

  • A TextureRegionDrawable, which is what you've created with your newDrawable calls, by default has a minimum size that matches its original pixel dimensions. The minimum size of the Drawable prevents the Slider widget from drawing it as small as it would like to fit it into its own bounds. So you can reduce the minimum size:

    sliderStyle.disabledBackground = skin.newDrawable("sliderBackS");
    sliderStyle.disabledBackground.setMinWidth(0);
    sliderStyle.disabledBackground.setMinHeight(0);
    // and so on for other new drawables.
    

    I'm not sure what your long term plans are, but typically you want all your skin's images to be part of a single Texture object so the SpriteBatch doesn't have to flush itself many times to draw your whole scene.

    If for some reason you're not doing that, you can at least make all these solid color drawables use the same texture. It can simply be a one-pixel white texture that is shared by everything. Also, make sure you are disposing of the pixmap you use to create a texture, or you are leaking memory!

    Pixmap pix = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
    pix.setColor(Color.WHITE);
    pix.fill();
    Texture tex = new Texture(pix);
    pix.dispose();
    skin.add(tex, "white");
    
    Drawable blackDrawable = skin.newDrawable("white", Color.BLACK);
    Drawable redDrawable = skin.newDrawable("white", Color.RED);
    
    Slider.SliderStyle sliderStyle = new Slider.SliderStyle();
    sliderStyle.disabledBackground = blackDrawable;
    sliderStyle.disabledKnob = redDrawable;
    sliderStyle.background = blackDrawable;
    sliderStyle.knob = redDrawable;
    

    Since you passed your Texture object to the Skin, the Skin will dispose of it when the Skin is disposed. Don't forget to dispose of the Skin in the dipose() method.