mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-04-14 06:33:34 +02:00
arrange und align Funktionen
This commit is contained in:
@@ -5,6 +5,7 @@ import schule.ngb.zm.Options;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -28,9 +29,20 @@ import java.util.List;
|
||||
* benötigen, erst nach Hinzufügen der Gruppenelemente ausgeführt werden.
|
||||
* Nachdem sich die Zusammensetzung der Gruppe geändert hat, muss die Gruppe
|
||||
* ggf. neu ausgerichtet werden.
|
||||
* <p>
|
||||
* Für die Ausrichtung der Elemente in einer Gruppe können
|
||||
* {@link #arrange(Options.Direction, double)},
|
||||
* {@link #arrangeInGrid(int, Options.Direction, double, int)} und
|
||||
* {@link #align(Options.Direction)} verwendet werden, die jeweils die Position
|
||||
* der Formen in der Gruppe ändern und nicht die Position der Gruppe selbst (so
|
||||
* wie z.B. {@link #alignTo(Shape, Options.Direction)}.
|
||||
*/
|
||||
public class ShapeGroup extends Shape {
|
||||
|
||||
public static final int ARRANGE_ROWS = 0;
|
||||
|
||||
public static final int ARRANGE_COLS = 1;
|
||||
|
||||
private List<Shape> shapes;
|
||||
|
||||
private double groupWidth = -1.0;
|
||||
@@ -132,6 +144,111 @@ public class ShapeGroup extends Shape {
|
||||
return groupHeight;
|
||||
}
|
||||
|
||||
public void arrange( Options.Direction dir, double buffer ) {
|
||||
Shape last = null;
|
||||
for( Shape s : shapes ) {
|
||||
if( last != null ) {
|
||||
s.nextTo(last, dir, buffer);
|
||||
} else {
|
||||
s.moveTo(0, 0);
|
||||
}
|
||||
last = s;
|
||||
}
|
||||
invalidateBounds();
|
||||
}
|
||||
|
||||
public void arrangeInRows( int n, Options.Direction dir, double buffer ) {
|
||||
arrangeInGrid(n, dir, buffer, ARRANGE_ROWS);
|
||||
}
|
||||
|
||||
public void arrangeInColumns( int n, Options.Direction dir, double buffer ) {
|
||||
arrangeInGrid(n, dir, buffer, ARRANGE_COLS);
|
||||
}
|
||||
|
||||
public void arrangeInGrid( int n, Options.Direction dir, double buffer, int mode ) {
|
||||
// Calculate grid size
|
||||
int rows, cols;
|
||||
if( mode == ARRANGE_ROWS ) {
|
||||
rows = n;
|
||||
cols = (int) ceil(shapes.size() / n);
|
||||
} else {
|
||||
cols = n;
|
||||
rows = (int) ceil(shapes.size() / n);
|
||||
}
|
||||
|
||||
// Calculate grid cell size
|
||||
double maxHeight = shapes.stream().mapToDouble(
|
||||
( s ) -> s.getHeight()
|
||||
).reduce(0.0, Double::max);
|
||||
double maxWidth = shapes.stream().mapToDouble(
|
||||
( s ) -> s.getWidth()
|
||||
).reduce(0.0, Double::max);
|
||||
double halfHeight = maxHeight * .5;
|
||||
double halfWidth = maxWidth * .5;
|
||||
|
||||
// Layout shapes
|
||||
for( int i = 0; i < shapes.size(); i++ ) {
|
||||
// Calculate center of grid cell
|
||||
int row, col;
|
||||
switch( dir ) {
|
||||
case UP:
|
||||
case NORTH:
|
||||
row = rows - i % rows;
|
||||
col = cols - (i / rows);
|
||||
break;
|
||||
case LEFT:
|
||||
case WEST:
|
||||
row = rows - (i / cols);
|
||||
col = cols - i % cols;
|
||||
break;
|
||||
case RIGHT:
|
||||
case EAST:
|
||||
row = i / cols;
|
||||
col = i % cols;
|
||||
break;
|
||||
case DOWN:
|
||||
case SOUTH:
|
||||
default:
|
||||
row = i % rows;
|
||||
col = i / rows;
|
||||
break;
|
||||
}
|
||||
|
||||
double centerX = halfWidth + col * (maxWidth + buffer);
|
||||
double centerY = halfHeight + row * (maxHeight + buffer);
|
||||
|
||||
// Move shape to proper anchor location in cell
|
||||
Shape s = shapes.get(i);
|
||||
Point2D ap = Shape.getAnchorPoint(maxWidth, maxHeight, s.getAnchor());
|
||||
s.moveTo(centerX + ap.getX(), centerY + ap.getY());
|
||||
}
|
||||
|
||||
invalidateBounds();
|
||||
}
|
||||
|
||||
public void align( Options.Direction dir ) {
|
||||
Shape target = shapes.stream().reduce(null,
|
||||
( t, s ) -> {
|
||||
if( t == null ) return s;
|
||||
Point2D apt = t.getAbsAnchorPoint(dir);
|
||||
Point2D aps = s.getAbsAnchorPoint(dir);
|
||||
if( apt.getX() * dir.x >= aps.getX() * dir.x && apt.getY() * dir.y >= aps.getY() * dir.y ) {
|
||||
return t;
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
for( Shape s : shapes ) {
|
||||
if( s != target ) {
|
||||
s.alignTo(target, dir);
|
||||
}
|
||||
}
|
||||
|
||||
invalidateBounds();
|
||||
}
|
||||
|
||||
private void invalidateBounds() {
|
||||
groupWidth = -1.0;
|
||||
groupHeight = -1.0;
|
||||
@@ -148,6 +265,25 @@ public class ShapeGroup extends Shape {
|
||||
maxy = Math.max(maxy, bounds.y + bounds.height);
|
||||
}
|
||||
|
||||
//groupWidth = maxx - minx;
|
||||
//groupHeight = maxy - miny;
|
||||
groupWidth = maxx;
|
||||
groupHeight = maxy;
|
||||
}
|
||||
|
||||
public void pack() {
|
||||
double minx = Double.MAX_VALUE, miny = Double.MAX_VALUE,
|
||||
maxx = Double.MIN_VALUE, maxy = Double.MIN_VALUE;
|
||||
for( Shape pShape : shapes ) {
|
||||
Bounds bounds = pShape.getBounds();
|
||||
minx = Math.min(minx, bounds.x);
|
||||
maxx = Math.max(maxx, bounds.x + bounds.width);
|
||||
miny = Math.min(miny, bounds.y);
|
||||
maxy = Math.max(maxy, bounds.y + bounds.height);
|
||||
}
|
||||
|
||||
x = minx;
|
||||
y = miny;
|
||||
groupWidth = maxx - minx;
|
||||
groupHeight = maxy - miny;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user