SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/gui/components/SelectionComponent.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");
}
}
}