Skip to content

Instantly share code, notes, and snippets.

@fkaa
Created August 12, 2012 08:19
Show Gist options
  • Save fkaa/3330643 to your computer and use it in GitHub Desktop.
Save fkaa/3330643 to your computer and use it in GitHub Desktop.

Slider

You've probably seen the slider in the options GUI a lot. But what you might not know is that you can't use it directly in your GUI if you so wished. The slider is hardcoded to work with the options GUI and to be able to use it, we have to make our own slider.

The easiest way to do this is to copy the contents of GuiSlider and pasting it into a new class which can be called GuiSliderFixed for example. After you've pasted the code, the first thing you need to do is change the class name and constructor name from GuiSlider to GuiSliderFixed.

After you're done with that, we can go over what's making the slider un-usable in the first place. The constructor has a parameter called EnumOptions par4EnumOptions. This parameter decides which option the slider is going to modify, and if left to null, it will cause a NullPointerException, since further down in the code the parameter is being used. To fix this, we need to remove all references to EnumOptions in the class. After you're done with that the slider class should look something like this

package net.minecraft.src;

import net.minecraft.client.Minecraft;
import org.lwjgl.opengl.GL11;

public class GuiSliderFixed extends GuiButton {

    public float sliderValue = 1.0F;
    public boolean dragging = false;

    public GuiSliderFixed(int id, int x, int y, String label, float startingValue) {
        super(id, x, y, 150, 20, label);
        this.sliderValue = startingValue;
    }

    protected int getHoverState(boolean par1) {
        return 0;
    }

    protected void mouseDragged(Minecraft par1Minecraft, int par2, int par3) {
        if (this.drawButton) {
            if (this.dragging) {
                this.sliderValue = (float) (par2 - (this.xPosition + 4)) / (float) (this.width - 8);

                if (this.sliderValue < 0.0F) {
                    this.sliderValue = 0.0F;
                }

                if (this.sliderValue > 1.0F) {
                    this.sliderValue = 1.0F;
                }

            }

            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
            this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
        }
    }

    public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) {
        if (super.mousePressed(par1Minecraft, par2, par3)) {
            this.sliderValue = (float) (par2 - (this.xPosition + 4)) / (float) (this.width - 8);

            if (this.sliderValue < 0.0F) {
                this.sliderValue = 0.0F;
            }

            if (this.sliderValue > 1.0F) {
                this.sliderValue = 1.0F;
            }

            this.dragging = true;
            return true;
        } else {
            return false;
        }
    }

    public void mouseReleased(int par1, int par2) {
        this.dragging = false;
    }
}

Adding the fixed slider to a GUI is also very trivial. Seeing as it extends GuiButton, all you need to do is add it to the controlList like this

    this.controlList.add(new GuiSliderFixed(3, width / 2 - 75, height - 30, "Working slider!", 0));

However, it wont be exactly like the sliders in the option GUI. The reason for that is that we removed the part of the slider which shows the current value at the end. Just appending the value to the label wont work in this case because the slidervalue only going from 0 to 1. To fix this, we can introduce two new parameters to the constructor, which will control the maximum value and set the label to a local variable, to seperate the displayString and the label. We can then set the displayString to the new label variable plus the slidervalue multiplied by the maximum value.

    public float sliderValue = 1.0F;
    public float sliderMaxValue = 1.0F;
    public boolean dragging = false;
    public String label;

    public GuiSliderFixed(int id, int x, int y, String label, float startingValue, float maxValue) {
        super(id, x, y, 150, 20, label);
        this.label = label;
        this.sliderValue = startingValue;
        this.sliderMaxValue = maxValue;
    }

After that, we can move on to the appending of the slidervalue to the label. Looking at what we removed, we see that the label plus value was set in two methods, MouseDragged and MousePressed. We can actually skip setting it in MousePressed, since MouseDragged is called even when the mouse is just pressed. We'll also convert the slidevalue to int to avoid decimals.

    this.displayString = label + ": " + (int) (sliderValue * sliderMaxValue);

Finally, the slider should look something like this

Alt text

If you so feel like it, you can implement booleans to control whether or not it should display the value at all. You can also try and modify the height and width of the slider so it can become more flexible.

Final code:

package net.minecraft.src;

import net.minecraft.client.Minecraft;
import org.lwjgl.opengl.GL11;

public class GuiSliderFixed extends GuiButton {

    public float sliderValue = 1.0F;
    public float sliderMaxValue = 1.0F;
    public boolean dragging = false;
    public String label;

    public GuiSliderFixed(int id, int x, int y, String label, float startingValue, float maxValue) {
        super(id, x, y, 150, 20, label);
        this.label = label;
        this.sliderValue = startingValue;
        this.sliderMaxValue = maxValue;
    }

    protected int getHoverState(boolean par1) {
        return 0;
    }

    protected void mouseDragged(Minecraft par1Minecraft, int par2, int par3) {
        if (this.drawButton) {
            if (this.dragging) {
                this.sliderValue = (float) (par2 - (this.xPosition + 4)) / (float) (this.width - 8);

                if (this.sliderValue < 0.0F) {
                    this.sliderValue = 0.0F;
                }

                if (this.sliderValue > 1.0F) {
                    this.sliderValue = 1.0F;
                }

            }

            this.displayString = label + ": " + (int) (sliderValue * sliderMaxValue);
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)), this.yPosition, 0, 66, 4, 20);
            this.drawTexturedModalRect(this.xPosition + (int) (this.sliderValue * (float) (this.width - 8)) + 4, this.yPosition, 196, 66, 4, 20);
        }
    }

    public boolean mousePressed(Minecraft par1Minecraft, int par2, int par3) {
        if (super.mousePressed(par1Minecraft, par2, par3)) {
            this.sliderValue = (float) (par2 - (this.xPosition + 4)) / (float) (this.width - 8);

            if (this.sliderValue < 0.0F) {
                this.sliderValue = 0.0F;
            }

            if (this.sliderValue > 1.0F) {
                this.sliderValue = 1.0F;
            }

            this.dragging = true;
            return true;
        } else {
            return false;
        }
    }

    public void mouseReleased(int par1, int par2) {
        this.dragging = false;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment