mirror of
https://github.com/aNNiMON/HotaruFX.git
synced 2024-09-19 14:14:21 +03:00
Add polygon and polyline nodes
This commit is contained in:
parent
65f6d17917
commit
4e72878546
@ -5,13 +5,17 @@ import com.annimon.hotarufx.lib.Function;
|
|||||||
import com.annimon.hotarufx.lib.NodeValue;
|
import com.annimon.hotarufx.lib.NodeValue;
|
||||||
import com.annimon.hotarufx.lib.Types;
|
import com.annimon.hotarufx.lib.Types;
|
||||||
import com.annimon.hotarufx.lib.Validator;
|
import com.annimon.hotarufx.lib.Validator;
|
||||||
|
import com.annimon.hotarufx.lib.Value;
|
||||||
import com.annimon.hotarufx.visual.objects.CircleNode;
|
import com.annimon.hotarufx.visual.objects.CircleNode;
|
||||||
import com.annimon.hotarufx.visual.objects.GroupNode;
|
import com.annimon.hotarufx.visual.objects.GroupNode;
|
||||||
import com.annimon.hotarufx.visual.objects.ObjectNode;
|
import com.annimon.hotarufx.visual.objects.ObjectNode;
|
||||||
|
import com.annimon.hotarufx.visual.objects.PolygonNode;
|
||||||
|
import com.annimon.hotarufx.visual.objects.PolylineNode;
|
||||||
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
||||||
import com.annimon.hotarufx.visual.objects.SVGPathNode;
|
import com.annimon.hotarufx.visual.objects.SVGPathNode;
|
||||||
import com.annimon.hotarufx.visual.objects.TextNode;
|
import com.annimon.hotarufx.visual.objects.TextNode;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
@ -22,6 +26,8 @@ public class NodesBundle implements Bundle {
|
|||||||
public void load(Context context) {
|
public void load(Context context) {
|
||||||
context.functions().put("circle", node(CircleNode::new));
|
context.functions().put("circle", node(CircleNode::new));
|
||||||
context.functions().put("group", group());
|
context.functions().put("group", group());
|
||||||
|
context.functions().put("polygon", poly(PolygonNode::new));
|
||||||
|
context.functions().put("polyline", poly(PolylineNode::new));
|
||||||
context.functions().put("rectangle", node(RectangleNode::new));
|
context.functions().put("rectangle", node(RectangleNode::new));
|
||||||
context.functions().put("svgPath", node(SVGPathNode::new));
|
context.functions().put("svgPath", node(SVGPathNode::new));
|
||||||
context.functions().put("text", node(TextNode::new));
|
context.functions().put("text", node(TextNode::new));
|
||||||
@ -36,6 +42,19 @@ public class NodesBundle implements Bundle {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Function poly(java.util.function.Function<List<Double>, ObjectNode> ctor) {
|
||||||
|
return args -> {
|
||||||
|
val validator = Validator.with(args);
|
||||||
|
val map = validator.requireMapAt(1);
|
||||||
|
val points = validator.requireArrayAt(0).stream()
|
||||||
|
.map(Value::asNumber)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
val node = new NodeValue(ctor.apply(points));
|
||||||
|
node.fill(map);
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private Function group() {
|
private Function group() {
|
||||||
return args -> {
|
return args -> {
|
||||||
val nodes = Arrays.stream(args)
|
val nodes = Arrays.stream(args)
|
||||||
|
@ -3,6 +3,8 @@ package com.annimon.hotarufx.lib;
|
|||||||
import com.annimon.hotarufx.exceptions.TypeException;
|
import com.annimon.hotarufx.exceptions.TypeException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
public class ArrayValue implements Value, Iterable<Value> {
|
public class ArrayValue implements Value, Iterable<Value> {
|
||||||
@ -71,6 +73,10 @@ public class ArrayValue implements Value, Iterable<Value> {
|
|||||||
return Arrays.asList(elements).iterator();
|
return Arrays.asList(elements).iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Stream<Value> stream() {
|
||||||
|
return Arrays.stream(elements);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 5;
|
int hash = 5;
|
||||||
|
@ -36,6 +36,15 @@ public class Validator {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayValue requireArrayAt(int index) {
|
||||||
|
checkAtLeast(index + 1);
|
||||||
|
val value = args[index];
|
||||||
|
if (value.type() != Types.ARRAY) {
|
||||||
|
throw new TypeException(String.format("Array required at %d argument", index));
|
||||||
|
}
|
||||||
|
return (ArrayValue) value;
|
||||||
|
}
|
||||||
|
|
||||||
public MapValue requireMapAt(int index) {
|
public MapValue requireMapAt(int index) {
|
||||||
checkAtLeast(index + 1);
|
checkAtLeast(index + 1);
|
||||||
val value = args[index];
|
val value = args[index];
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.annimon.hotarufx.visual.objects;
|
||||||
|
|
||||||
|
import com.annimon.hotarufx.visual.visitors.NodeVisitor;
|
||||||
|
import java.util.List;
|
||||||
|
import javafx.scene.shape.Polygon;
|
||||||
|
|
||||||
|
public class PolygonNode extends ShapeNode {
|
||||||
|
|
||||||
|
public final Polygon polygon;
|
||||||
|
|
||||||
|
public PolygonNode(List<Double> points) {
|
||||||
|
this(new Polygon(), points);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PolygonNode(Polygon polygon, List<Double> points) {
|
||||||
|
super(polygon);
|
||||||
|
this.polygon = polygon;
|
||||||
|
polygon.getPoints().addAll(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R, T> R accept(NodeVisitor<R, T> visitor, T input) {
|
||||||
|
return visitor.visit(this, input);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.annimon.hotarufx.visual.objects;
|
||||||
|
|
||||||
|
import com.annimon.hotarufx.visual.visitors.NodeVisitor;
|
||||||
|
import java.util.List;
|
||||||
|
import javafx.scene.shape.Polyline;
|
||||||
|
|
||||||
|
public class PolylineNode extends ShapeNode {
|
||||||
|
|
||||||
|
public final Polyline polyline;
|
||||||
|
|
||||||
|
public PolylineNode(List<Double> points) {
|
||||||
|
this(new Polyline(), points);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PolylineNode(Polyline polyline, List<Double> points) {
|
||||||
|
super(polyline);
|
||||||
|
this.polyline = polyline;
|
||||||
|
polyline.getPoints().addAll(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R, T> R accept(NodeVisitor<R, T> visitor, T input) {
|
||||||
|
return visitor.visit(this, input);
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@ package com.annimon.hotarufx.visual.visitors;
|
|||||||
|
|
||||||
import com.annimon.hotarufx.visual.objects.CircleNode;
|
import com.annimon.hotarufx.visual.objects.CircleNode;
|
||||||
import com.annimon.hotarufx.visual.objects.GroupNode;
|
import com.annimon.hotarufx.visual.objects.GroupNode;
|
||||||
|
import com.annimon.hotarufx.visual.objects.PolygonNode;
|
||||||
|
import com.annimon.hotarufx.visual.objects.PolylineNode;
|
||||||
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
||||||
import com.annimon.hotarufx.visual.objects.SVGPathNode;
|
import com.annimon.hotarufx.visual.objects.SVGPathNode;
|
||||||
import com.annimon.hotarufx.visual.objects.TextNode;
|
import com.annimon.hotarufx.visual.objects.TextNode;
|
||||||
@ -10,6 +12,8 @@ public interface NodeVisitor<R, T> {
|
|||||||
|
|
||||||
R visit(CircleNode node, T input);
|
R visit(CircleNode node, T input);
|
||||||
R visit(GroupNode node, T input);
|
R visit(GroupNode node, T input);
|
||||||
|
R visit(PolygonNode node, T input);
|
||||||
|
R visit(PolylineNode node, T input);
|
||||||
R visit(RectangleNode node, T input);
|
R visit(RectangleNode node, T input);
|
||||||
R visit(SVGPathNode node, T input);
|
R visit(SVGPathNode node, T input);
|
||||||
R visit(TextNode node, T input);
|
R visit(TextNode node, T input);
|
||||||
|
@ -5,6 +5,8 @@ import com.annimon.hotarufx.visual.VirtualScene;
|
|||||||
import com.annimon.hotarufx.visual.objects.CircleNode;
|
import com.annimon.hotarufx.visual.objects.CircleNode;
|
||||||
import com.annimon.hotarufx.visual.objects.GroupNode;
|
import com.annimon.hotarufx.visual.objects.GroupNode;
|
||||||
import com.annimon.hotarufx.visual.objects.ObjectNode;
|
import com.annimon.hotarufx.visual.objects.ObjectNode;
|
||||||
|
import com.annimon.hotarufx.visual.objects.PolygonNode;
|
||||||
|
import com.annimon.hotarufx.visual.objects.PolylineNode;
|
||||||
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
import com.annimon.hotarufx.visual.objects.RectangleNode;
|
||||||
import com.annimon.hotarufx.visual.objects.SVGPathNode;
|
import com.annimon.hotarufx.visual.objects.SVGPathNode;
|
||||||
import com.annimon.hotarufx.visual.objects.TextNode;
|
import com.annimon.hotarufx.visual.objects.TextNode;
|
||||||
@ -30,6 +32,16 @@ public class RenderVisitor implements NodeVisitor<Void, VirtualScene> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(PolygonNode node, VirtualScene scene) {
|
||||||
|
return render(node, scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(PolylineNode node, VirtualScene scene) {
|
||||||
|
return render(node, scene);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(RectangleNode node, VirtualScene scene) {
|
public Void visit(RectangleNode node, VirtualScene scene) {
|
||||||
return render(node, scene);
|
return render(node, scene);
|
||||||
|
@ -71,8 +71,20 @@ HEART = svgPath({
|
|||||||
stroke: "white"
|
stroke: "white"
|
||||||
})
|
})
|
||||||
|
|
||||||
#render(B, A, C, CLIP, HEART)
|
points = [
|
||||||
|
0, -50,
|
||||||
|
-25, 0,
|
||||||
|
25, 0,
|
||||||
|
0, 50,
|
||||||
|
]
|
||||||
|
POLYGON = polygon(points, {
|
||||||
|
translateX: -300,
|
||||||
|
fill: "purple"
|
||||||
|
})
|
||||||
|
POLYLINE = polyline(points, {
|
||||||
|
translateX: 300,
|
||||||
|
stroke: "purple"
|
||||||
|
})
|
||||||
|
|
||||||
|
render(B, A, C, CLIP, HEART, POLYGON, POLYLINE)
|
||||||
|
|
||||||
G1 = group(B, A)
|
|
||||||
G1@rotate.add(10, 45).add(20, -45)
|
|
||||||
render(G1)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user