Ability to set explicit dimensions of basic shapes - rectangles and ellipses

This commit is contained in:
Bane Stojkovic
2025-02-09 16:10:30 +01:00
parent 6ad5a5361c
commit e0aa7d99ee
9 changed files with 195 additions and 36 deletions
@@ -4441,7 +4441,11 @@
<org.diylc.appframework.update.Change> <org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType> <changeType>NEW_FEATURE</changeType>
<description>Added two types of 4PDT On/On/On Switches, e.g. DiMarzio EP1111 (thank you Lukasz Tekieli)</description> <description>Added two types of 4PDT On/On/On Switches, e.g. DiMarzio EP1111 (thank you Lukasz Tekieli)</description>
</org.diylc.appframework.update.Change> </org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Ability to set explicit dimensions of basic shapes - rectangles and ellipses</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change> <org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType> <changeType>IMPROVEMENT</changeType>
<description>Better rendering of the effective circuit graph in the guitar wiring analyzer, showing series and parallel connections in a more intuitive way</description> <description>Better rendering of the effective circuit graph in the guitar wiring analyzer, showing series and parallel connections in a more intuitive way</description>
Binary file not shown.
@@ -0,0 +1,21 @@
package org.diylc.components.boards;
import org.diylc.components.boards.AbstractBoard.BoardSizingMode;
import org.diylc.components.shapes.AbstractShapeWithDimensions;
import org.diylc.components.shapes.AbstractShapeWithDimensions.ShapeSizingMode;
import org.diylc.core.IPropertyValidator;
import org.diylc.core.ValidationException;
import org.diylc.core.measures.Size;
public class ShapeModeValidator implements IPropertyValidator {
public ShapeModeValidator() {}
@Override
public void validate(Object owner, Object value) throws ValidationException {
AbstractShapeWithDimensions board = (AbstractShapeWithDimensions)owner;
Size size = (Size)value;
if (board.getMode() == ShapeSizingMode.Explicit && (value == null || size.getValue() == null || size.getUnit() == null))
throw new ValidationException("Dimensions are required when mode is set to " + BoardSizingMode.Explicit);
}
}
@@ -1,33 +1,33 @@
/* /*
DIY Layout Creator (DIYLC). DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors. Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC. This file is part of DIYLC.
DIYLC is free software: you can redistribute it and/or modify DIYLC is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
DIYLC is distributed in the hope that it will be useful, DIYLC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>. along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.diylc.components.shapes; package org.diylc.components.shapes;
import java.awt.Color; import java.awt.Color;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import org.diylc.components.AbstractTransparentComponent; import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.VisibilityPolicy; import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty; import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator; import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
public abstract class AbstractShape extends AbstractTransparentComponent<Void> { public abstract class AbstractShape extends AbstractTransparentComponent<Void> {
@@ -103,11 +103,11 @@ public abstract class AbstractShape extends AbstractTransparentComponent<Void> {
Math.min(controlPoints[0].getY(), controlPoints[1].getY())); Math.min(controlPoints[0].getY(), controlPoints[1].getY()));
secondPoint.setLocation(Math.max(controlPoints[0].getX(), controlPoints[1].getX()), secondPoint.setLocation(Math.max(controlPoints[0].getX(), controlPoints[1].getX()),
Math.max(controlPoints[0].getY(), controlPoints[1].getY())); Math.max(controlPoints[0].getY(), controlPoints[1].getY()));
} }
@Override @Override
public String getControlPointNodeName(int index) { public String getControlPointNodeName(int index) {
return null; return null;
} }
@Deprecated @Deprecated
@@ -0,0 +1,134 @@
/*
DIY Layout Creator (DIYLC).
Copyright (c) 2009-2018 held jointly by the individual authors.
This file is part of DIYLC.
DIYLC 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 3 of the License, or
(at your option) any later version.
DIYLC is distributed in the hope that it will be useful,
but 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.
You should have received a copy of the GNU General Public License
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
*/
package org.diylc.components.shapes;
import java.awt.geom.Point2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.components.boards.ShapeModeValidator;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
public abstract class AbstractShapeWithDimensions extends AbstractShape {
private static final long serialVersionUID = 1L;
protected Size length;
protected Size width;
protected ShapeSizingMode mode = ShapeSizingMode.TwoPoints;
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return getMode() == ShapeSizingMode.TwoPoints ? VisibilityPolicy.WHEN_SELECTED : VisibilityPolicy.NEVER;
}
protected Point2D getFinalSecondPoint() {
Point2D finalSecondPoint;
if (getMode() == ShapeSizingMode.TwoPoints)
finalSecondPoint = secondPoint;
else
finalSecondPoint = new Point2D.Double(firstPoint.getX() + getLength().convertToPixels(),
firstPoint.getY() + getWidth().convertToPixels());
return finalSecondPoint;
}
@Override
public void setControlPoint(Point2D point, int index) {
controlPoints[index].setLocation(point);
firstPoint.setLocation(Math.min(controlPoints[0].getX(), controlPoints[1].getX()),
Math.min(controlPoints[0].getY(), controlPoints[1].getY()));
secondPoint.setLocation(Math.max(controlPoints[0].getX(), controlPoints[1].getX()),
Math.max(controlPoints[0].getY(), controlPoints[1].getY()));
}
@EditableProperty(name = "Dimension Mode")
public ShapeSizingMode getMode() {
if (mode == null)
mode = ShapeSizingMode.TwoPoints;
return mode;
}
public void setMode(ShapeSizingMode mode) {
this.mode = mode;
}
@EditableProperty(name = "Explicit Length", validatorClass = ShapeModeValidator.class)
public Size getLength() {
if (getMode() == ShapeSizingMode.TwoPoints) {
double lengthPx = Math.abs(this.firstPoint.getX() - this.secondPoint.getX());
this.length = Size.fromPixels(lengthPx, length == null ? getDefaultUnit() : length.getUnit());
}
return this.length;
}
public void setLength(Size length) {
if (getMode() == ShapeSizingMode.Explicit && length != null && width != null) {
setControlPoint(firstPoint, 0);
Point2D second = new Point2D.Double(firstPoint.getX() + length.convertToPixels(),
firstPoint.getY() + width.convertToPixels());
setControlPoint(second, 1);
}
this.length = length;
}
@EditableProperty(name = "Explicit Width", validatorClass = ShapeModeValidator.class)
public Size getWidth() {
if (getMode() == ShapeSizingMode.TwoPoints) {
double widthPx = Math.abs(this.firstPoint.getY() - this.secondPoint.getY());
this.width = Size.fromPixels(widthPx, width == null ? getDefaultUnit() : width.getUnit());
}
return this.width;
}
public void setWidth(Size width) {
if (getMode() == ShapeSizingMode.Explicit && length != null && width != null) {
setControlPoint(firstPoint, 0);
Point2D second = new Point2D.Double(firstPoint.getX() + length.convertToPixels(), firstPoint.getY() + width.convertToPixels());
setControlPoint(second, 1);
}
this.width = width;
}
private SizeUnit getDefaultUnit() {
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.METRIC_KEY, true))
return SizeUnit.mm;
return SizeUnit.in;
}
public static enum ShapeSizingMode {
TwoPoints("Opposing Points"), Explicit("Explicit Dimensions");
private String label;
private ShapeSizingMode(String label) {
this.label = label;
}
@Override
public String toString() {
return label;
}
}
}
@@ -36,7 +36,7 @@ import org.diylc.core.annotations.ComponentDescriptor;
@ComponentDescriptor(name = "Ellipse", author = "Branislav Stojkovic", category = "Shapes", instanceNamePrefix = "ELL", @ComponentDescriptor(name = "Ellipse", author = "Branislav Stojkovic", category = "Shapes", instanceNamePrefix = "ELL",
description = "Elliptical area", zOrder = IDIYComponent.COMPONENT, flexibleZOrder = true, description = "Elliptical area", zOrder = IDIYComponent.COMPONENT, flexibleZOrder = true,
bomPolicy = BomPolicy.SHOW_ALL_NAMES, autoEdit = false, transformer = SimpleComponentTransformer.class) bomPolicy = BomPolicy.SHOW_ALL_NAMES, autoEdit = false, transformer = SimpleComponentTransformer.class)
public class Ellipse extends AbstractShape { public class Ellipse extends AbstractShapeWithDimensions {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -40,7 +40,7 @@ import org.diylc.core.measures.SizeUnit;
instanceNamePrefix = "RECT", description = "Ractangular area, with or withouth rounded edges", instanceNamePrefix = "RECT", description = "Ractangular area, with or withouth rounded edges",
zOrder = IDIYComponent.COMPONENT, flexibleZOrder = true, bomPolicy = BomPolicy.SHOW_ALL_NAMES, autoEdit = false, zOrder = IDIYComponent.COMPONENT, flexibleZOrder = true, bomPolicy = BomPolicy.SHOW_ALL_NAMES, autoEdit = false,
transformer = SimpleComponentTransformer.class) transformer = SimpleComponentTransformer.class)
public class Rectangle extends AbstractShape { public class Rectangle extends AbstractShapeWithDimensions {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
Binary file not shown.
Binary file not shown.