Renderer/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java
austin 63feb835cd
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
slider fixes, dragevent fixes, new component
2024-09-15 22:49:28 -04:00

396 lines
12 KiB
Java

package electrosphere.renderer.ui.elements;
import java.util.LinkedList;
import java.util.List;
import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.ui.elementtypes.ContainerElement;
import electrosphere.renderer.ui.elementtypes.DrawableElement;
import electrosphere.renderer.ui.elementtypes.Element;
/**
* An element that contains other elements
*/
public class StandardContainerElement extends StandardElement implements ContainerElement {
List<Element> childList = new LinkedList<Element>();
public StandardContainerElement(){
super();
}
@Override
public int getWidth() {
if(width == -1){
if(childList.size() > 0){
int minX = -1;
int maxX = -1;
for(Element child : childList){
if(minX == -1){
minX = child.getRelativeX();
} else if(child.getRelativeX() < minX){
minX = child.getRelativeX();
}
if(maxX == -1){
maxX = child.getRelativeX() + child.getWidth();
} else if(child.getRelativeX() + child.getWidth() > maxX){
maxX = child.getRelativeX() + child.getWidth();
}
}
if(minX == -1){
minX = 0;
}
if(maxX == -1){
maxX = 0;
}
return maxX - minX;
} else {
return 1;
}
} else {
return width;
}
}
@Override
public int getHeight() {
if(height == -1){
if(childList.size() > 0){
int minY = -1;
int maxY = -1;
for(Element child : childList){
if(minY == -1){
minY = child.getRelativeY();
} else if(child.getRelativeY() < minY){
minY = child.getRelativeY();
}
if(maxY == -1){
maxY = child.getRelativeY() + child.getHeight();
} else if(child.getRelativeY() + child.getHeight() > maxY){
maxY = child.getRelativeY() + child.getHeight();
}
}
if(minY == -1){
minY = 0;
}
if(maxY == -1){
maxY = 0;
}
return maxY - minY;
} else {
return 1;
}
} else {
return height;
}
}
@Override
public int getRelativeX() {
if(internalPositionX == -1){
if(childList.size() > 0){
int minX = -1;
for(Element child : childList){
if(minX == -1){
minX = child.getRelativeX();
} else if(child.getRelativeX() < minX){
minX = child.getRelativeX();
}
}
if(minX == -1){
minX = 0;
}
return minX;
} else {
return internalPositionX;
}
} else {
return internalPositionX;
}
}
@Override
public int getRelativeY() {
if(internalPositionY == -1){
if(childList.size() > 0){
int minY = -1;
for(Element child : childList){
if(minY == -1){
minY = child.getRelativeY();
} else if(child.getRelativeY() < minY){
minY = child.getRelativeY();
}
}
if(minY == -1){
minY = 0;
}
return minY;
} else {
return internalPositionY;
}
} else {
return internalPositionY;
}
}
@Override
public void setPositionX(int posX) {
internalPositionX = posX;
absoluteX = posX;
}
@Override
public void setPositionY(int posY) {
internalPositionY = posY;
absoluteY = posY;
}
@Override
public void setDirection(int layout) {
Yoga.YGNodeStyleSetDirection(yogaNode, layout);
}
@Override
public void setFlexDirection(YogaFlexDirection layout){
int directionInteger = Yoga.YGFlexDirectionColumn;
switch(layout){
case Column:
directionInteger = Yoga.YGFlexDirectionColumn;
break;
case Column_Reverse:
directionInteger = Yoga.YGFlexDirectionColumnReverse;
break;
case Row:
directionInteger = Yoga.YGFlexDirectionRow;
break;
case Row_Reverse:
directionInteger = Yoga.YGFlexDirectionRowReverse;
break;
}
Yoga.YGNodeStyleSetFlexDirection(yogaNode, directionInteger);
}
@Override
public void addChild(Element child) {
childList.add(child);
child.setParent(this);
if(child instanceof DrawableElement){
DrawableElement drawableChild = (DrawableElement) child;
drawableChild.setParentWidth(width);
drawableChild.setParentHeight(height);
drawableChild.setVisible(true);
Yoga.YGNodeInsertChild(yogaNode, drawableChild.getYogaNode(), childList.size() - 1);
}
}
@Override
public List<Element> getChildren() {
return childList;
}
@Override
public void removeChild(Element child) {
childList.remove(child);
child.setParent(null);
Yoga.YGNodeRemoveChild(this.yogaNode, child.getYogaNode());
}
@Override
public void clearChildren(){
Yoga.YGNodeRemoveAllChildren(yogaNode);
childList.clear();
}
@Override
public int getChildOffsetX(){
return 0;
}
@Override
public int getChildOffsetY(){
return 0;
}
@Override
public float getChildScaleX(){
return 1;
}
@Override
public float getChildScaleY(){
return 1;
}
@Override
public void destroy(){
for(Element child : childList){
Globals.signalSystem.post(SignalType.YOGA_DESTROY, child);
}
if(this.yogaNode != Element.NULL_YOGA_ELEMENT){
Yoga.YGNodeFree(this.yogaNode);
this.yogaNode = Element.NULL_YOGA_ELEMENT;
}
}
@Override
public void applyYoga(int parentX, int parentY) {
if(this.yogaNode != Element.NULL_YOGA_ELEMENT){
//get the values from yoga
float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode);
float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode);
float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode);
if(!Float.isFinite(widthRaw)){
widthRaw = 0;
}
float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode);
if(!Float.isFinite(heightRaw)){
heightRaw = 0;
}
LoggerInterface.loggerUI.DEBUG("" + this);
LoggerInterface.loggerUI.DEBUG("pos(" + leftRaw + "," + topRaw + ") dim(" + widthRaw + "," + heightRaw + ")");
//apply the values to this component
if(!useAbsolutePosition){
this.internalPositionX = (int)leftRaw;
this.internalPositionY = (int)topRaw;
this.internalWidth = (int)widthRaw;
this.internalHeight = (int)heightRaw;
//calculate absolute values
this.absoluteX = parentX + internalPositionX;
this.absoluteY = parentY + internalPositionY;
}
//apply yoga values to all children
for(Element child : this.getChildren()){
child.applyYoga(parentX + internalPositionX,parentY + internalPositionY);
}
}
}
@Override
public void setJustifyContent(YogaJustification justification){
int justificationInteger = Yoga.YGJustifyFlexStart;
switch(justification){
case Center:
justificationInteger = Yoga.YGJustifyCenter;
break;
case Start:
justificationInteger = Yoga.YGJustifyFlexStart;
break;
case End:
justificationInteger = Yoga.YGJustifyFlexEnd;
break;
case Around:
justificationInteger = Yoga.YGJustifySpaceAround;
break;
case Between:
justificationInteger = Yoga.YGJustifySpaceBetween;
break;
case Evenly:
justificationInteger = Yoga.YGJustifySpaceEvenly;
break;
}
Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justificationInteger);
}
@Override
public void setAlignItems(YogaAlignment alignment){
int alignmentInteger = Yoga.YGAlignAuto;
switch(alignment){
case Auto:
alignmentInteger = Yoga.YGAlignAuto;
break;
case Start:
alignmentInteger = Yoga.YGAlignFlexStart;
break;
case End:
alignmentInteger = Yoga.YGAlignFlexEnd;
break;
case Around:
alignmentInteger = Yoga.YGAlignSpaceAround;
break;
case Between:
alignmentInteger = Yoga.YGAlignSpaceBetween;
break;
case Stretch:
alignmentInteger = Yoga.YGAlignStretch;
break;
case Baseline:
alignmentInteger = Yoga.YGAlignBaseline;
break;
case Center:
alignmentInteger = Yoga.YGAlignCenter;
break;
}
Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignmentInteger);
}
@Override
public void setAlignContent(YogaAlignment alignment){
int alignmentInteger = Yoga.YGAlignAuto;
switch(alignment){
case Auto:
alignmentInteger = Yoga.YGAlignAuto;
break;
case Start:
alignmentInteger = Yoga.YGAlignFlexStart;
break;
case End:
alignmentInteger = Yoga.YGAlignFlexEnd;
break;
case Around:
alignmentInteger = Yoga.YGAlignSpaceAround;
break;
case Between:
alignmentInteger = Yoga.YGAlignSpaceBetween;
break;
case Stretch:
alignmentInteger = Yoga.YGAlignStretch;
break;
case Baseline:
alignmentInteger = Yoga.YGAlignBaseline;
break;
case Center:
alignmentInteger = Yoga.YGAlignCenter;
break;
}
Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignmentInteger);
}
@Override
public void setWrap(YogaWrap wrap) {
switch(wrap){
case WRAP:
Yoga.YGNodeStyleSetFlexWrap(yogaNode, Yoga.YGWrapWrap);
break;
case NO_WRAP:
Yoga.YGNodeStyleSetFlexWrap(yogaNode, Yoga.YGWrapNoWrap);
break;
case REVERSE:
Yoga.YGNodeStyleSetFlexWrap(yogaNode, Yoga.YGWrapReverse);
break;
}
}
@Override
public void setOverflow(YogaOverflow overflow){
switch(overflow){
case Visible:
Yoga.YGNodeStyleSetOverflow(yogaNode, Yoga.YGOverflowVisible);
break;
case Hidden:
Yoga.YGNodeStyleSetOverflow(yogaNode, Yoga.YGOverflowHidden);
break;
case Scroll:
Yoga.YGNodeStyleSetOverflow(yogaNode, Yoga.YGOverflowScroll);
break;
}
}
}