/* * This file is part of LaTeXDraw. * Copyright (c) 2005-2017 Arnaud BLOUIN * LaTeXDraw is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later version. * LaTeXDraw is distributed without any warranty; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ package net.sf.latexdraw.view.jfx; import java.util.Optional; import javafx.scene.shape.ClosePath; import javafx.scene.shape.CubicCurveTo; import javafx.scene.shape.LineTo; import javafx.scene.shape.MoveTo; import javafx.scene.shape.PathElement; import net.sf.latexdraw.models.MathUtils; import net.sf.latexdraw.models.interfaces.shape.IAxes; import net.sf.latexdraw.models.interfaces.shape.IBezierCurve; import net.sf.latexdraw.models.interfaces.shape.ICircle; import net.sf.latexdraw.models.interfaces.shape.ICircleArc; import net.sf.latexdraw.models.interfaces.shape.IDot; import net.sf.latexdraw.models.interfaces.shape.IEllipse; import net.sf.latexdraw.models.interfaces.shape.IFreehand; import net.sf.latexdraw.models.interfaces.shape.IGrid; import net.sf.latexdraw.models.interfaces.shape.IGroup; import net.sf.latexdraw.models.interfaces.shape.IPicture; import net.sf.latexdraw.models.interfaces.shape.IPlot; import net.sf.latexdraw.models.interfaces.shape.IPolygon; import net.sf.latexdraw.models.interfaces.shape.IPolyline; import net.sf.latexdraw.models.interfaces.shape.IRectangle; import net.sf.latexdraw.models.interfaces.shape.IRhombus; import net.sf.latexdraw.models.interfaces.shape.IShape; import net.sf.latexdraw.models.interfaces.shape.ISquare; import net.sf.latexdraw.models.interfaces.shape.IText; import net.sf.latexdraw.models.interfaces.shape.ITriangle; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; /** * The factory that creates views from given models. * @author Arnaud Blouin */ @NonNullByDefault public final class ViewFactory { /** The singleton. */ public static final ViewFactory INSTANCE = new ViewFactory(); private ViewFactory() { super(); } /** * Creates a view from a shape. * @param shape The shape used to create the view. * @return The created view or empty. * @since 3.0 */ public <T extends IShape, S extends ViewShape<T>> Optional<S> createView(final @Nullable T shape) { if(shape instanceof IGroup) return Optional.of((S) new ViewGroup((IGroup) shape)); if(shape instanceof IPlot) return Optional.of((S) new ViewPlot((IPlot) shape)); if(shape instanceof ISquare) return Optional.of((S) new ViewSquare((ISquare) shape)); if(shape instanceof IRectangle) return Optional.of((S) new ViewRectangle((IRectangle) shape)); if(shape instanceof IText) return Optional.of((S) new ViewText((IText) shape)); if(shape instanceof ICircleArc) return Optional.of((S) new ViewCircleArc((ICircleArc) shape)); if(shape instanceof ICircle) return Optional.of((S) new ViewCircle((ICircle) shape)); if(shape instanceof IEllipse) return Optional.of((S) new ViewEllipse((IEllipse) shape)); if(shape instanceof ITriangle) return Optional.of((S) new ViewTriangle((ITriangle) shape)); if(shape instanceof IRhombus) return Optional.of((S) new ViewRhombus((IRhombus) shape)); if(shape instanceof IPolyline) return Optional.of((S) new ViewPolyline((IPolyline) shape)); if(shape instanceof IPolygon) return Optional.of((S) new ViewPolygon((IPolygon) shape)); if(shape instanceof IBezierCurve) return Optional.of((S) new ViewBezierCurve((IBezierCurve) shape)); if(shape instanceof IAxes) return Optional.of((S) new ViewAxes((IAxes) shape)); if(shape instanceof IGrid) return Optional.of((S) new ViewGrid((IGrid) shape)); if(shape instanceof IDot) return Optional.of((S) new ViewDot((IDot) shape)); if(shape instanceof IPicture) return Optional.of((S) new ViewPicture((IPicture) shape)); if(shape instanceof IFreehand) return Optional.of((S) new ViewFreeHand((IFreehand) shape)); return Optional.empty(); } public void flushPathElement(final PathElement elt) { if(elt instanceof LineTo) { final LineTo lineTo = (LineTo) elt; lineTo.xProperty().unbind(); lineTo.yProperty().unbind(); }else if(elt instanceof MoveTo) { final MoveTo moveTo = (MoveTo) elt; moveTo.xProperty().unbind(); moveTo.yProperty().unbind(); }else if(elt instanceof CubicCurveTo) { final CubicCurveTo cct = (CubicCurveTo) elt; cct.xProperty().unbind(); cct.yProperty().unbind(); cct.controlX1Property().unbind(); cct.controlX2Property().unbind(); cct.controlY1Property().unbind(); cct.controlY2Property().unbind(); } } public LineTo createLineTo(final double x, final double y) { return new EqLineTo(x, y); } public MoveTo createMoveTo(final double x, final double y) { return new EqMoveTo(x, y); } public ClosePath createClosePath() { return new EqClosePath(); } public CubicCurveTo createCubicCurveTo(final double controlX1, final double controlY1, final double controlX2, final double controlY2, final double x, final double y) { return new EqCubicCurveTo(controlX1, controlY1, controlX2, controlY2, x, y); } private static class EqCubicCurveTo extends CubicCurveTo { EqCubicCurveTo(final double controlX1, final double controlY1, final double controlX2, final double controlY2, final double x, final double y) { super(controlX1, controlY1, controlX2, controlY2, x, y); } @Override public boolean equals(final Object o) { if(this == o) return true; if(o == null || getClass() != o.getClass()) return false; EqCubicCurveTo that = (EqCubicCurveTo) o; if(Double.compare(that.getControlX1(), getControlX1()) != 0) return false; if(Double.compare(that.getControlY1(), getControlY1()) != 0) return false; if(Double.compare(that.getControlX2(), getControlX2()) != 0) return false; if(Double.compare(that.getControlY2(), getControlY2()) != 0) return false; if(Double.compare(that.getX(), getX()) != 0) return false; return Double.compare(that.getY(), getY()) == 0; } @Override public int hashCode() { int result; long temp; temp = Double.doubleToLongBits(getControlX1()); result = (int) (temp ^ temp >>> 32); temp = Double.doubleToLongBits(getControlY1()); result = 31 * result + (int) (temp ^ temp >>> 32); temp = Double.doubleToLongBits(getControlX2()); result = 31 * result + (int) (temp ^ temp >>> 32); temp = Double.doubleToLongBits(getControlY2()); result = 31 * result + (int) (temp ^ temp >>> 32); temp = Double.doubleToLongBits(getX()); result = 31 * result + (int) (temp ^ temp >>> 32); temp = Double.doubleToLongBits(getY()); result = 31 * result + (int) (temp ^ temp >>> 32); return result; } } private static class EqClosePath extends ClosePath { @Override public boolean equals(final Object obj) { return obj != null && (obj == this || obj instanceof ClosePath); } } private static class EqLineTo extends LineTo { EqLineTo(final double x, final double y) { super(x, y); } @Override public int hashCode() { int result; long temp = Double.doubleToLongBits(getX()); result = (int) (temp ^ temp >>> 32); temp = Double.doubleToLongBits(getY()); result = 31 * result + (int) (temp ^ temp >>> 32); result = 31 * result + (isAbsolute() ? 1 : 0); return result; } @Override public boolean equals(final Object obj) { if(obj == null) return false; if(obj == this) return true; if(!(obj instanceof LineTo)) return false; final LineTo lt = (LineTo) obj; return MathUtils.INST.equalsDouble(lt.getX(), getX()) && MathUtils.INST.equalsDouble(lt.getY(), getY()) && lt.isAbsolute() == isAbsolute(); } } private static class EqMoveTo extends MoveTo { EqMoveTo(final double x, final double y) { super(x, y); } @Override public int hashCode() { int result; long temp = Double.doubleToLongBits(getX()); result = (int) (temp ^ temp >>> 32); temp = Double.doubleToLongBits(getY()); result = 31 * result + (int) (temp ^ temp >>> 32); result = 31 * result + (isAbsolute() ? 1 : 0); return result; } @Override public boolean equals(final Object obj) { if(obj == null) return false; if(obj == this) return true; if(!(obj instanceof MoveTo)) return false; final MoveTo mt = (MoveTo) obj; return MathUtils.INST.equalsDouble(mt.getX(), getX()) && MathUtils.INST.equalsDouble(mt.getY(), getY()) && mt.isAbsolute() == isAbsolute(); } } }