tcr/java/src/game/gui/element/Dropdown.java
2025-03-19 21:54:09 +01:00

125 lines
3.9 KiB
Java

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<T> 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<T> {
void use(Dropdown<T> elem, T value);
}
private final Callback<T> 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<T> callback, Formatter<Dropdown<T>> 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<T> callback, final String text) {
this(x, y, w, h, up, values, def, init, callback, new Formatter<Dropdown<T>>() {
public String use(Dropdown<T> 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;
}
}