/* * 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.models.impl; import java.util.ArrayList; import java.util.List; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleObjectProperty; import net.sf.latexdraw.models.MathUtils; import net.sf.latexdraw.models.ShapeFactory; import net.sf.latexdraw.models.interfaces.prop.IAxesProp; import net.sf.latexdraw.models.interfaces.shape.ArrowStyle; import net.sf.latexdraw.models.interfaces.shape.AxesStyle; import net.sf.latexdraw.models.interfaces.shape.IArrow; import net.sf.latexdraw.models.interfaces.shape.IAxes; import net.sf.latexdraw.models.interfaces.shape.ILine; import net.sf.latexdraw.models.interfaces.shape.IPoint; import net.sf.latexdraw.models.interfaces.shape.IShape; import net.sf.latexdraw.models.interfaces.shape.PlottingStyle; import net.sf.latexdraw.models.interfaces.shape.TicksStyle; import net.sf.latexdraw.view.pst.PSTricksConstants; /** * An implementation of axes. * @author Arnaud Blouin */ class LAxes extends LAbstractGrid implements IAxes, LArrowableShape { private final List<IArrow> arrows; /** The increment of X axe (Dx in PST). */ private final DoubleProperty incrementX; /** The increment of Y axe (Dy in PST). */ private final DoubleProperty incrementY; /** The distance between each label of the X axe; if 0, the default value will be used (in cm). */ private final DoubleProperty distLabelsX; /** The distance between each label of the Y axe; if 0, the default value will be used (in cm). */ private final DoubleProperty distLabelsY; /** Define which labels must be displayed. */ private final ObjectProperty<PlottingStyle> labelsDisplayed; /** Define the origin must be shown. */ private final BooleanProperty showOrigin; /** Define how the ticks must be shown. */ private final ObjectProperty<PlottingStyle> ticksDisplayed; /** Define the style of the ticks. */ private final ObjectProperty<TicksStyle> ticksStyle; /** The size of the ticks. */ private final DoubleProperty ticksSize; /** The style of the axes. */ private final ObjectProperty<AxesStyle> axesStyle; LAxes(final IPoint pt) { super(pt); arrows = new ArrayList<>(4); // The first arrow is for the bottom of the Y-axis. arrows.add(ShapeFactory.INST.createArrow(this)); // The second arrow is for the left of the X-axis. arrows.add(ShapeFactory.INST.createArrow(this)); // The third arrow is for the top of the Y-axis. arrows.add(ShapeFactory.INST.createArrow(this)); // The fourth arrow is for the right of the X-axis. arrows.add(ShapeFactory.INST.createArrow(this)); incrementX = new SimpleDoubleProperty(PSTricksConstants.DEFAULT_DX); incrementY = new SimpleDoubleProperty(PSTricksConstants.DEFAULT_DY); distLabelsX = new SimpleDoubleProperty(1.0); distLabelsY = new SimpleDoubleProperty(1.0); labelsDisplayed = new SimpleObjectProperty<>(PlottingStyle.ALL); showOrigin = new SimpleBooleanProperty(true); ticksDisplayed = new SimpleObjectProperty<>(PlottingStyle.ALL); ticksStyle = new SimpleObjectProperty<>(TicksStyle.FULL); ticksSize = new SimpleDoubleProperty(PSTricksConstants.DEFAULT_TICKS_SIZE * IShape.PPC); axesStyle = new SimpleObjectProperty<>(AxesStyle.AXES); } @Override public void copy(final IShape s) { super.copy(s); LArrowableShape.super.copy(s); if(s instanceof IAxesProp) { final IAxesProp axes = (IAxesProp) s; setTicksDisplayed(axes.getTicksDisplayed()); setTicksSize(axes.getTicksSize()); setTicksStyle(axes.getTicksStyle()); setAxesStyle(axes.getAxesStyle()); setShowOrigin(axes.isShowOrigin()); setDistLabelsX(axes.getDistLabelsX()); setDistLabelsY(axes.getDistLabelsY()); setIncrementX(axes.getIncrementX()); setIncrementY(axes.getIncrementY()); setLabelsDisplayed(axes.getLabelsDisplayed()); } } @Override public void setArrowStyle(ArrowStyle style, final int position) { final IArrow arr1 = getArrowAt(position); if(style != null && arr1 != null) { LArrowableShape.super.setArrowStyle(style, position); final int pos = (position == -1 ? arrows.size() - 1 : position) % 4; switch(pos) { case 0: arrows.get(1).setArrowStyle(style); break; case 1: arrows.get(0).setArrowStyle(style); break; case 2: arrows.get(3).setArrowStyle(style); break; case 3: arrows.get(2).setArrowStyle(style); break; } } } @Override public ILine getArrowLine(final IArrow arrow) { // For the X-axis if(arrow == arrows.get(1) || arrow == arrows.get(3)) { return getArrowLineX(arrow == arrows.get(1)); } // For the Y-axis. if(arrow == arrows.get(0) || arrow == arrows.get(2)) { return getArrowLineY(arrow == arrows.get(2)); } return null; } /** * @return The line of the Y-axis. */ private ILine getArrowLineY(final boolean topY) { final IPoint pos = getPosition(); final IPoint p2 = ShapeFactory.INST.createPoint(pos.getX(), pos.getY() - getGridEndY() * IShape.PPC); final IPoint p1 = ShapeFactory.INST.createPoint(pos.getX(), pos.getY() - getGridStartY() * IShape.PPC); if(topY) { return ShapeFactory.INST.createLine(p2, p1); } return ShapeFactory.INST.createLine(p1, p2); } /** * @return The line of the X-axis. */ private ILine getArrowLineX(final boolean leftX) { final IPoint pos = getPosition(); final IPoint p2 = ShapeFactory.INST.createPoint(pos.getX() + getGridEndX() * IShape.PPC, pos.getY()); final IPoint p1 = ShapeFactory.INST.createPoint(pos.getX() + getGridStartX() * IShape.PPC, pos.getY()); if(leftX) { return ShapeFactory.INST.createLine(p1, p2); } return ShapeFactory.INST.createLine(p2, p1); } @Override public AxesStyle getAxesStyle() { return axesStyle.getValue(); } @Override public double getDistLabelsX() { return distLabelsX.get(); } @Override public double getDistLabelsY() { return distLabelsY.get(); } @Override public PlottingStyle getLabelsDisplayed() { return labelsDisplayed.getValue(); } @Override public PlottingStyle getTicksDisplayed() { return ticksDisplayed.getValue(); } @Override public double getTicksSize() { return ticksSize.get(); } @Override public TicksStyle getTicksStyle() { return ticksStyle.getValue(); } @Override public boolean isShowOrigin() { return showOrigin.get(); } @Override public void setAxesStyle(final AxesStyle style) { if(style != null) { axesStyle.set(style); } } @Override public void setDistLabelsX(final double distX) { if(distX > 0.0 && MathUtils.INST.isValidCoord(distX)) { distLabelsX.set(distX); } } @Override public void setDistLabelsY(final double distY) { if(distY > 0.0 && MathUtils.INST.isValidCoord(distY)) { distLabelsY.set(distY); } } @Override public void setIncrementX(final double incr) { if(incr > 0.0 && MathUtils.INST.isValidCoord(incr)) { incrementX.set(incr); } } @Override public void setIncrementY(final double incr) { if(incr > 0.0 && MathUtils.INST.isValidCoord(incr)) { incrementY.set(incr); } } @Override public void setLabelsDisplayed(final PlottingStyle style) { if(style != null) { labelsDisplayed.set(style); } } @Override public void setShowOrigin(final boolean show) { showOrigin.set(show); } @Override public void setTicksDisplayed(final PlottingStyle style) { if(style != null) { ticksDisplayed.set(style); } } @Override public void setTicksSize(final double ticks) { if(ticks > 0.0 && MathUtils.INST.isValidCoord(ticks)) { ticksSize.set(ticks); } } @Override public void setTicksStyle(final TicksStyle style) { if(style != null) { ticksStyle.set(style); } } @Override public double getStep() { return IShape.PPC; } @Override public boolean isLineStylable() { return true; } @Override public boolean isThicknessable() { return true; } @Override public double getIncrementX() { return incrementX.get(); } @Override public double getIncrementY() { return incrementY.get(); } @Override public IPoint getIncrement() { return ShapeFactory.INST.createPoint(getIncrementX(), getIncrementY()); } @Override public void setIncrement(final IPoint increment) { if(increment != null) { setIncrementX(increment.getX()); setIncrementY(increment.getY()); } } @Override public IPoint getDistLabels() { return ShapeFactory.INST.createPoint(getDistLabelsX(), getDistLabelsY()); } @Override public void setDistLabels(final IPoint distLabels) { if(distLabels != null) { setDistLabelsX(distLabels.getX()); setDistLabelsY(distLabels.getY()); } } @Override public List<IArrow> getArrows() { return arrows; } @Override public DoubleProperty incrementXProperty() { return incrementX; } @Override public DoubleProperty incrementYProperty() { return incrementY; } @Override public DoubleProperty distLabelsXProperty() { return distLabelsX; } @Override public DoubleProperty distLabelsYProperty() { return distLabelsY; } @Override public ObjectProperty<PlottingStyle> labelsDisplayedProperty() { return labelsDisplayed; } @Override public BooleanProperty showOriginProperty() { return showOrigin; } @Override public ObjectProperty<PlottingStyle> ticksDisplayedProperty() { return ticksDisplayed; } @Override public ObjectProperty<TicksStyle> ticksStyleProperty() { return ticksStyle; } @Override public DoubleProperty ticksSizeProperty() { return ticksSize; } @Override public ObjectProperty<AxesStyle> axesStyleProperty() { return axesStyle; } }