aboutsummaryrefslogtreecommitdiffstats
path: root/src/graphui/classes/com/jogamp/graph
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphui/classes/com/jogamp/graph')
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/Group.java47
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java144
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/layout/Padding.java49
3 files changed, 198 insertions, 42 deletions
diff --git a/src/graphui/classes/com/jogamp/graph/ui/Group.java b/src/graphui/classes/com/jogamp/graph/ui/Group.java
index b3ae5b41d..e349b1302 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/Group.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/Group.java
@@ -48,10 +48,22 @@ import jogamp.graph.ui.TreeTool;
* @see Group.Layout
*/
public class Group extends Shape implements Container {
- /** Layout for the group, called @ {@link Group#validate(GL2ES2)} or {@link Group#validate(GLProfile)}. */
+ /** Layout for the GraphUI {@link Group}, called @ {@link Shape#validate(GL2ES2)} or {@link Shape#validate(GLProfile)}. */
public static interface Layout {
- /** Performing the layout, called @ {@link Group#validate(GL2ES2)} or {@link Group#validate(GLProfile)}. */
- void layout(Group g);
+ /**
+ * Performing the layout of {@link Group#getShapes()}, called @ {@link Shape#validate(GL2ES2)} or {@link Shape#validate(GLProfile)}.
+ * <p>
+ * According to the implemented layout, method
+ * - may scale the {@Link Shape}s
+ * - may move the {@Link Shape}s
+ * - may reuse the given {@link PMVMatrix} `pmv`
+ * - must update the given {@link AABBox} `box`
+ * </p>
+ * @param g the {@link Group} to layout
+ * @param box the bounding box of {@link Group} to be updated by this method.
+ * @param pmv a {@link PMVMatrix} which can be reused.
+ */
+ void layout(final Group g, final AABBox box, final PMVMatrix pmv);
}
private final List<Shape> shapes = new ArrayList<Shape>();
@@ -161,12 +173,6 @@ public class Group extends Shape implements Container {
}
}
- private void layout() {
- if( null != layouter ) {
- layouter.layout(this);
- }
- }
-
private boolean doFrustumCulling = false;
@Override
@@ -200,21 +206,25 @@ public class Group extends Shape implements Container {
@Override
protected void validateImpl(final GLProfile glp, final GL2ES2 gl) {
if( isShapeDirty() ) {
- layout();
final PMVMatrix pmv = new PMVMatrix();
final AABBox tmpBox = new AABBox();
for(final Shape s : shapes) {
- // s.validateImpl(glp, gl);
if( null != gl ) {
s.validate(gl);
} else {
s.validate(glp);
}
- pmv.glPushMatrix();
- s.setTransform(pmv);
- s.getBounds().transformMv(pmv, tmpBox);
- pmv.glPopMatrix();
- box.resize(tmpBox);
+ }
+ if( null != layouter ) {
+ layouter.layout(this, box, pmv);
+ } else {
+ for(final Shape s : shapes) {
+ pmv.glPushMatrix();
+ s.setTransform(pmv);
+ s.getBounds().transformMv(pmv, tmpBox);
+ pmv.glPopMatrix();
+ box.resize(tmpBox);
+ }
}
}
}
@@ -249,6 +259,11 @@ public class Group extends Shape implements Container {
}
@Override
+ public String getSubString() {
+ return super.getSubString()+", shapes "+shapes.size();
+ }
+
+ @Override
public boolean forOne(final PMVMatrix pmv, final Shape shape, final Runnable action) {
return TreeTool.forOne(shapes, pmv, shape, action);
}
diff --git a/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java b/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java
index bd2fd2d76..7d1739dd6 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010-2023 JogAmp Community. All rights reserved.
+ * Copyright 2023 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -27,43 +27,135 @@
*/
package com.jogamp.graph.ui.layout;
+import java.util.List;
+
+import com.jogamp.graph.ui.GraphShape;
import com.jogamp.graph.ui.Group;
import com.jogamp.graph.ui.Shape;
-import com.jogamp.graph.ui.Group.Layout;
+import com.jogamp.opengl.math.geom.AABBox;
+import com.jogamp.opengl.util.PMVMatrix;
+/**
+ * GraphUI Grid {@link Group.Layout}.
+ */
public class GridLayout implements Group.Layout {
- private final int columns;
- private final float padX, padY;
+ /** Layout order for {@link Group#getShapes()}} after population. */
+ public static enum Order {
+ /** COLUMN layout order of {@link Group#getShapes()}} is left to right and top to bottom. */
+ COLUMN,
+ /** ROW layout order of {@link Group#getShapes()}} is top to bottom and left to right. */
+ ROW
+ }
+ private final Order order;
+ private final int col_limit;
+ private final int row_limit;
+ private final float cellWidth, cellHeight;
+ private final Padding padding;
+ private int row_count, col_count;
+
+
+ /**
+ * Default layout order of {@link Group#getShapes()}} is {@link Order#COLUMN}.
+ * @param column_limit [1..inf)
+ * @param cellWidth
+ * @param cellHeight
+ */
+ public GridLayout(final int column_limit, final float cellWidth, final float cellHeight) {
+ this(Math.max(1, column_limit), -1, cellWidth, cellHeight, new Padding());
+ }
+
+ /**
+ * Default layout order of {@link Group#getShapes()}} is {@link Order#COLUMN}.
+ * @param column_limit [1..inf)
+ * @param cellWidth
+ * @param cellHeight
+ * @param padding
+ */
+ public GridLayout(final int column_limit, final float cellWidth, final float cellHeight, final Padding padding) {
+ this(Math.max(1, column_limit), -1, cellWidth, cellHeight, padding);
+ }
/**
- *
- * @param columns [1..inf)
- * @param padX
- * @param padY
+ * Default layout order of {@link Group#getShapes()}} is {@link Order#ROW}.
+ * @param cellWidth
+ * @param cellHeight
+ * @param padding
+ * @param row_limit [1..inf)
*/
- public GridLayout(final int columns, final float padX, final float padY) {
- this.columns = Math.max(1, columns);
- this.padX = padX;
- this.padY = padY;
+ public GridLayout(final float cellWidth, final float cellHeight, final Padding padding, final int row_limit) {
+ this(-1, Math.max(1, row_limit), cellWidth, cellHeight, padding);
+ }
+
+ private GridLayout(final int column_limit, final int row_limit, final float cellWidth, final float cellHeight, final Padding padding) {
+ this.order = 0 < column_limit ? Order.COLUMN : Order.ROW;
+ this.col_limit = column_limit;
+ this.row_limit = row_limit;
+ this.cellWidth = cellWidth;
+ this.cellHeight = cellHeight;
+ this.padding = padding;;
+ row_count = 0;
+ col_count = 0;
}
+ public Order getOrder() { return order; }
+ public int getColumnCount() { return col_count; }
+ public int getRowCount() { return row_count; }
+
@Override
- public void layout(final Group g) {
- int col = 0;
- float x=0;
- float y=0;
- for(final Shape s : g.getShapes()) {
- s.moveTo(x, y, 0);
- if( col + 1 == columns ) {
- col = 0;
- // row++;
- x = 0;
- y -= padY;
- } else {
- col++;
- x += padX;
+ public void layout(final Group g, final AABBox box, final PMVMatrix pmv) {
+ final List<Shape> shapes = g.getShapes();
+ if( Order.COLUMN == order ) {
+ row_count = (int) Math.ceil( (double)shapes.size() / (double)col_limit );
+ col_count = col_limit;
+ } else { // Order.ROW_MAJOR == order
+ row_count = row_limit;
+ col_count = (int) Math.ceil( (double)shapes.size() / (double)row_limit );
+ }
+ int col_i = 0, row_i = 0;
+ final AABBox sbox = new AABBox();
+ for(final Shape s : shapes) {
+ // measure size
+ pmv.glPushMatrix();
+ s.setTransform(pmv);
+ s.getBounds().transformMv(pmv, sbox);
+ pmv.glPopMatrix();
+
+ // adjust size and position (centered)
+ final float x = ( ( col_i ) * ( cellWidth + padding.width() ) ) + padding.left;
+ final float y = ( ( row_count - row_i - 1 ) * ( cellHeight + padding.height() ) ) + padding.bottom;
+ final float sx = cellWidth / sbox.getWidth();
+ final float sy = cellHeight/ sbox.getHeight();
+ final float sxy = sx < sy ? sx : sy;
+ final float dxh = sbox.getWidth() * ( sx - sxy ) * 0.5f;
+ final float dyh = sbox.getHeight() * ( sy - sxy ) * 0.5f;
+ s.moveTo( x + dxh, y + dyh, 0f );
+ s.scale( sxy, sxy, 1f);
+ box.resize( x + cellWidth + padding.right, y + cellHeight + padding.top, 0);
+ box.resize( x - padding.left, y - padding.bottom, 0);
+ // System.err.println("["+row_i+"]["+col_i+"]: "+x+" / "+y);
+
+ // position for next cell
+ if( Order.COLUMN == order ) {
+ if( col_i + 1 == col_limit ) {
+ col_i = 0;
+ row_i++;
+ } else {
+ col_i++;
+ }
+ } else { // Order.ROW_MAJOR == order
+ if( row_i + 1 == row_limit ) {
+ row_i = 0;
+ col_i++;
+ } else {
+ row_i++;
+ }
}
}
}
+
+ @Override
+ public String toString() {
+ return "Grid["+row_count+"x"+col_count+", "+order+", cell["+cellWidth+" x "+cellHeight+"], "+padding+"]";
+ }
}
diff --git a/src/graphui/classes/com/jogamp/graph/ui/layout/Padding.java b/src/graphui/classes/com/jogamp/graph/ui/layout/Padding.java
new file mode 100644
index 000000000..f4b35e723
--- /dev/null
+++ b/src/graphui/classes/com/jogamp/graph/ui/layout/Padding.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2023 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.graph.ui.layout;
+
+/**
+ * GraphUI Padding of cells, e.g. {@link GridLayout}.
+ */
+public class Padding {
+ public final float left, right, bottom, top;
+
+ public Padding() {
+ left = 0f; right = 0f; bottom = 0f; top = 0f;
+ }
+ public Padding(final float width, final float height) {
+ left = width/2f; right = width/2f; bottom = height/2f; top = height/2f;
+ }
+ public Padding(final float left, final float right, final float bottom, final float top) {
+ this.left = left; this.right = right; this.bottom = bottom; this.top = top;
+ }
+ public float width() { return left + right; }
+ public float height() { return bottom + top; }
+ @Override
+ public String toString() { return "Padding[l "+left+", r "+right+", b "+bottom+", t "+top+"]"; }
+}