Skip to content

Commit

Permalink
First implementation try on the border layout.
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed Feb 4, 2015
1 parent 81fb880 commit 8eda347
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 20 deletions.
8 changes: 6 additions & 2 deletions src/main/java/nova/core/gui/GuiComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public abstract class GuiComponent<O extends GuiComponent<O, T>, T extends Nativ
protected String qualifiedName;

private T nativeElement;
private SidedEventListenerList<ComponentEvent> eventListenerList = new SidedEventListenerList<ComponentEvent>(this::dispatchNetworkEvent);
private SidedEventListenerList<ComponentEvent<?>> eventListenerList = new SidedEventListenerList<ComponentEvent<?>>(this::dispatchNetworkEvent);
private EventListenerList<GuiEvent> listenerList = new EventListenerList<GuiEvent>();

protected Optional<Vector2i> preferredSize = Optional.empty();
Expand Down Expand Up @@ -58,6 +58,10 @@ public GuiComponent(String uniqueID) {
this.qualifiedName = uniqueID;
}

public Optional<AbstractGuiContainer<?, ?>> getParentContainer() {
return parentContainer;
}

/**
* @return Outline of this component.
* @see Outline
Expand All @@ -74,7 +78,7 @@ public Outline getOutline() {
* @param outline {@link Outline} to use as outline
*/
@Deprecated
protected void setOutlineNative(Outline outline) {
public void setOutlineNative(Outline outline) {
nativeElement.setOutline(outline);
}

Expand Down
24 changes: 20 additions & 4 deletions src/main/java/nova/core/gui/Outline.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
*/
public class Outline extends Rectangle<Vector2i> {

private Outline(Vector2i min, Vector2i max) {
super(min, max);
}

/**
* Creates a new Outline with the specified position and dimension.
*
Expand All @@ -27,6 +23,10 @@ public Outline(int x, int y, int width, int height) {
super(new Vector2i(x, y), new Vector2i(x + width, y + height));
}

public Outline(Vector2i position, Vector2i dimension) {
super(position, position.add(dimension));
}

public int getWidth() {
return x2i() - x1i();
}
Expand All @@ -42,4 +42,20 @@ public Outline setHeight(int height) {
public Outline setWidth(int width) {
return new Outline(new Vector2i(x1i(), x1i() + width), max);
}

public Vector2i getDimension() {
return new Vector2i(getWidth(), getHeight());
}

public Outline setDimension(Vector2i dimension) {
return new Outline(min, min.add(dimension));
}

public Vector2i getPosition() {
return getMin();
}

public Outline setPosition(Vector2i position) {
return new Outline(position, position.add(getMax()));
}
}
34 changes: 33 additions & 1 deletion src/main/java/nova/core/gui/layout/AbstractGuiLayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import nova.core.gui.AbstractGuiContainer;
import nova.core.gui.GuiComponent;
import nova.core.gui.Outline;
import nova.core.util.transform.Vector2i;

public abstract class AbstractGuiLayout<T extends LayoutConstraints<T>> implements GuiLayout {

Expand Down Expand Up @@ -38,7 +40,37 @@ public final void add(GuiComponent<?, ?> component, AbstractGuiContainer<?, ?> p
addImpl(component, parent, LayoutConstraints.createConstraints(constraintsClass, parameters));
}

protected abstract void addImpl(GuiComponent<?, ?> element, AbstractGuiContainer<?, ?> parent, T constraints);
protected abstract void addImpl(GuiComponent<?, ?> component, AbstractGuiContainer<?, ?> parent, T constraints);

// TODO Document as needed by possible custom layouts.
protected final Vector2i getPreferredSizeOf(GuiComponent<?, ?> component) {
return component != null ? component.getPreferredSize().orElse(component.getMinimumSize().orElse(Vector2i.zero)) : Vector2i.zero;
}

protected final Vector2i getMaximumSizeOf(GuiComponent<?, ?> component) {
return component != null ? component.getPreferredSize().orElse(component.getMaximumSize().orElse(Vector2i.max)) : Vector2i.max;
}

@SuppressWarnings("deprecation")
protected final void setSizeOf(GuiComponent<?, ?> component, Vector2i size) {
if (component != null) {
component.setOutlineNative(component.getOutline().setDimension(size));
}
}

@SuppressWarnings("deprecation")
protected final void setPositionOf(GuiComponent<?, ?> component, Vector2i position) {
if (component != null) {
component.setOutlineNative(component.getOutline().setPosition(position));
}
};

@SuppressWarnings("deprecation")
protected final void setOutlineOf(GuiComponent<?, ?> component, Outline outline) {
if (component != null) {
component.setOutlineNative(outline);
}
}

public abstract T constraints();
}
84 changes: 74 additions & 10 deletions src/main/java/nova/core/gui/layout/BorderLayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

import nova.core.gui.AbstractGuiContainer;
import nova.core.gui.GuiComponent;
import nova.core.gui.Outline;
import nova.core.gui.layout.LayoutConstraints.BorderLayoutConstraints;
import nova.core.util.transform.Vector2i;

/**
* A basic layout that splits the parent's container up into multiple regions.
Expand All @@ -22,11 +24,81 @@ public BorderLayout() {

private final HashMap<BorderLayout.EnumBorderRegion, GuiComponent<?, ?>> components = new HashMap<>();

// TODO HIGHLY untested
@Override
public void revalidate(AbstractGuiContainer<?, ?> parent) {
for (EnumBorderRegion region : components.keySet()) {
Outline outline = parent.getOutline();
Vector2i dimension = outline.getDimension();

GuiComponent<?, ?> cComp = components.get(EnumBorderRegion.CENTER);
GuiComponent<?, ?> wComp = components.get(EnumBorderRegion.WEST);
GuiComponent<?, ?> eComp = components.get(EnumBorderRegion.EAST);
GuiComponent<?, ?> nComp = components.get(EnumBorderRegion.NORTH);
GuiComponent<?, ?> sComp = components.get(EnumBorderRegion.SOUTH);

Vector2i wDim = getPreferredSizeOf(wComp);
Vector2i eDim = getPreferredSizeOf(eComp);
Vector2i nDim = getPreferredSizeOf(nComp);
Vector2i sDim = getPreferredSizeOf(sComp);
Vector2i cDim = Vector2i.zero;

Vector2i overAllocated = Vector2i.zero;
Vector2i space = dimension;

if (cComp != null) {
Vector2i pref = new Vector2i(dimension.x - wDim.x - nDim.x, dimension.y - nDim.y - sDim.y);
cDim = pref.min(getMaximumSizeOf(cComp));
Vector2i cOver = pref.subtract(cDim).divide(2);

if (cOver.x > 0) {
if (wComp != null)
wDim = wDim.add(new Vector2i(cOver.x, 0));
if (eComp != null)
eDim = eDim.add(new Vector2i(cOver.x, 0));
}
if (cOver.y > 0) {
if (nComp != null)
nDim = nDim.add(new Vector2i(0, cOver.y));
if (sComp != null)
sDim = sDim.add(new Vector2i(0, cOver.y));
}

Vector2i v1 = dimension.subtract(cDim);
overAllocated = v1.subtract(wDim).subtract(nDim).subtract(eDim).subtract(sDim).inverse().max(Vector2i.zero);
space = space.subtract(cDim);

} else {
overAllocated = dimension.subtract(wDim).subtract(nDim).subtract(eDim).subtract(sDim).inverse().max(Vector2i.zero);
}

Vector2i v2 = space.divide(2);

if (overAllocated.x > 0) {
Vector2i v3 = wComp != null && eComp != null ? v2 : space;
wDim = new Vector2i(v3.x, eDim.y);
eDim = new Vector2i(v3.x, wDim.y);
}
if (overAllocated.y > 0) {
Vector2i v3 = nComp != null && sComp != null ? v2 : space;
wDim = new Vector2i(eDim.x, v3.y);
eDim = new Vector2i(wDim.x, v3.y);
}

if (cComp != null) {
cDim = cDim.min(dimension.subtract(wDim).subtract(nDim).subtract(eDim).subtract(sDim));
}

// Centers the border components
int wOffset = (int) ((dimension.y + wDim.y) / 2D);
int eOffset = (int) ((dimension.y + eDim.y) / 2D);
int nOffset = (int) ((dimension.x + nDim.x) / 2D);
int sOffset = (int) ((dimension.x + sDim.x) / 2D);

setOutlineOf(cComp, new Outline(new Vector2i(wDim.x, nDim.y), dimension));
setOutlineOf(wComp, new Outline(new Vector2i(0, wOffset), wDim));
setOutlineOf(eComp, new Outline(new Vector2i(dimension.x - wDim.x, eOffset), wDim));
setOutlineOf(nComp, new Outline(new Vector2i(nOffset, 0), eDim));
setOutlineOf(sComp, new Outline(new Vector2i(sOffset, dimension.y - sDim.y), sDim));
}

@Override
Expand All @@ -42,15 +114,7 @@ public void remove(GuiComponent<?, ?> component) {
}

public static enum EnumBorderRegion {
CENTER(2, 2), NORTH(1, 1), EAST(1, 2), SOUTH(1, 1), WEST(1, 2);

public final int priority;
public final int axis;

private EnumBorderRegion(int priority, int axis) {
this.priority = priority;
this.axis = axis;
}
CENTER, NORTH, EAST, SOUTH, WEST;
}

@Override
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/nova/core/util/transform/Vector2i.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package nova.core.util.transform;

/**
* A double implementation of Vector2. Vector2 is an immutable quantity that holds an x, y and z value.
* A double implementation of Vector2. Vector2 is an immutable quantity that
* holds an x, y and z value.
*
* @author Calclavia
*/
@SuppressWarnings("rawtypes")
Expand All @@ -10,6 +12,7 @@ public class Vector2i extends Vector2<Vector2i> {
public static final Vector2i one = new Vector2i(1, 1);
public static final Vector2i xAxis = new Vector2i(1, 0);
public static final Vector2i yAxis = new Vector2i(0, 1);
public static final Vector2i max = new Vector2i(Integer.MAX_VALUE, Integer.MAX_VALUE);

public final int x, y;

Expand Down Expand Up @@ -68,12 +71,12 @@ public int hashCode() {

@Override
public int xi() {
return (int) x;
return x;
}

@Override
public int yi() {
return (int) y;
return y;
}

@Override
Expand Down

0 comments on commit 8eda347

Please sign in to comment.