Skip to content

Instantly share code, notes, and snippets.

@davidB
Created May 21, 2014 10:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidB/b7565de511ae7d2f6edf to your computer and use it in GitHub Desktop.
Save davidB/b7565de511ae7d2f6edf to your computer and use it in GitHub Desktop.
/// License [CC0](http://creativecommons.org/publicdomain/zero/1.0/)
package tonegod.ext;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.Savable;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector4f;
import com.jme3.scene.Node;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.ComponentWrapper;
import net.miginfocom.layout.ConstraintParser;
import net.miginfocom.layout.ContainerWrapper;
import net.miginfocom.layout.Grid;
import net.miginfocom.layout.LC;
import net.miginfocom.layout.LayoutUtil;
import static tonegod.ext.LayoutMig.findDimensionMin;
import tonegod.gui.controls.text.Label;
import tonegod.gui.core.Element;
import tonegod.gui.core.Screen;
/**
* A try to use <a href="www.migcalendar.com/miglayout/">MigLayout</a> with tonegodgui.
*
* MigLayout is a powerfull layout lib that allow to layout like a Border, Flow, Grid, ...
*
* <pre><code>
* LayoutMig container = LayoutMig.newContainer(screen);
* container.setConstraints("", "push[]push", "push[]push");
* for (int i = 0; i < 5; i++) {
* Label l = new Label(screen, Vector2f.ZERO, Vector2f.ZERO);
* l.setText("label_" + i);
* //l.setColorMap(null);
* //l.setTextAlign(BitmapFont.Align.Center);
* container.add(l, "cell 0 0, flowy").setPreferredDimensions(findDimensionMin(l));
* }
* container.layout();
* screen.addElement(container.element);
* </code></pre>
*
* @author David Bernard
*/
public class LayoutMig implements ContainerWrapper, Savable {
////////////////////////////////////////////////////////////////////////////
// CLASS
////////////////////////////////////////////////////////////////////////////
public static int pixelUnitFactor = 1;
public static int horizontalScreenDPI = 72;
public static int verticalScreenDPI = 72;
public static int[] visualPadding = new int[]{0, 0, 0, 0};
public static String udKey = "LayoutMig";
// basic way to compute dimension (ignore orientation, ignore variable)
public static Vector2f findDimensionMin(Label label) {
float size = label.getFontSize();
return new Vector2f(size * label.getText().length(), size);
}
public static LayoutMig newContainer(Screen screen) {
return new LayoutMig(new Element(screen, UUID.randomUUID().toString(), new Vector2f(0, 0), new Vector2f(screen.getWidth(), screen.getHeight()), Vector4f.ZERO, null));
}
////////////////////////////////////////////////////////////////////////////
// OBJECT
////////////////////////////////////////////////////////////////////////////
public final Element element;
public int minimumWidth = 0;
public int minimumHeight = 0;
public int preferredWidth = 0;
public int preferredHeight = 0;
public int maximumWidth = LayoutUtil.INF;
public int maximumHeight = LayoutUtil.INF;
private transient final Map<ComponentWrapper, CC> ccMap = new LinkedHashMap<ComponentWrapper, CC>(8);
private transient LC lc = null;
private transient AC colSpecs = null, rowSpecs = null;
protected boolean needLayout = false;
public LayoutMig(Element e0) {
element = e0;
e0.setUserData(LayoutMig.udKey, this);
setConstraints("", "", "");
}
//-- Mig
@Override
public ComponentWrapper[] getComponents() {
Collection<ComponentWrapper> keys = ccMap.keySet();
return keys.toArray(new ComponentWrapper[keys.size()]);
}
@Override
public int getComponentCount() {
return ccMap.size();
}
@Override
public Object getLayout() {
return this;
}
@Override
public boolean isLeftToRight() {
return true;
}
@Override
public void paintDebugCell(int i, int i1, int i2, int i3) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Object getComponent() {
return element;
}
@Override
public int getX() {
return (int) element.getX();
}
@Override
public int getY() {
return (int) element.getY();
}
@Override
public int getWidth() {
return (int) element.getWidth();
}
@Override
public int getHeight() {
return (int) element.getHeight();
}
@Override
public int getScreenLocationX() {
return (int) element.getAbsoluteX();
}
@Override
public int getScreenLocationY() {
return (int) element.getAbsoluteY();
}
@Override
public int getMinimumWidth(int i) {
return minimumWidth;
}
@Override
public int getMinimumHeight(int i) {
return minimumHeight;
}
@Override
public int getPreferredWidth(int i) {
return preferredWidth;
}
@Override
public int getPreferredHeight(int i) {
return preferredHeight;
}
@Override
public int getMaximumWidth(int i) {
return maximumWidth;
}
@Override
public int getMaximumHeight(int i) {
return maximumHeight;
}
@Override
public void setBounds(int x, int y, int w, int h) {
element.setPosition(x, y);
element.setDimensions(w, h);
System.out.println("pos : " + element.getPosition() + " // dim : " + element.getDimensions());
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean isVisible() {
return element.getIsVisible();
}
public int getBaseline(int i, int i1) {
return -1;
}
public boolean hasBaseline() {
return false;
}
public ContainerWrapper getParent() {
Node p = element.getParent();
return (p == null) ? null : (ContainerWrapper) p.getUserData(LayoutMig.udKey);
}
public float getPixelUnitFactor(boolean bln) {
return pixelUnitFactor;
}
public int getHorizontalScreenDPI() {
return horizontalScreenDPI;
}
public int getVerticalScreenDPI() {
return verticalScreenDPI;
}
public int getScreenWidth() {
return (int) element.getScreen().getWidth();
}
public int getScreenHeight() {
return (int) element.getScreen().getHeight();
}
public String getLinkId() {
throw new UnsupportedOperationException("Not supported yet.");
}
public int getLayoutHashCode() {
throw new UnsupportedOperationException("Not supported yet.");
}
public int[] getVisualPadding() {
return visualPadding;
}
public void paintDebugOutline() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public int getComponetType(boolean bln) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
//-- Savable (TODO)
public void write(JmeExporter ex) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void read(JmeImporter im) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
//--
public final void setConstraints(String layoutConstr, String colConstr, String rowConstr) {
setLayoutConstraints(layoutConstr);
setColumnConstraints(colConstr);
setRowConstraints(rowConstr);
}
/**
* Sets the layout constraints for the layout manager instance as a String.
* <p>
* See the class JavaDocs for information on how this string is formatted.
*
* @param constr The layout constraints as a String representation. <code>null</code> is converted * * * * * * * *
* to <code>""</code> for storage.
* @throws RuntimeException if the constraint was not valid.
*/
public final void setLayoutConstraints(String constr) {
constr = ConstraintParser.prepare((String) constr);
lc = ConstraintParser.parseLayoutConstraint((String) constr);
needLayout = true;
}
/**
* Sets the column layout constraints for the layout manager instance as a String.
* <p>
* See the class JavaDocs for information on how this string is formatted.
*
* @param constr The column layout constraints as a String representation. <code>null</code> is converted * * * * *
* to <code>""</code> for storage.
* @throws RuntimeException if the constraint was not valid.
*/
public final void setColumnConstraints(String constr) {
constr = ConstraintParser.prepare((String) constr);
colSpecs = ConstraintParser.parseColumnConstraints((String) constr);
needLayout = true;
}
/**
* Sets the row layout constraints for the layout manager instance as a String.
* <p>
* See the class JavaDocs for information on how this string is formatted.
*
* @param constr The row layout constraints as a String representation. <code>null</code> is converted * * * * * *
* to <code>""</code> for storage.
* @throws RuntimeException if the constraint was not valid.
*/
public final void setRowConstraints(String constr) {
constr = ConstraintParser.prepare((String) constr);
rowSpecs = ConstraintParser.parseRowConstraints((String) constr);
needLayout = true;
}
public LayoutMig add(Element child, String constr) {
LayoutMig cw = child.getUserData(LayoutMig.udKey);
if (cw == null) {
cw = new LayoutMig(child);
}
String cStr = ConstraintParser.prepare(constr);
ccMap.put(cw, ConstraintParser.parseComponentConstraint(cStr));
element.addChild(child, false); // failed to process hidden elements
needLayout = true;
return cw;
}
public boolean layout() {
Grid grid = new Grid(this, lc, rowSpecs, colSpecs, ccMap, null);
int[] b = new int[]{
10,
0,
this.getWidth(),
this.getHeight()
};
needLayout = grid.layout(b, lc.getAlignX(), lc.getAlignY(), false, false);
System.out.println("layout... : " + element.getUID() + " .. " + needLayout);
return needLayout;
}
public void layoutIfNeeded(float tpf) {
if (needLayout) {
if (element instanceof Label) {
Vector2f dim = findDimensionMin((Label) element);
minimumHeight = (int) dim.y;
minimumWidth = (int) dim.x;
}
layout();
// need to notify parent, because controlUpdate is called parent first and Layout need child first
LayoutMig p = (LayoutMig) getParent();
if (p != null) {
p.needLayout = true;
}
}
}
public void setPreferredDimensions(Vector2f dim) {
preferredWidth = (int) Math.ceil(dim.x);
preferredHeight = (int) Math.ceil(dim.y);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment