Container started

This commit is contained in:
2026-08-24 15:50:28 +02:00
parent 4e37253988
commit a3e4739825
5 changed files with 258 additions and 9 deletions
@@ -4,12 +4,15 @@ import speiger.src.coreengine.ui.gui.layout.box.IGuiBox;
import speiger.src.coreengine.ui.gui.layout.constraint.ConstraintContainer; import speiger.src.coreengine.ui.gui.layout.constraint.ConstraintContainer;
public interface IComponentScreen { public interface IComponentScreen {
public IGuiBox getBox(); IGuiBox getBox();
public long clock(); long clock();
public void pushLayer(); void pushLayer();
public void popLayer(); void popLayer();
public GuiComponent addComponent(GuiComponent component, ConstraintContainer constraints);
public boolean hasComponent(GuiComponent component); GuiComponent addComponent(GuiComponent component, ConstraintContainer constraints);
public boolean removeComponent(GuiComponent component); boolean hasComponent(GuiComponent component);
boolean isAtTop(GuiComponent component);
boolean moveToTop(GuiComponent component);
boolean removeComponent(GuiComponent component);
} }
@@ -0,0 +1,21 @@
package speiger.src.coreengine.ui.gui.component.impl;
import speiger.src.coreengine.ui.gui.component.base.GuiComponent;
import speiger.src.coreengine.ui.gui.renderer.IUIRenderer;
public class TestComponent extends GuiComponent {
public TestComponent(float x, float y, float width, float height) {
super(x, y, width, height);
}
@Override
public void init() {
}
@Override
protected void renderComponent(IUIRenderer renderer, int mouseX, int mouseY, float partialTicks) {
renderer.drawRect(getBox(), 0xFF00FFFF);
}
}
@@ -59,12 +59,12 @@ public class UIRenderer implements IUIRenderer {
for(int i = 0,m=draws.size();i<m;i++) { for(int i = 0,m=draws.size();i<m;i++) {
UIDraw draw = draws.get(i); UIDraw draw = draws.get(i);
BufferResult result = draw.result(); BufferResult result = draw.result();
buffer.pipeline(draw.pipeline());
if(draw.drawer != null) { if(draw.drawer != null) {
draw.drawer.setupExtra(buffer); draw.drawer.setupExtra(buffer);
buffer.mesh(mesh); buffer.mesh(mesh);
} }
if(draw.texture() != null) buffer.texture(0, draw.texture()); if(draw.texture() != null) buffer.texture(0, draw.texture());
buffer.pipeline(draw.pipeline());
boolean pop = false; boolean pop = false;
Vec4i scissors = draw.scissors(); Vec4i scissors = draw.scissors();
if(scissors != Vec4i.MINUS_ONE) { if(scissors != Vec4i.MINUS_ONE) {
@@ -0,0 +1,225 @@
package speiger.src.coreengine.ui.gui.screen;
import java.util.Iterator;
import java.util.List;
import speiger.src.collections.ints.sets.IntOpenHashSet;
import speiger.src.collections.ints.sets.IntSet;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.maps.abstracts.AbstractObject2BooleanMap.BasicEntry;
import speiger.src.collections.objects.maps.interfaces.Object2BooleanMap;
import speiger.src.collections.objects.maps.interfaces.Object2BooleanMap.Entry;
import speiger.src.collections.utils.Stack;
import speiger.src.coreengine.platform.input.window.Window;
import speiger.src.coreengine.ui.gui.component.base.GuiComponent;
import speiger.src.coreengine.ui.gui.component.base.IComponentScreen;
import speiger.src.coreengine.ui.gui.interaction.IInteractable;
import speiger.src.coreengine.ui.gui.interaction.IInteractableContainer;
import speiger.src.coreengine.ui.gui.layout.box.IGuiBox;
import speiger.src.coreengine.ui.gui.layout.constraint.ConstraintContainer;
import speiger.src.coreengine.ui.gui.renderer.IUIRenderer;
public class GuiContainer implements IComponentScreen, IInteractableContainer {
LayeredContainer container = new LayeredContainer();
IntSet activeButtons = new IntOpenHashSet();
IInteractable focused;
IGuiBox box = IGuiBox.of(0F, 0F, 0F, 0F);
long tick;
public void setScreen(Window window) {
box = IGuiBox.of(0, 0, window.width(), window.height());
init();
}
public void init() {
}
@Override
public IGuiBox getBox() { return box; }
@Override
public long clock() { return tick; }
@Override
public boolean isFocused() { return focused != null; }
@Override
public void setFocused(boolean value) { if(!value) setFocusedChild(null); }
@Override
public List<? extends IInteractable> getChildren() { return container.interactables(); }
@Override
public void setFocusedChild(IInteractable child) {
if(focused != null) focused.setFocused(false);
this.focused = child;
if(focused != null) focused.setFocused(true);
}
@Override
public IInteractable getFocusedChild() { return focused; }
@Override
public IntSet getActiveButtons() { return activeButtons; }
@Override
public void pushLayer() { container.pushLayer(); }
@Override
public void popLayer() { container.popLayer(); }
@Override
public GuiComponent addComponent(GuiComponent component, ConstraintContainer constraints) {
if(component.screen() != null) throw new IllegalArgumentException("A Child can not have multiple Screens");
container.add(component);
component.withConstraints(constraints);
component.setScreen(this);
component.init();
component.onChanged(true);
return component;
}
@Override
public boolean hasComponent(GuiComponent component) {
return component.screen() == this && container.contains(component);
}
@Override
public boolean isAtTop(GuiComponent component) {
return component.screen() == this && container.children().contains(component);
}
@Override
public boolean moveToTop(GuiComponent component) {
return component.screen() == this && container.moveToTop(component);
}
@Override
public boolean removeComponent(GuiComponent component) {
if(component.screen() == this && container.remove(component)) {
component.close();
component.setScreen(null);
return true;
}
return false;
}
public void render(IUIRenderer renderer, int mouseX, int mouseY, float partialTicks) {
for(Object2BooleanMap.Entry<GuiComponent> entry : container) {
boolean keepMouse = entry.getBooleanValue();
GuiComponent.renderComponent(entry.getKey(), renderer, keepMouse ? mouseX : -1, keepMouse ? mouseY : -1, partialTicks);
}
}
public void tick() {
tick++;
for(Object2BooleanMap.Entry<GuiComponent> entry : container) {
GuiComponent.tickComponent(entry.getKey());
}
}
public static class LayeredContainer implements Iterable<Object2BooleanMap.Entry<GuiComponent>> {
Stack<Layer> layers = new ObjectArrayList<>();
public LayeredContainer() { pushLayer(); }
public void pushLayer() {
layers.push(new Layer());
}
public void popLayer() {
if(layers.size() == 1) return;
layers.pop();
}
public void add(GuiComponent component) {
layers.top().add(component);
}
public boolean moveToTop(GuiComponent component) {
if(layers.top().contains(component)) return true;
for(int i = 1,m=layers.size();i<m;i++) {
Layer layer = layers.peek(i);
if(layer.remove(component)) {
layers.top().add(component);
return true;
}
}
return false;
}
public boolean contains(GuiComponent component) {
for(int i = 0,m=layers.size();i<m;i++) {
if(layers.peek(i).contains(component)) return true;
}
return false;
}
public boolean remove(GuiComponent component) {
for(int i = 0,m=layers.size();i<m;i++) {
if(layers.peek(i).remove(component)) {
clearEmptyLayers();
return true;
}
}
return false;
}
public void clearEmptyLayers() {
while(layers.top().isEmpty() && layers.size() > 0) {
popLayer();
}
}
@Override
public Iterator<Object2BooleanMap.Entry<GuiComponent>> iterator() {
return new Iterator<>() {
BasicEntry<GuiComponent> entry = new BasicEntry<>();
int myLayer = layers.size()-1;
Iterator<GuiComponent> childIterator = layers.peek(myLayer).components.iterator();
@Override
public boolean hasNext() {
return childIterator.hasNext();
}
@Override
public Entry<GuiComponent> next() {
if(!hasNext()) throw new IllegalStateException("Out of Elements to poll");
entry.set(childIterator.next(), myLayer == 0);
if(!childIterator.hasNext() && myLayer > 0) {
childIterator = layers.peek(--myLayer).components.iterator();
}
return entry;
}
};
}
public List<GuiComponent> children() {
return layers.top().components;
}
public List<IInteractable> interactables() {
return layers.top().interactables;
}
}
private static class Layer {
List<GuiComponent> components = new ObjectArrayList<>();
List<IInteractable> interactables = new ObjectArrayList<>();
public void add(GuiComponent component) {
components.add(component);
interactables.add(component.interactContainer());
}
public boolean contains(GuiComponent component) {
return components.contains(component);
}
public boolean remove(GuiComponent component) {
if(components.remove(component)) {
interactables.remove(component.interactContainer());
return true;
}
return false;
}
public boolean isEmpty() {
return components.isEmpty();
}
}
}
@@ -410,7 +410,7 @@ public class GuiScreenBase extends GuiBase
protected Iterator<IButtonComponent> sortByHeight(List<IButtonComponent> comp) protected Iterator<IButtonComponent> sortByHeight(List<IButtonComponent> comp)
{ {
comp.sort(ButtonSorter.SORTER); comp.sort(Comparator.comparingDouble(IButtonComponent::getComponentZ));
return comp.iterator(); return comp.iterator();
} }