package game.gui.element; import game.renderer.Drawing; import game.util.ExtMath; import game.util.Formatter; import game.window.Button; public class Slider extends Element { public static interface Callback { void use(Slider elem, int value); } public static interface FloatCallback { void use(Slider elem, float value); } private static final int SLIDER_WIDTH = 10; private final Callback func; private final int def; private final int min; private final int max; private final int precision; private final int handle; private int value; private int position; public Slider(int x, int y, int w, int h, int prec, int min, int max, int def, int init, Callback callback, Formatter formatter) { super(x, y, w, h, formatter); this.handle = ((this.size_y * SLIDER_WIDTH) / 24) & ~1; this.func = callback; this.precision = prec; this.min = min; this.max = max; this.def = def; this.value = init; this.position = gui_slider_pixel(); this.formatText(); } public Slider(int x, int y, int w, int h, int prec, int min, int max, int def, int init, Callback callback, final String text) { this(x, y, w, h, prec, min, max, def, init, callback, new Formatter() { public String use(Slider elem) { return String.format("%s: %d", text, elem.value); } }); } public Slider(int x, int y, int w, int h, int prec, int min, int max, int def, int init, Callback callback, final String text, final String unit) { this(x, y, w, h, prec, min, max, def, init, callback, new Formatter() { private final String format = unit.isEmpty() ? "%s: %d" : "%s: %d %s"; public String use(Slider elem) { return String.format(this.format, text, elem.value, unit); } }); } public Slider(int x, int y, int w, int h, int prec, float min, float max, float def, float init, final FloatCallback callback, Formatter formatter) { this(x, y, w, h, prec, (int)(min * 1000.0f), (int)(max * 1000.0f), (int)(def * 1000.0f), (int)(init * 1000.0f), new Callback() { public void use(Slider elem, int value) { callback.use(elem, (float)value / 1000.0f); } }, formatter); } public Slider(int x, int y, int w, int h, final int prec, float min, float max, float def, float init, FloatCallback callback, final String text, final String unit) { this(x, y, w, h, prec < 0 ? 0 : prec, min, max, def, init, callback, new Formatter() { private final String format = "%s: " + (prec <= 0 ? "%d" : ("%." + prec + "f")) + (unit.isEmpty() ? "" : " %s"); public String use(Slider elem) { return prec <= 0 ? String.format(this.format, text, prec < 0 ? (int)((float)elem.value / 10.0f) : (elem.value / 1000), unit) : String.format(this.format, text, (float)elem.value / 1000.0f, unit); } }); } public void scroll(int scr_x, int scr_y, int x, int y, boolean ctrl, boolean shift) { if(scr_y != 0) { int prev = this.value; this.value += (scr_y < 0 ? -1 : 1) * (ctrl ? (this.precision != 0 ? 1 : 10) : ((this.precision >= 2) ? 10 : (this.precision != 0 ? 100 : 1))) * (shift ? (this.precision != 0 ? 50 : 5) : 1); this.value = ExtMath.clampi(this.value, this.min, this.max); this.position = gui_slider_pixel(); if(this.value != prev) { this.func.use(this, this.value); this.formatText(); } } } public void mouse(Button btn, int x, int y, boolean ctrl, boolean shift) { int prev = this.value; if(ctrl || (btn == Button.MOUSE_MIDDLE)) { this.value = this.def; this.position = gui_slider_pixel(); if(this.value != prev) { this.func.use(this, this.value); this.formatText(); this.playSound(); } } else { this.position = x - this.pos_x; this.value = gui_slider_value(); this.position = gui_slider_pixel(); if(this.value != prev) { this.func.use(this, this.value); this.formatText(); this.playSound(); } } } public void drag(int x, int y) { x = (x < this.pos_x) ? this.pos_x : ((x >= (this.pos_x + this.size_x)) ? (this.pos_x - 1 + this.size_x) : x); int prev = this.value; this.position = x - this.pos_x; this.value = gui_slider_value(); this.value = ExtMath.clampi(this.value, this.min, this.max); this.position = gui_slider_pixel(); if(this.value != prev) { this.func.use(this, this.value); this.formatText(); } } public void reformat() { this.position = gui_slider_pixel(); if(this.visible) this.r_dirty = true; super.reformat(); } private int gui_slider_value() { int r = this.min + (int)(((float)(int)(this.position - (this.handle / 2))) * ((float)(int)(this.max - this.min)) / ((float)(int)(this.size_x + 1 - this.handle))); return ExtMath.clampi(r, this.min, this.max); } private int gui_slider_pixel() { int r = ((int)(float)(((float)(int)(this.value - this.min)) * ((float)(int)(this.size_x + 1 - this.handle)) / ((float)(int)(this.max - this.min)))) + (this.handle / 2); return ExtMath.clampi(r, this.handle / 2, this.size_x - (this.handle / 2)); } public void setValue(int value) { this.value = ExtMath.clampi(value, this.min, this.max); this.position = gui_slider_pixel(); this.formatText(); } public void setFloatValue(float value) { this.setValue((int)(value * 1000.0f)); } public int getValue() { return this.value; } public float getFloatValue() { return (float)this.value / 1000.0f; } protected void drawBackground() { Drawing.drawGradient2Border(this.pos_x, this.pos_y, this.size_x, this.size_y, this.gm.style.fill_btm, this.gm.style.fill_top, this.gm.style.brdr_top, this.gm.style.brdr_btm); Drawing.drawGradient2Border(this.pos_x + this.position - (this.handle / 2), this.pos_y, this.handle, this.size_y, this.gm.style.fill_top, this.gm.style.fill_btm, this.gm.style.brdr_btm, this.gm.style.brdr_top); } }