diff --git a/app/src/main/java/com/annimon/hotarufx/bundles/NodesBundle.java b/app/src/main/java/com/annimon/hotarufx/bundles/NodesBundle.java index 186eceb..4d3ff78 100644 --- a/app/src/main/java/com/annimon/hotarufx/bundles/NodesBundle.java +++ b/app/src/main/java/com/annimon/hotarufx/bundles/NodesBundle.java @@ -6,15 +6,7 @@ import com.annimon.hotarufx.lib.NodeValue; import com.annimon.hotarufx.lib.Types; 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.GroupNode; -import com.annimon.hotarufx.visual.objects.LineNode; -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.SVGPathNode; -import com.annimon.hotarufx.visual.objects.TextNode; +import com.annimon.hotarufx.visual.objects.*; import java.util.Arrays; import java.util.List; import java.util.function.Supplier; @@ -26,6 +18,7 @@ public class NodesBundle implements Bundle { @Override public void load(Context context) { context.functions().put("circle", node(CircleNode::new)); + context.functions().put("ellipse", node(EllipseNode::new)); context.functions().put("group", group()); context.functions().put("line", node(LineNode::new)); context.functions().put("polygon", poly(PolygonNode::new)); diff --git a/app/src/main/java/com/annimon/hotarufx/visual/objects/EllipseNode.java b/app/src/main/java/com/annimon/hotarufx/visual/objects/EllipseNode.java new file mode 100644 index 0000000..683c395 --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/visual/objects/EllipseNode.java @@ -0,0 +1,70 @@ +package com.annimon.hotarufx.visual.objects; + +import com.annimon.hotarufx.visual.PropertyBindings; +import com.annimon.hotarufx.visual.PropertyTimeline; +import com.annimon.hotarufx.visual.PropertyTimelineHolder; +import com.annimon.hotarufx.visual.TimeLine; +import com.annimon.hotarufx.visual.visitors.NodeVisitor; +import javafx.scene.shape.Ellipse; +import static com.annimon.hotarufx.visual.PropertyType.NUMBER; + +public class EllipseNode extends ShapeNode { + + public final Ellipse ellipse; + + private PropertyTimelineHolder centerX, centerY, radiusX, radiusY; + + public EllipseNode() { + this(new Ellipse()); + } + + private EllipseNode(Ellipse ellipse) { + super(ellipse); + this.ellipse = ellipse; + centerX = PropertyTimelineHolder.empty(); + centerY = PropertyTimelineHolder.empty(); + radiusX = PropertyTimelineHolder.empty(); + radiusY = PropertyTimelineHolder.empty(); + } + + public PropertyTimeline centerXProperty() { + return centerX.setIfEmptyThenGet(ellipse::centerXProperty); + } + + public PropertyTimeline centerYProperty() { + return centerY.setIfEmptyThenGet(ellipse::centerYProperty); + } + + public PropertyTimeline radiusXProperty() { + return radiusX.setIfEmptyThenGet(ellipse::radiusXProperty); + } + + public PropertyTimeline radiusYProperty() { + return radiusY.setIfEmptyThenGet(ellipse::radiusYProperty); + } + + @Override + public void buildTimeline(TimeLine timeline) { + super.buildTimeline(timeline); + centerX.applyIfPresent(timeline); + centerY.applyIfPresent(timeline); + radiusX.applyIfPresent(timeline); + radiusY.applyIfPresent(timeline); + } + + @Override + public PropertyBindings propertyBindings(PropertyBindings bindings) { + return super.propertyBindings(bindings) + .add("cx", NUMBER, this::centerXProperty) + .add("centerX", NUMBER, this::centerXProperty) + .add("cy", NUMBER, this::centerYProperty) + .add("centerY", NUMBER, this::centerYProperty) + .add("radiusX", NUMBER, this::radiusXProperty) + .add("radiusY", NUMBER, this::radiusYProperty); + } + + @Override + public R accept(NodeVisitor visitor, T input) { + return visitor.visit(this, input); + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/visual/visitors/NodeVisitor.java b/app/src/main/java/com/annimon/hotarufx/visual/visitors/NodeVisitor.java index 010b743..494ed8c 100644 --- a/app/src/main/java/com/annimon/hotarufx/visual/visitors/NodeVisitor.java +++ b/app/src/main/java/com/annimon/hotarufx/visual/visitors/NodeVisitor.java @@ -1,6 +1,7 @@ package com.annimon.hotarufx.visual.visitors; import com.annimon.hotarufx.visual.objects.CircleNode; +import com.annimon.hotarufx.visual.objects.EllipseNode; import com.annimon.hotarufx.visual.objects.GroupNode; import com.annimon.hotarufx.visual.objects.LineNode; import com.annimon.hotarufx.visual.objects.PolygonNode; @@ -12,6 +13,7 @@ import com.annimon.hotarufx.visual.objects.TextNode; public interface NodeVisitor { R visit(CircleNode node, T input); + R visit(EllipseNode node, T input); R visit(GroupNode node, T input); R visit(LineNode node, T input); R visit(PolygonNode node, T input); diff --git a/app/src/main/java/com/annimon/hotarufx/visual/visitors/RenderVisitor.java b/app/src/main/java/com/annimon/hotarufx/visual/visitors/RenderVisitor.java index cf789e9..c68a390 100644 --- a/app/src/main/java/com/annimon/hotarufx/visual/visitors/RenderVisitor.java +++ b/app/src/main/java/com/annimon/hotarufx/visual/visitors/RenderVisitor.java @@ -2,15 +2,7 @@ package com.annimon.hotarufx.visual.visitors; import com.annimon.hotarufx.visual.TimeLine; import com.annimon.hotarufx.visual.VirtualScene; -import com.annimon.hotarufx.visual.objects.CircleNode; -import com.annimon.hotarufx.visual.objects.GroupNode; -import com.annimon.hotarufx.visual.objects.LineNode; -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.SVGPathNode; -import com.annimon.hotarufx.visual.objects.TextNode; +import com.annimon.hotarufx.visual.objects.*; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @@ -23,6 +15,11 @@ public class RenderVisitor implements NodeVisitor { return render(node, scene); } + @Override + public Void visit(EllipseNode node, VirtualScene scene) { + return render(node, scene); + } + @Override public Void visit(GroupNode group, VirtualScene scene) { render(group, scene);