package org.darkstorm.minecraft.gui.component; import java.util.*; import java.awt.Rectangle; import org.darkstorm.minecraft.gui.layout.*; import org.darkstorm.minecraft.gui.theme.Theme; public abstract class AbstractContainer extends AbstractComponent implements Container { private final Map<Component, Constraint[]> children = new LinkedHashMap<Component, Constraint[]>(); private LayoutManager layoutManager = new BasicLayoutManager(); @Override public void render() { super.render(); synchronized(children) { for(Component child : children.keySet()) child.render(); } } public LayoutManager getLayoutManager() { return layoutManager; } public void setLayoutManager(LayoutManager layoutManager) { if(layoutManager == null) layoutManager = new BasicLayoutManager(); this.layoutManager = layoutManager; layoutChildren(); } public Component[] getChildren() { synchronized(children) { return children.keySet().toArray(new Component[children.size()]); } } public void add(Component child, Constraint... constraints) { synchronized(children) { Container parent = child.getParent(); if(parent != null && parent.hasChild(child)) parent.remove(child); children.put(child, constraints); if(!enabled) child.setEnabled(false); if(!visible) child.setVisible(false); child.setParent(this); child.setTheme(getTheme()); layoutChildren(); } } @Override public Constraint[] getConstraints(Component child) { if(child == null) throw new NullPointerException(); synchronized(children) { Constraint[] constraints = children.get(child); return constraints != null ? constraints : new Constraint[0]; } } public Component getChildAt(int x, int y) { synchronized(children) { for(Component child : children.keySet()) if(child.getArea().contains(x, y)) return child; return null; } } public boolean remove(Component child) { synchronized(children) { if(children.remove(child) != null) { layoutChildren(); return true; } else return false; } } public boolean hasChild(Component child) { synchronized(children) { return children.get(child) != null; } } @Override public void setTheme(Theme theme) { super.setTheme(theme); synchronized(children) { for(Component child : children.keySet()) child.setTheme(theme); } } @Override public void layoutChildren() { synchronized(children) { Component[] components = children.keySet().toArray( new Component[children.size()]); Rectangle[] areas = new Rectangle[components.length]; for(int i = 0; i < components.length; i++) areas[i] = components[i].getArea(); Constraint[][] allConstraints = children.values().toArray( new Constraint[children.size()][]); if(getTheme() != null) layoutManager.reposition(ui.getChildRenderArea(this), areas, allConstraints); for(Component child : components) if(child instanceof Container) ((Container) child).layoutChildren(); } } @Override public void onMousePress(int x, int y, int button) { super.onMousePress(x, y, button); synchronized(children) { for(Component child : children.keySet()) { if(!child.isVisible()) continue; if(!child.getArea().contains(x, y)) { for(Rectangle area : child.getTheme() .getUIForComponent(child) .getInteractableRegions(child)) { if(area.contains(x - child.getX(), y - child.getY())) { child.onMousePress(x - child.getX(), y - child.getY(), button); return; } } } } for(Component child : children.keySet()) { if(!child.isVisible()) continue; if(child.getArea().contains(x, y)) { child.onMousePress(x - child.getX(), y - child.getY(), button); return; } } } } @Override public void onMouseRelease(int x, int y, int button) { super.onMouseRelease(x, y, button); synchronized(children) { for(Component child : children.keySet()) { if(!child.isVisible()) continue; if(!child.getArea().contains(x, y)) { for(Rectangle area : child.getTheme() .getUIForComponent(child) .getInteractableRegions(child)) { if(area.contains(x - child.getX(), y - child.getY())) { child.onMouseRelease(x - child.getX(), y - child.getY(), button); return; } } } } for(Component child : children.keySet()) { if(!child.isVisible()) continue; if(child.getArea().contains(x, y)) { child.onMouseRelease(x - child.getX(), y - child.getY(), button); return; } } } } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); enabled = isEnabled(); synchronized(children) { for(Component child : children.keySet()) child.setEnabled(enabled); } } @Override public void setVisible(boolean visible) { super.setVisible(visible); visible = isVisible(); synchronized(children) { for(Component child : children.keySet()) child.setVisible(visible); } } @Override public void update() { for(Component child : getChildren()) child.update(); } }