SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/newGui/components/base/GuiComponent.java

189 lines
5.4 KiB
Java

package speiger.src.coreengine.rendering.newGui.components.base;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.newGui.renderer.IUIRenderer;
import speiger.src.coreengine.utils.collections.CollectionUtils;
import speiger.src.coreengine.utils.collections.FlagObject;
import speiger.src.coreengine.utils.misc.ICastable;
public non-sealed class GuiComponent extends FlagObject implements ICastable, ILayoutComponent, IListableComponent {
private static final int FLAG_FOCUSED = 1<<0;
private static final int FLAG_ENABLED = 1<<1;
private static final int FLAG_VISIBLE = 1<<2;
private static final int FLAG_MANUAL_MANAGED = 1<<3;
private static final int FLAG_SCISSORED = 1<<4;
IGuiBox box;
GuiComponent parent;
List<GuiComponent> children = new ObjectArrayList<>();
InteractionContainer interactions = new InteractionContainer(this::isInteractable);
List<Consumer<GuiComponent>>[] listeners = CollectionUtils.createList(IListableComponent.MAX_LISTENER_TYPES);
IComponentRenderer<GuiComponent> renderer;
public GuiComponent(float x, float y, float width, float height) {
this(IGuiBox.of(x, y, width, height));
}
public GuiComponent(IGuiBox box) {
this.box = box;
if(this instanceof IInteractable actor) {
interactions.add(actor);
}
}
@Override
public void calculateBounds(ILayoutScanner output) {
output.accept(getBox());
for(GuiComponent child : children) {
if(child.isVisible() || output.acceptsInvisble()) {
child.calculateBounds(output);
}
}
}
public void updateComponent() {
children.forEach(GuiComponent::updateComponent);
}
protected void renderComponent(IUIRenderer renderer, int mouseX, int mouseY, float particalTicks) {
renderChildren(renderer, mouseX, mouseY, particalTicks);
}
protected void renderChildren(IUIRenderer renderer, int mouseX, int mouseY, float particalTicks) {
for(GuiComponent child : children) {
renderComponent(child, renderer, mouseX, mouseY, particalTicks);
}
}
public static boolean renderComponent(GuiComponent comp, IUIRenderer renderer, int mouseX, int mouseY, float particalTicks) {
if(!comp.isVisible() || comp.isManualManaged() || (comp.isScissored() && !renderer.isInScissors(comp.getBox()))) return false;
if(comp.isScissored()) {
renderer.pushScissors(comp.getBox());
if(comp.renderer != null) {
comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, particalTicks);
comp.renderChildren(renderer, mouseX, mouseY, particalTicks);
}
else comp.renderComponent(renderer, mouseX, mouseY, particalTicks);
renderer.popScissors();
}
else if(comp.renderer != null) {
comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, particalTicks);
comp.renderChildren(renderer, mouseX, mouseY, particalTicks);
}
else comp.renderComponent(renderer, mouseX, mouseY, particalTicks);
return true;
}
@Override
public GuiComponent addListener(Consumer<GuiComponent> listener, int index) {
listeners[index].add(listener);
return this;
}
@Override
public GuiComponent removeListener(Consumer<GuiComponent> listener, int index) {
listeners[index].remove(listener);
return this;
}
@Override
public void notifyListeners(int index) {
if(listeners[index].isEmpty()) return;
for(Consumer<GuiComponent> comp : listeners[index]) {
comp.accept(this);
}
}
@Override
public IGuiBox getBox() {
return box;
}
@Override
public GuiComponent set(float x, float y) {
if(box.getBaseX() != x || box.getBaseY() != y) {
box.setXY(x, y);
//TODO implement onChanged
}
return this;
}
@Override
public GuiComponent bounds(float width, float height) {
if(box.getBaseWidth() != width || box.getBaseHeight() != height) {
box.setBounds(width, height);
//TODO implement onChanged
}
return this;
}
@Override
public GuiComponent resize(float width, float height) {
if(width != 0F || height != 0F) {
box.grow(width, height);
//TODO implement onChanged
}
return this;
}
@Override
public GuiComponent move(float moveX, float moveY) {
if(moveX != 0F || moveY != 0F) {
box.move(moveX, moveY);
//TODO implement onChanged
}
return this;
}
private final boolean isInteractable() {
return isFlagSet(FLAG_ENABLED | FLAG_VISIBLE);
}
public final boolean isFocused() {
return isFlagSet(FLAG_FOCUSED);
}
public final boolean isEnabled() {
return isFlagSet(FLAG_ENABLED);
}
public final boolean isVisible() {
return isFlagSet(FLAG_VISIBLE);
}
public final boolean isManualManaged() {
return isFlagSet(FLAG_MANUAL_MANAGED);
}
public final boolean isScissored() {
return isFlagSet(FLAG_SCISSORED);
}
public final void setFocused(boolean value) {
setFlag(FLAG_FOCUSED, value);
}
public final GuiComponent setEnabled(boolean value) {
setFlag(FLAG_ENABLED, value);
return this;
}
public final GuiComponent setVisible(boolean value) {
setFlag(FLAG_VISIBLE, value);
return this;
}
public final GuiComponent setManualManaged(boolean value) {
setFlag(FLAG_MANUAL_MANAGED, value);
return this;
}
public final GuiComponent setScissored(boolean value) {
setFlag(FLAG_SCISSORED, value);
return this;
}
}