28package com.jogamp.graph.ui.layout;
32import com.jogamp.graph.ui.Group;
33import com.jogamp.graph.ui.Shape;
34import com.jogamp.math.FloatUtil;
35import com.jogamp.math.Vec2f;
36import com.jogamp.math.Vec3f;
37import com.jogamp.math.geom.AABBox;
38import com.jogamp.math.util.PMVMatrix4f;
64 private final Order order;
65 private final int col_limit;
66 private final int row_limit;
67 private final Vec2f cellSize;
70 private final Gap gap;
73 private int row_count, col_count;
75 private static final boolean TRACE_LAYOUT =
false;
84 public GridLayout(
final int column_limit,
final float cellWidth,
final float cellHeight,
final Alignment alignment) {
85 this(alignment, Math.max(1, column_limit), -1, cellWidth, cellHeight,
Gap.
None,
null);
96 public GridLayout(
final int column_limit,
final float cellWidth,
final float cellHeight,
final Alignment alignment,
final Gap gap) {
97 this(alignment, Math.max(1, column_limit), -1, cellWidth, cellHeight, gap,
null);
110 this(alignment, Math.max(1, column_limit), -1, cellWidth, cellHeight, gap, padding);
120 public GridLayout(
final float cellWidth,
final float cellHeight,
final Alignment alignment,
final int row_limit) {
121 this(alignment, -1, Math.max(1, row_limit), cellWidth, cellHeight,
Gap.
None,
null);
132 public GridLayout(
final float cellWidth,
final float cellHeight,
final Alignment alignment,
final Gap gap,
final int row_limit) {
133 this(alignment, -1, Math.max(1, row_limit), cellWidth, cellHeight, gap,
null);
146 this(alignment, -1, Math.max(1, row_limit), cellWidth, cellHeight, gap, padding);
149 private GridLayout(
final Alignment alignment,
final int column_limit,
final int row_limit,
final float cellWidth,
final float cellHeight,
151 this.order = 0 < column_limit ? Order.COLUMN : Order.ROW;
152 this.col_limit = column_limit;
153 this.row_limit = row_limit;
154 this.cellSize =
new Vec2f(Math.max(0f, cellWidth), Math.max(0f, cellHeight));
155 this.alignment = alignment;
157 this.padding = padding;
179 if(
null != padding ) {
191 final List<Shape> shapes = g.
getShapes();
193 row_count = (int) Math.ceil( (
double)shapes.size() / (double)col_limit );
194 col_count = col_limit;
196 row_count = row_limit;
197 col_count = (int) Math.ceil( (
double)shapes.size() / (double)row_limit );
200 System.err.println(
"gl.00: "+order+
", "+col_count+
" x "+row_count+
", a "+alignment+
", shapes "+shapes.size()+
", "+gap+
", "+box);
202 int col_i = 0, row_i = 0;
204 float totalWidth=-Float.MAX_VALUE, totalHeight=-Float.MAX_VALUE;
206 final float[] y_pos =
new float[col_count * row_count];
209 for(
int i=0; i < shapes.size(); ++i) {
210 final Shape s = shapes.get(i);
217 final float shapeWidthU = sbox.
getWidth();
218 final float shapeHeightU = sbox.
getHeight();
226 final float cellWidth = hasCellWidth ? cellSize.x() : shapeWidthU;
227 final float cellHeight = hasCellHeight ? cellSize.y() : shapeHeightU;
228 final float sx = cellWidth / shapeWidthU;
229 final float sy = cellHeight/ shapeHeightU;
230 sxy = sx < sy ? sx : sy;
234 final float shapeWidthS = sxy * shapeWidthU;
235 final float shapeHeightS = sxy * shapeHeightU;
236 final float cellWidthS = hasCellWidth ? cellSize.x() : shapeWidthS;
237 final float cellHeightS = hasCellHeight ? cellSize.y() : shapeHeightS;
240 final float y0 = y + cellHeightS;
241 final float x1 = x + cellWidthS;
242 totalHeight = Math.max(totalHeight, y0);
243 totalWidth = Math.max(totalWidth, x1);
244 y_pos[col_count * row_i + col_i] = y0;
246 System.err.println(
"gl.00: y("+i+
")["+col_i+
"]["+row_i+
"]: "+y0+
", ["+cellWidthS+
" x "+cellHeightS+
"]");
250 if( i + 1 < shapes.size() ) {
252 if( col_i + 1 == col_count ) {
256 y += cellHeightS + gap.
height();
259 x += cellWidthS + gap.
width();
262 if( row_i + 1 == row_count ) {
266 x += cellWidthS + gap.
width();
269 y += cellHeightS + gap.
height();
275 System.err.println(
"gl[__].00: Total "+totalWidth+
" / "+totalHeight);
279 row_i = 0; col_i = 0;
281 for(
int i=0; i < shapes.size(); ++i) {
282 final Shape s = shapes.get(i);
283 final AABBox sbox = sboxes[i];
288 System.err.println(
"gl("+i+
")["+col_i+
"]["+row_i+
"].0: sbox "+sbox+
", s "+s);
292 final float shapeWidthU = sbox.
getWidth();
293 final float shapeHeightU = sbox.
getHeight();
295 float dxh = 0, dyh = 0;
298 final float cellWidth = hasCellWidth ? cellSize.x() : shapeWidthU;
299 final float cellHeight = hasCellHeight ? cellSize.y() : shapeHeightU;
300 final float sx = cellWidth / shapeWidthU;
301 final float sy = cellHeight/ shapeHeightU;
302 sxy = sx < sy ? sx : sy;
305 System.err.println(
"gl("+i+
")["+col_i+
"]["+row_i+
"].s: "+sx+
" x "+sy+
" -> "+sxy+
": +"+dxh+
" / "+dyh+
", U: s "+shapeWidthU+
" x "+shapeHeightU+
", sz "+cellWidth+
" x "+cellHeight);
310 final float shapeWidthS = sxy * shapeWidthU;
311 final float shapeHeightS = sxy * shapeHeightU;
312 final float cellWidthS = hasCellWidth ? cellSize.x() : shapeWidthS;
313 final float cellHeightS = hasCellHeight ? cellSize.y() : shapeHeightS;
315 y = totalHeight - y_pos[col_count * row_i + col_i];
317 if( isCenteredHoriz ) {
318 dxh += 0.5f * ( cellWidthS - shapeWidthS );
320 if( isCenteredVert ) {
321 dyh += 0.5f * ( cellHeightS - shapeHeightS );
325 System.err.println(
"gl("+i+
")["+col_i+
"]["+row_i+
"].m: "+x+
" / "+y+
" + "+dxh+
" / "+dyh+
", S: s "+shapeWidthS+
" x "+shapeHeightS+
", sz "+cellWidthS+
" x "+cellHeightS);
330 final float aX = x + dxh;
331 final float aY = y + dyh;
338 if( isCenteredHoriz || isCenteredVert ) {
339 if( !isCenteredVert && diffBL.y() > 0 ) {
341 }
else if( !isCenteredHoriz && diffBL.x() > 0 ) {
350 System.err.println(
"gl("+i+
")["+col_i+
"]["+row_i+
"].bl: sbox0 "+s.
getBounds()+
", diffBL_ "+diffBL);
355 box.
resize( x + cellWidthS, y + cellHeightS, sbox.
getMaxZ());
357 s.scale( sxy, sxy, 1f);
360 System.err.println(
"gl("+i+
")["+col_i+
"]["+row_i+
"].x: "+x+
" / "+y+
" + "+dxh+
" / "+dyh+
" -> "+s.
getPosition()+
", p3 "+shapeWidthS+
" x "+shapeHeightS+
", sz3 "+cellWidthS+
" x "+cellHeightS+
", box "+box.
getWidth()+
" x "+box.
getHeight());
361 System.err.println(
"gl("+i+
")["+col_i+
"]["+row_i+
"].x: "+s);
362 System.err.println(
"gl("+i+
")["+col_i+
"]["+row_i+
"].x: "+box);
365 if( i + 1 < shapes.size() ) {
368 if( col_i + 1 == col_count ) {
374 x += cellWidthS + gap.
width();
377 if( row_i + 1 == row_count ) {
381 x += cellWidthS + gap.
width();
392 System.err.println(
"gl.xx: "+box);
398 final String p_s = (
null == padding || padding.
zeroSize() ) ?
"" :
", "+padding.
toString();
400 return "Grid["+col_count+
"x"+row_count+
", "+order+
", cell "+cellSize+
", a "+alignment+g_s+p_s+
"]";
Group of Shapes, optionally utilizing a Group.Layout.
List< Shape > getShapes()
Returns added Shapes.
Generic Shape, potentially using a Graph via GraphShape or other means of representing content.
final Shape move(final float dtx, final float dty, final float dtz)
Move about scaled distance.
final Vec3f getScale()
Returns scale Vec3f reference.
final Shape moveTo(final float tx, final float ty, final float tz)
Move to scaled position.
final Vec3f getPosition()
Returns position Vec3f reference, i.e.
final AABBox getBounds()
Returns the unscaled bounding AABBox for this shape, borrowing internal instance.
final Shape setPaddding(final Padding padding)
Sets the unscaled padding for this shape, which is included in unscaled getBounds() and also includes...
final void applyMatToMv(final PMVMatrix4f pmv)
Applies the internal Matrix4f to the given modelview matrix, i.e.
Immutable layout alignment options, including Bit#Fill.
boolean isSet(final Bit bit)
GraphUI CSS property Gap, scaled spacing between (grid) cells not belonging to the cell element.
static final Gap None
Zero gap constant.
float height()
Return scaled height of vertical value, i.e.
float width()
Return scaled width of horizontal value, i.e.
GraphUI Grid Group.Layout.
GridLayout(final int column_limit, final float cellWidth, final float cellHeight, final Alignment alignment, final Gap gap)
Default layout order of Group#getShapes()} is Order#COLUMN.
Vec2f getCellSize()
Returns the preset cell size.
int getColumnCount()
Returns column count after layout(Group, AABBox, PMVMatrix4f).
Order getOrder()
Returns given Order.
void preValidate(final Shape s)
Prepare given Shape before validation, e.g.
GridLayout(final float cellWidth, final float cellHeight, final Alignment alignment, final Gap gap, final Padding padding, final int row_limit)
Default layout order of Group#getShapes()} is Order#ROW.
GridLayout(final int column_limit, final float cellWidth, final float cellHeight, final Alignment alignment)
Default layout order of Group#getShapes()} is Order#COLUMN.
GridLayout(final float cellWidth, final float cellHeight, final Alignment alignment, final int row_limit)
Default layout order of Group#getShapes()} is Order#ROW.
Padding getPadding()
Returns given unscaled Padding, may be null if not given via constructor.
GridLayout(final int column_limit, final float cellWidth, final float cellHeight, final Alignment alignment, final Gap gap, final Padding padding)
Default layout order of Group#getShapes()} is Order#COLUMN.
void layout(final Group g, final AABBox box, final PMVMatrix4f pmv)
Performing the layout of Group#getShapes(), called @ Shape#validate(GL2ES2) or Shape#validate(GLProfi...
Gap getGap()
Returns given scaled Gap.
Alignment getAlignment()
Returns given Alignment.
int getRowCount()
Returns row count after layout(Group, AABBox, PMVMatrix4f).
GridLayout(final float cellWidth, final float cellHeight, final Alignment alignment, final Gap gap, final int row_limit)
Default layout order of Group#getShapes()} is Order#ROW.
GraphUI CSS property Padding, unscaled space belonging to the element and included in the element's s...
Basic Float math utility functions.
static boolean isZero(final float a, final float epsilon)
Returns true if value is zero, i.e.
2D Vector based upon two float components.
3D Vector based upon three float components.
Vec3f mul(final float val)
Returns this * val; creates new vector.
Vec3f scale(final float s)
this = this * s, returns this.
Vec3f min(final Vec3f m)
this = min(this, m), returns this.
Axis Aligned Bounding Box.
final Vec3f getLow()
Returns the minimum left-bottom-far (xyz) coordinate.
AABBox transform(final Matrix4f mat, final AABBox out)
Transform this box using the given Matrix4f into out @endiliteral.
final AABBox resize(final AABBox newBox)
Resize the AABBox to encapsulate another AABox.
PMVMatrix4f implements the basic computer graphics Matrix4f pack using projection (P),...
final Matrix4f getMv()
Returns the modelview matrix (Mv).
final PMVMatrix4f popMv()
Pop the modelview matrix from its stack.
final PMVMatrix4f pushMv()
Push the modelview matrix to its stack, while preserving its values.
CenterHoriz
Horizontal center alignment.
CenterVert
Vertical center alignment.
Fill
Scale object to parent size, e.g.
Layout order for Group#getShapes()} after population.
COLUMN
COLUMN layout order of Group#getShapes()} is left to right and top to bottom.
Layout for the GraphUI Group, called @ Shape#validate(GL2ES2) or Shape#validate(GLProfile).