SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/gui/components/menu/MenuComponent.java

319 lines
7.2 KiB
Java

package speiger.src.coreengine.rendering.gui.components.menu;
import java.util.List;
import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.DynamicConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.MenuConstrain;
import speiger.src.coreengine.rendering.gui.helper.constrains.PixelConstrain;
public class MenuComponent extends MenuItemComponent implements Consumer<GuiComponent>
{
static final int FLAG_OPEN = 1 << 21;
static final int FLAG_SUB_MENU = 1 << 22;
List<MenuItemComponent> components = new ObjectArrayList<MenuItemComponent>();
float defaultScale = 1F;
float width = 0F;
float entryHeight = 10F;
float textScale = 1F;
long timeNotHovered = -1;
MenuComponent ownerMenu;
public MenuComponent(String name)
{
super(name);
clearFlag(FLAG_SUPPORT_BINDING);
}
public MenuComponent(float x, float y, float width, float height, String name)
{
super(x, y, width, height, name);
clearFlag(FLAG_SUPPORT_BINDING);
}
@Override
public boolean canMoveIntoForground()
{
return true;
}
public MenuComponent setHeight(float height)
{
entryHeight = height;
return this;
}
protected MenuComponent setParent(MenuComponent owner)
{
ownerMenu = owner;
return this;
}
@Override
protected void setMenuColor(int color)
{
super.setMenuColor(color);
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setMenuColor(color);
}
}
public MenuComponent setDefaultScale(float scale)
{
defaultScale = scale;
return this;
}
@Override
protected void setTextScale(float scale)
{
super.setTextScale(scale);
if(textScale != scale)
{
textScale = scale;
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setTextScale(textScale);
}
}
}
@Override
protected void setBoxWidth(float value)
{
boolean changed = boxWidth != value;
super.setBoxWidth(value);
if(changed)
{
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).onChanged(false);
}
}
}
public MenuComponent addSubMenu(String name)
{
return addMenuItem(new MenuComponent(name+" >").setIsSubMenu(true).setParent(this)).cast();
}
public MenuItemComponent addText(String name)
{
return addMenuItem(new MenuTextComponent(name)).cast();
}
public MenuItemComponent addMenuItem(String name)
{
return addMenuItem(new MenuItemComponent(name));
}
public MenuCheckBoxComponent addCheckBox(String name)
{
return addMenuItem(new MenuCheckBoxComponent(name)).cast();
}
public MenuCheckBoxComponent addCheckBox(String name, boolean value)
{
return addMenuItem(new MenuCheckBoxComponent(name, value)).cast();
}
public MenuItemComponent addMenuItem(MenuItemComponent comp)
{
components.add(comp);
comp.setScale(defaultScale);
comp.setMenuColor(color);
addChild(comp.setIgnoreBounds(true).addUserActionListener(this), createConstrains(comp)).onChanged(false);
comp.setVisible(isFlagSet(FLAG_OPEN));
comp.setTextScale(textScale);
return comp;
}
protected Constrains createConstrains(MenuItemComponent comp)
{
Constrain constraint = isFlagSet(FLAG_SUB_MENU) ? new DynamicConstrain(() -> Math.max(getBox().getBaseWidth(), boxWidth / getBox().getScale())) : new PixelConstrain();
return new Constrains(constraint, new MenuConstrain<MenuItemComponent>(components, isFlagSet(FLAG_SUB_MENU) ? MenuConstrain.DEFAULT : () -> getBox().getBaseHeight() + 0.1F).setPadding(0.01F), comp.createWidthConstriain(), new PixelConstrain(entryHeight));
}
@Override
public GuiComponent removeChild(GuiComponent comp)
{
super.removeChild(comp);
if(components.remove(comp))
{
onChanged(false);
}
return this;
}
@Override
public GuiComponent removeChildren()
{
components.clear();
return super.removeChildren();
}
public void removeElements()
{
for(MenuItemComponent comp : components)
{
super.removeChild(comp);
}
components.clear();
}
@Override
protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
{
if(isSubMenu() && isVisible())
{
if(isFlagSet(FLAG_OPEN))
{
if(isMouseOver(mouseX, mouseY) || isOverChild(mouseX, mouseY))
{
timeNotHovered = -1;
return true;
}
if(timeNotHovered == -1)
{
timeNotHovered = getGlobalClock();
}
if(getGlobalClock() - timeNotHovered > 10)
{
setOpen(false);
}
return true;
}
timeNotHovered = -1;
if(isMouseOver(mouseX, mouseY) && !ownerMenu.hasOtherMenuOpen(this))
{
setOpen(true);
}
}
return true;
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float brigthness = isFlagSet(FLAG_OPEN) ? 0.7F : getBrightness(mouseX, mouseY);
float minX = getBox().getMinX(0.2F);
float minY = getBox().getMinY(0.2F);
float maxX = Math.max(getBox().getMaxX(), minX + boxWidth);
float maxY = getBox().getMaxY(-0.2F);
getRenderer().setBrightness(brigthness).drawQuad(minX, minY, maxX, maxY, color).setBrightness(brigthness * 0.5F).drawFrame(minX, minY, maxX, maxY, color);
text.setBrightness(brigthness);
return true;
}
@Override
public boolean onClick(int button, int mouseX, int mouseY)
{
if(!isSubMenu())
{
setOpen(!isFlagSet(FLAG_OPEN)).notifyListeners(LISTENER_USER_ACTION);
}
return true;
}
protected MenuComponent setIsSubMenu(boolean value)
{
if(setFlag(FLAG_SUB_MENU, value))
{
setFlag(FLAG_KEEP_MENU_OPEN, value);
for(int i = 0,m=components.size();i<m;i++)
{
MenuItemComponent comp = components.get(i);
addConstrains(comp, createConstrains(comp));
}
}
return this;
}
public boolean isSubMenu()
{
return isFlagSet(FLAG_SUB_MENU);
}
public MenuComponent setOpen(boolean open)
{
if(setFlag(FLAG_OPEN, open))
{
width = 0F;
for(int i = 0,m=components.size();i<m;i++)
{
GuiComponent comp = components.get(i);
comp.setVisible(open);
width = Math.max(width, comp.getBox().getBaseWidth());
}
width *= getBox().getScale();
width += 1F;
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setBoxWidth(width);
}
onChanged(false);
}
return this;
}
protected boolean hasOtherMenuOpen(MenuComponent other)
{
for(int i = 0,m=components.size();i<m;i++)
{
MenuItemComponent comp = components.get(i);
if(comp != other && comp instanceof MenuComponent && comp.isFlagSet(FLAG_OPEN))
{
return true;
}
}
return false;
}
@Override
protected void updateState()
{
if(isFlagSet(FLAG_OPEN) != isVisible())
{
boolean isOpen = isFlagSet(FLAG_OPEN);
for(int i = 0,m=components.size();i<m;i++)
{
components.get(i).setVisible(isOpen);
}
}
}
@Override
public void onFocusLost()
{
if(!isChildFocused())
{
setOpen(false);
}
}
@Override
public void accept(GuiComponent t)
{
if(t.cast(MenuItemComponent.class).isNotClosingMenu())
{
return;
}
setOpen(false);
if(ownerMenu != null)
{
ownerMenu.accept(t);
}
}
@Override
public String toString()
{
return "Menu: "+getText().getText();
}
}