/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.arakhne.afc.math.geometry.d2.dfx; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ReadOnlyDoubleProperty; import org.eclipse.xtext.xbase.lib.Pure; import org.arakhne.afc.math.geometry.MathFXAttributeNames; import org.arakhne.afc.math.geometry.d2.Point2D; import org.arakhne.afc.math.geometry.d2.afp.RectangularShape2afp; import org.arakhne.afc.math.geometry.d2.afp.RoundRectangle2afp; import org.arakhne.afc.vmutil.asserts.AssertMessages; /** Round rectangle with 2 double precision floating-point FX properties. * * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ * @since 13.0 */ public class RoundRectangle2dfx extends AbstractRectangularShape2dfx<RoundRectangle2dfx> implements RoundRectangle2afp<Shape2dfx<?>, RoundRectangle2dfx, PathElement2dfx, Point2dfx, Vector2dfx, Rectangle2dfx> { private static final long serialVersionUID = -2020546629513913417L; private DoubleProperty arcWidth; private DoubleProperty arcHeight; /** Construct an empty round rectangle. */ public RoundRectangle2dfx() { super(); } /** * @param min is the min corner of the rectangle. * @param max is the max corner of the rectangle. * @param arcWidth the width of the arcs. * @param arcHeight the height of the arcs. */ public RoundRectangle2dfx(Point2D<?, ?> min, Point2D<?, ?> max, double arcWidth, double arcHeight) { this(min.getX(), min.getY(), max.getX(), max.getY(), arcWidth, arcHeight); } /** Constructor by copy. * @param shape the shape to copy. */ public RoundRectangle2dfx(RoundRectangle2afp<?, ?, ?, ?, ?, ?> shape) { this(shape.getMinX(), shape.getMinY(), shape.getMaxX(), shape.getMaxY(), shape.getArcWidth(), shape.getArcHeight()); } /** Constructor by copy. * @param shape the shape to copy. */ public RoundRectangle2dfx(RectangularShape2afp<?, ?, ?, ?, ?, ?> shape) { this(shape.getMinX(), shape.getMinY(), shape.getMaxX(), shape.getMaxY(), 0, 0); } /** Construct a round rectangle. * @param x x coordinate of the minimum corner. * @param y y coordinate of the minimum corner. * @param width width of the rectangle. * @param height height of the rectangle. * @param arcWidth width of the arcs. * @param arcHeight height of the arcs. */ public RoundRectangle2dfx(double x, double y, double width, double height, double arcWidth, double arcHeight) { set(x, y, width, height, arcWidth, arcHeight); } @Override public RoundRectangle2dfx clone() { final RoundRectangle2dfx clone = super.clone(); if (clone.arcWidth != null) { clone.arcWidth = null; clone.arcWidthProperty().set(getArcWidth()); } if (clone.arcHeight != null) { clone.arcHeight = null; clone.arcHeightProperty().set(getArcHeight()); } return clone; } @Pure @Override public int hashCode() { int bits = super.hashCode(); bits = 31 * bits + Double.hashCode(getArcWidth()); bits = 31 * bits + Double.hashCode(getArcHeight()); return bits ^ (bits >> 31); } @Pure @Override public double getArcWidth() { return this.arcWidth == null ? 0 : this.arcWidth.get(); } /** Replies the property for the arc width. * * @return the arcWidth property. */ public DoubleProperty arcWidthProperty() { if (this.arcWidth == null) { this.arcWidth = new DependentSimpleDoubleProperty<ReadOnlyDoubleProperty>( this, MathFXAttributeNames.ARC_WIDTH, widthProperty()) { @Override protected void invalidated(ReadOnlyDoubleProperty dependency) { final double value = get(); if (value < 0.) { set(0.); } else { final double maxArcWidth = dependency.get() / 2.; if (value > maxArcWidth) { set(maxArcWidth); } } } }; } return this.arcWidth; } @Pure @Override public double getArcHeight() { return this.arcHeight == null ? 0 : this.arcHeight.get(); } /** Replies the property for the arc height. * * @return the arcHeight property. */ public DoubleProperty arcHeightProperty() { if (this.arcHeight == null) { this.arcHeight = new DependentSimpleDoubleProperty<ReadOnlyDoubleProperty>( this, MathFXAttributeNames.ARC_HEIGHT, heightProperty()) { @Override protected void invalidated(ReadOnlyDoubleProperty dependency) { final double value = get(); if (value < 0.) { set(0.); } else { final double maxArcHeight = dependency.get() / 2.; if (value > maxArcHeight) { set(maxArcHeight); } } } }; } return this.arcHeight; } @Override public void setArcWidth(double arcWidth) { assert arcWidth >= 0. : AssertMessages.positiveOrZeroParameter(); arcWidthProperty().set(arcWidth); } @Override public void setArcHeight(double arcHeight) { assert arcHeight >= 0. : AssertMessages.positiveOrZeroParameter(); arcHeightProperty().set(arcHeight); } @Override public void setFromCorners(double x1, double y1, double x2, double y2) { final double arcWidth = getArcWidth(); final double arcHeight = getArcHeight(); setFromCorners(x1, y1, x2, y2, arcWidth, arcHeight); } @Override @SuppressWarnings("checkstyle:magicnumber") public void setFromCorners(double x1, double y1, double x2, double y2, double arcWidth, double arcHeight) { assert arcWidth >= 0. : AssertMessages.positiveOrZeroParameter(4); assert arcHeight >= 0. : AssertMessages.positiveOrZeroParameter(5); if (x1 <= x2) { minXProperty().set(x1); maxXProperty().set(x2); } else { minXProperty().set(x2); maxXProperty().set(x1); } if (y1 <= y2) { minYProperty().set(y1); maxYProperty().set(y2); } else { minYProperty().set(y2); maxYProperty().set(y1); } setArcWidth(arcWidth); setArcHeight(arcHeight); } }