319 lines
7.2 KiB
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();
|
|
}
|
|
}
|