mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-04-14 14:43:33 +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.Graphics2D;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -28,9 +29,20 @@ import java.util.List;
|
|||||||
* benötigen, erst nach Hinzufügen der Gruppenelemente ausgeführt werden.
|
* benötigen, erst nach Hinzufügen der Gruppenelemente ausgeführt werden.
|
||||||
* Nachdem sich die Zusammensetzung der Gruppe geändert hat, muss die Gruppe
|
* Nachdem sich die Zusammensetzung der Gruppe geändert hat, muss die Gruppe
|
||||||
* ggf. neu ausgerichtet werden.
|
* 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 class ShapeGroup extends Shape {
|
||||||
|
|
||||||
|
public static final int ARRANGE_ROWS = 0;
|
||||||
|
|
||||||
|
public static final int ARRANGE_COLS = 1;
|
||||||
|
|
||||||
private List<Shape> shapes;
|
private List<Shape> shapes;
|
||||||
|
|
||||||
private double groupWidth = -1.0;
|
private double groupWidth = -1.0;
|
||||||
@@ -132,6 +144,111 @@ public class ShapeGroup extends Shape {
|
|||||||
return groupHeight;
|
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() {
|
private void invalidateBounds() {
|
||||||
groupWidth = -1.0;
|
groupWidth = -1.0;
|
||||||
groupHeight = -1.0;
|
groupHeight = -1.0;
|
||||||
@@ -148,6 +265,25 @@ public class ShapeGroup extends Shape {
|
|||||||
maxy = Math.max(maxy, bounds.y + bounds.height);
|
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;
|
groupWidth = maxx - minx;
|
||||||
groupHeight = maxy - miny;
|
groupHeight = maxy - miny;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user