package game.gui.element; import game.gui.Font; import game.renderer.Drawing; import game.util.Displayable; import game.util.ExtMath; import game.util.Formatter; import game.util.Util; import game.window.Button; public class Dropdown extends Element { public class Handle extends Element { private Handle(boolean up) { super(Dropdown.this.pos_x, Dropdown.this.pos_y + (up ? -(Font.YGLYPH * Dropdown.this.values.length + 2) : Dropdown.this.size_y), Dropdown.this.size_x, Font.YGLYPH * Dropdown.this.values.length + 2, null); StringBuilder sb = new StringBuilder(); for(T value : Dropdown.this.values) { if(sb.length() > 0) sb.append('\n'); sb.append(value instanceof Displayable ? ((Displayable)value).getDisplay() : value.toString()); } this.setText(sb.toString()); this.visible = this.r_dirty = false; } public void updateText() { } // protected boolean isTextCenteredX() { // return false; // } // // protected boolean isTextCenteredY() { // return false; // } public boolean canClick() { return false; } public void deselect() { this.visible = false; this.r_dirty = true; } public void mouse(Button btn, int x, int y, boolean ctrl, boolean shift) { Dropdown drop = Dropdown.this; int prev = drop.value; drop.value = (y - (this.pos_y + this.margin_y1)) * drop.values.length / (this.size_y - (this.margin_y1 + this.margin_y2)); drop.value = ExtMath.clampi(drop.value, 0, drop.values.length - 1); if(drop.value != prev) { drop.func.use(drop, drop.getValue()); drop.formatText(); this.playSound(); } this.visible = false; this.r_dirty = true; } public void drawHover() { int m = ((this.gm.mouse_y - (this.pos_y + this.margin_y1)) * Dropdown.this.values.length / (this.size_y - (this.margin_y1 + this.margin_y2))); // if((sys.mouse_y - this.pos_y) < (this.size_y - this.margin_y2)) Drawing.drawRect(this.pos_x + this.margin_x1, this.pos_y + this.margin_y1 + ExtMath.clampi(m, 0, Dropdown.this.values.length - 1) * ((this.size_y - (this.margin_y1 + this.margin_y2)) / Dropdown.this.values.length), this.size_x - (this.margin_x1 + this.margin_x2), (this.size_y - (this.margin_y1 + this.margin_y2)) / Dropdown.this.values.length, this.gm.style.hover); } } public static interface Callback { void use(Dropdown elem, T value); } private final Callback func; private final T[] values; private final Handle handle; private final int def; private int value; public Dropdown(int x, int y, int w, int h, boolean up, T[] values, T def, T init, Callback callback, Formatter> formatter) { super(x, y, w, h, formatter); this.func = callback; this.values = values; this.def = Util.indexOfChecked(this.values, def); this.value = Util.indexOfChecked(this.values, init); this.handle = new Handle(up); this.formatText(); } public Dropdown(int x, int y, int w, int h, boolean up, T[] values, T def, T init, Callback callback, final String text) { this(x, y, w, h, up, values, def, init, callback, new Formatter>() { public String use(Dropdown elem) { T value = elem.getValue(); return String.format("%s: %s", text, value instanceof Displayable ? ((Displayable)value).getDisplay() : value.toString()); } }); } public T getValue() { return this.values[this.value]; } public void setValue(T value) { this.value = Util.indexOfChecked(this.values, value); } public void mouse(Button btn, int x, int y, boolean ctrl, boolean shift) { int prev = this.value; if(ctrl || (btn == Button.MOUSE_MIDDLE)) { if((this.value = this.def) != prev) { this.func.use(this, this.getValue()); this.formatText(); this.playSound(); } } else if(this.gui != null) { Handle drop = this.handle; drop.visible = true; drop.r_dirty = true; this.gui.selected = drop; this.playSound(); } } public Handle getHandle() { return this.handle; } }