1
0
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:
Victor 2017-09-02 13:52:55 +03:00
parent 65f6d17917
commit 4e72878546
8 changed files with 116 additions and 4 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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];

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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)