364 lines
8.8 KiB
Java
364 lines
8.8 KiB
Java
package speiger.src.coreengine.rendering.gui.components;
|
|
|
|
import java.util.Collection;
|
|
import java.util.function.Consumer;
|
|
|
|
import org.lwjgl.opengl.GL11;
|
|
|
|
import speiger.src.collections.ints.collections.IntCollection;
|
|
import speiger.src.coreengine.math.value.IValue;
|
|
import speiger.src.coreengine.math.value.LiniarValue;
|
|
import speiger.src.coreengine.rendering.gui.GuiComponent;
|
|
import speiger.src.coreengine.rendering.gui.base.IButtonComponent;
|
|
import speiger.src.coreengine.rendering.gui.components.list.SelectionEntry;
|
|
import speiger.src.coreengine.rendering.gui.helper.Align;
|
|
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
|
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain.Target;
|
|
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
|
|
import speiger.src.coreengine.rendering.gui.renderer.UIRenderer;
|
|
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
|
import speiger.src.coreengine.rendering.tesselation.Tesselator;
|
|
import speiger.src.coreengine.rendering.tesselation.VertexType;
|
|
|
|
public class SelectionComponent extends GuiComponent implements IButtonComponent, Consumer<GuiComponent>
|
|
{
|
|
public static final int FLAG_ANIMATE = 1 << 20;
|
|
ListComponent<SelectionEntry> list = new ListComponent<SelectionEntry>().bounds(0F, 120F).setManualRenderer(true).setIgnoreBounds(true).cast();
|
|
TextComponent text = new TextComponent().align(Align.LEFT_TOP, Align.CENTER).setTextScale(0.85F).setManualRenderer(true).cast();
|
|
RenderBuffer buffer;
|
|
int color;
|
|
boolean isOpen = false;
|
|
int selectedIndex = -1;
|
|
int defaultIndex = -1;
|
|
IValue animation = null;
|
|
|
|
public SelectionComponent(int color)
|
|
{
|
|
super(0F, 0F, 0F, 0F);
|
|
this.color = color;
|
|
text.setText("Select Index");
|
|
list.setColor(color);
|
|
}
|
|
|
|
public SelectionComponent(int color, Collection<String> collection)
|
|
{
|
|
super(0F, 0F, 0F, 0F);
|
|
this.color = color;
|
|
text.setText("Select Index");
|
|
list.setColor(color);
|
|
addEntries(collection);
|
|
}
|
|
|
|
public SelectionComponent(float x, float y, float width, float height, int color)
|
|
{
|
|
super(x, y, width, height);
|
|
this.color = color;
|
|
text.setText("Select Index");
|
|
list.setColor(color);
|
|
}
|
|
|
|
public SelectionComponent(float x, float y, float width, float height, int color, Collection<String> collection)
|
|
{
|
|
super(x, y, width, height);
|
|
this.color = color;
|
|
text.setText("Select Index");
|
|
list.setColor(color);
|
|
addEntries(collection);
|
|
}
|
|
|
|
@Override
|
|
public void init()
|
|
{
|
|
list.setEntryHeight(getGui().getFont().height()).addUserActionListener(this);
|
|
addChild(text, Constrains.parent(21F, 0F, 10.5F, 0F));
|
|
addChild(list, Constrains.parent(Target.X).invParent(Target.Y).parent(Target.WIDTH).build());
|
|
addCloseListener(buffer = getRenderer().createBuffer());
|
|
createArrow();
|
|
}
|
|
|
|
public final SelectionComponent setAnimating(boolean value)
|
|
{
|
|
setFlag(FLAG_ANIMATE, value);
|
|
return this;
|
|
}
|
|
|
|
public final boolean isAnimating()
|
|
{
|
|
return isFlagSet(FLAG_ANIMATE);
|
|
}
|
|
|
|
@Override
|
|
protected void updateState()
|
|
{
|
|
list.setVisible(isOpen);
|
|
}
|
|
|
|
public TextComponent getText()
|
|
{
|
|
return text;
|
|
}
|
|
|
|
public ListComponent<SelectionEntry> getList()
|
|
{
|
|
return list;
|
|
}
|
|
|
|
public SelectionComponent addEntry(String s)
|
|
{
|
|
list.add(new SelectionEntry(s));
|
|
return this;
|
|
}
|
|
|
|
public SelectionComponent addEntries(Collection<String> collection)
|
|
{
|
|
for(String s : collection)
|
|
{
|
|
list.add(new SelectionEntry(s));
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public SelectionComponent updateEntry(int index, String newName)
|
|
{
|
|
list.get(index).setText(newName);
|
|
if(index == selectedIndex)
|
|
{
|
|
updateSelection();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public SelectionComponent removeEntry(String s)
|
|
{
|
|
for(int i = 0,m=list.size();i<m;i++)
|
|
{
|
|
if(list.get(i).getText().equals(s))
|
|
{
|
|
list.remove(i);
|
|
if(selectedIndex == i)
|
|
{
|
|
updateSelection();
|
|
}
|
|
return this;
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public SelectionComponent removeIndex(int index)
|
|
{
|
|
if(list.remove(index) != null && selectedIndex == index)
|
|
{
|
|
updateSelection();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public SelectionComponent removeIndexes(IntCollection values)
|
|
{
|
|
if(list.removeAll(values) && values.contains(selectedIndex))
|
|
{
|
|
updateSelection();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public SelectionComponent setDefaultIndex(int index)
|
|
{
|
|
defaultIndex = index;
|
|
if(index != -1 && selectedIndex == -1)
|
|
{
|
|
list.setSelectedIndex(index);
|
|
updateSelection();
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public SelectionComponent setSelectedIndex(int index)
|
|
{
|
|
list.setSelectedIndex(index);
|
|
updateSelection();
|
|
return this;
|
|
}
|
|
|
|
public int getSelectedIndex()
|
|
{
|
|
return selectedIndex;
|
|
}
|
|
|
|
public String getSelectedValue()
|
|
{
|
|
return list.get(selectedIndex).getText();
|
|
}
|
|
|
|
protected void createArrow()
|
|
{
|
|
if(buffer == null)
|
|
{
|
|
return;
|
|
}
|
|
buffer.clear();
|
|
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI).setOffset(-6F, -6F, 0F);
|
|
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
|
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
|
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
|
tes.pos(0F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
|
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
|
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
|
tes.pos(6F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
|
tes.pos(6F, 12F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
|
tes.pos(12F, 6F, 0F).tex(0F, 0F).color4f(color).endVertex();
|
|
tes.setOffset(0F, 0F, 0F);
|
|
buffer.finishShape(0);
|
|
}
|
|
|
|
@Override
|
|
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
|
|
{
|
|
if(animation != null)
|
|
{
|
|
animation.update(particalTicks);
|
|
if(animation.isDone())
|
|
{
|
|
if(animation.get() < 1F)
|
|
{
|
|
isOpen = false;
|
|
list.setVisible(false);
|
|
}
|
|
animation = null;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
|
|
{
|
|
float brightness = getActiveBrightness();
|
|
IGuiBox box = getBox();
|
|
float minX = box.getMinX(10F);
|
|
float minY = box.getMinY(10F);
|
|
float currentZ = getRenderer().getCurrentZ();
|
|
float rotation = animation != null ? animation.get() : (isOpen ? 90 : 0);
|
|
UIRenderer render = getRenderer();
|
|
render.setBrightness(brightness).drawQuad(box, color);
|
|
render.setBrightness(brightness * 0.7F).drawQuad(box.getMinX(), box.getMinY(), box.getMinX(20F), box.getMaxY(), 0.001F, color);
|
|
render.setFastTransform(false).setBrightness(brightness).translate(minX, minY, 0.02F + currentZ);
|
|
render.scale(box.getScale()).rotateZ(rotation).drawBuffers(buffer, 0, 0).resetTransform().setFastTransform(true).translate(0F, 0F, 0.01F).setBrightness(1F);
|
|
text.render(mouseX, mouseY, particalTicks);
|
|
if(animation != null)
|
|
{
|
|
float progress = animation.get() / 90F;
|
|
box = list.getBox();
|
|
enableScissors(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight() * progress);
|
|
list.render(mouseX, mouseY, particalTicks);
|
|
disableScissors();
|
|
}
|
|
else if(isOpen)
|
|
{
|
|
list.render(mouseX, mouseY, particalTicks);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean isComponentColliding(int mouseX, int mouseY)
|
|
{
|
|
return isMouseOver(mouseX, mouseY) || (isOpen && list.isComponentColliding(mouseX, mouseY));
|
|
}
|
|
|
|
@Override
|
|
public boolean isValidButton(int button)
|
|
{
|
|
return button == 0 || button == 2;
|
|
}
|
|
|
|
@Override
|
|
public boolean onClick(int button, int mouseX, int mouseY)
|
|
{
|
|
//TODO look how to move into OnRelease
|
|
if(isOpen && button == 0)
|
|
{
|
|
if(isMouseOver(mouseX, mouseY) && animation == null)
|
|
{
|
|
close();
|
|
}
|
|
return animation == null && list.onClick(button, mouseX, mouseY);
|
|
}
|
|
if(button == 2)
|
|
{
|
|
list.setSelectedIndex(-1);
|
|
updateSelection();
|
|
return true;
|
|
}
|
|
isOpen = true;
|
|
list.setVisible(true);
|
|
if(isAnimating())
|
|
{
|
|
animation = new LiniarValue(2F, 0F, 90F).setSmooth();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onDrag(int mouseX, int mouseY)
|
|
{
|
|
return isOpen && animation == null && list.onDrag(mouseX, mouseY);
|
|
}
|
|
|
|
@Override
|
|
public void onRelease(int button, int mouseX, int mouseY)
|
|
{
|
|
if(isOpen && animation == null)
|
|
{
|
|
list.onRelease(button, mouseX, mouseY);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onScroll(int scroll, int mouseX, int mouseY)
|
|
{
|
|
return isOpen && animation == null && list.onScroll(scroll, mouseX, mouseY);
|
|
}
|
|
|
|
protected void close()
|
|
{
|
|
if(isAnimating())
|
|
{
|
|
animation = new LiniarValue(2F, 90F, 0F).setSmooth();
|
|
}
|
|
else
|
|
{
|
|
isOpen = false;
|
|
list.setVisible(false);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void accept(GuiComponent t)
|
|
{
|
|
updateSelection();
|
|
close();
|
|
}
|
|
|
|
protected void updateSelection()
|
|
{
|
|
if(list.hasSelected())
|
|
{
|
|
selectedIndex = list.getSelectedIndex();
|
|
text.setText(list.get(selectedIndex).getText());
|
|
}
|
|
else if(defaultIndex != -1)
|
|
{
|
|
list.setSelectedIndex(defaultIndex);
|
|
selectedIndex = list.getSelectedIndex();
|
|
text.setText(list.get(selectedIndex).getText());
|
|
}
|
|
else
|
|
{
|
|
selectedIndex = -1;
|
|
text.setText("Select Index");
|
|
}
|
|
}
|
|
}
|