diff --git a/diylc/diylc-core/src/org/diylc/components/transform/DefaultTransformer.java b/diylc/diylc-core/src/org/diylc/components/transform/DefaultTransformer.java new file mode 100644 index 00000000..2761e708 --- /dev/null +++ b/diylc/diylc-core/src/org/diylc/components/transform/DefaultTransformer.java @@ -0,0 +1,33 @@ +package org.diylc.components.transform; + +import java.awt.Point; + +import org.diylc.common.IComponentTransformer; +import org.diylc.core.IDIYComponent; + +public class DefaultTransformer implements IComponentTransformer { + + @Override + public boolean canRotate(IDIYComponent component) { + return false; + } + + @Override + public boolean canMirror(IDIYComponent component) { + return false; + } + + @Override + public boolean mirroringChangesCircuit() { + return false; + } + + @Override + public void rotate(IDIYComponent component, Point center, int direction) { + } + + @Override + public void mirror(IDIYComponent component, Point center, int direction) { + } + +} diff --git a/diylc/diylc-core/src/org/diylc/components/transform/LeadedComponentTransformer.java b/diylc/diylc-core/src/org/diylc/components/transform/LeadedComponentTransformer.java new file mode 100644 index 00000000..dd77e1d2 --- /dev/null +++ b/diylc/diylc-core/src/org/diylc/components/transform/LeadedComponentTransformer.java @@ -0,0 +1,48 @@ +package org.diylc.components.transform; + +import java.awt.Point; +import java.awt.geom.AffineTransform; + +import org.diylc.common.IComponentTransformer; +import org.diylc.core.IDIYComponent; + +public class LeadedComponentTransformer implements IComponentTransformer { + + @Override + public boolean canRotate(IDIYComponent component) { + return true; + } + + @Override + public boolean canMirror(IDIYComponent component) { + return true; + } + + @Override + public boolean mirroringChangesCircuit() { + return false; + } + + @Override + public void rotate(IDIYComponent component, Point center, int direction) { + AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2 * direction, center.x, center.y); + for (int index = 0; index < component.getControlPointCount(); index++) { + Point p = new Point(component.getControlPoint(index)); + rotate.transform(p, p); + component.setControlPoint(p, index); + } + } + + @Override + public void mirror(IDIYComponent component, Point center, int direction) { + for (int i = 0; i < component.getControlPointCount(); i++) { + Point p = component.getControlPoint(i); + if (direction == IComponentTransformer.HORIZONTAL) { + component.setControlPoint(new Point(p.x - 2 * (p.x - center.x), p.y), i); + } else { + component.setControlPoint(new Point(p.x, p.y - 2 * (p.y - center.y)), i); + } + } + } + +} diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index eb2e6cb1..8a7d81ee 100644 Binary files a/diylc/diylc-library/lib/diylc-core.jar and b/diylc/diylc-library/lib/diylc-core.jar differ diff --git a/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java b/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java index 6e6e0ad7..79701a32 100644 --- a/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java +++ b/diylc/diylc-library/src/org/diylc/components/tube/TubeSocket.java @@ -34,7 +34,7 @@ public class TubeSocket extends AbstractTransparentComponent { private static final long serialVersionUID = 1L; - private static Color BODY_COLOR = Color.decode("#FFFFE0"); + private static Color BODY_COLOR = Color.decode("#F7F7EF"); private static Color BORDER_COLOR = Color.decode("#8E8E38"); public static Color PIN_COLOR = Color.decode("#00B2EE"); public static Color PIN_BORDER_COLOR = PIN_COLOR.darker(); @@ -44,8 +44,9 @@ public class TubeSocket extends AbstractTransparentComponent { private Base base = Base.B9A; private String type = ""; - private Orientation orientation = Orientation.DEFAULT; + private Orientation orientation; // private Mount mount = Mount.CHASSIS; + private int angle; private Point[] controlPoints = new Point[] {new Point(0, 0)}; @@ -67,14 +68,41 @@ public class TubeSocket extends AbstractTransparentComponent { // Reset body shape body = null; } +// +// @EditableProperty +// public Orientation getOrientation() { +// return orientation; +// } +// +// public void setOrientation(Orientation orientation) { +// this.orientation = orientation; +// updateControlPoints(); +// // Reset body shape +// body = null; +// } @EditableProperty - public Orientation getOrientation() { - return orientation; + @SuppressWarnings("incomplete-switch") + public int getAngle() { + if (orientation != null) { + switch (orientation) { + case _90: + angle = 90; + break; + case _180: + angle = 180; + break; + case _270: + angle = 270; + break; + } + orientation = null; + } + return angle; } - public void setOrientation(Orientation orientation) { - this.orientation = orientation; + public void setAngle(int angle) { + this.angle = angle; updateControlPoints(); // Reset body shape body = null; @@ -115,31 +143,15 @@ public class TubeSocket extends AbstractTransparentComponent { } double angleIncrement = Math.PI * 2 / (hasEmptySpace ? (pinCount + 1) : pinCount); double initialAngleOffset = hasEmptySpace ? angleIncrement : (angleIncrement / 2); - double initialAngle; - switch (orientation) { - case DEFAULT: - initialAngle = Math.PI / 2 + initialAngleOffset; - break; - case _90: - initialAngle = Math.PI + initialAngleOffset; - break; - case _180: - initialAngle = 3 * Math.PI / 2 + initialAngleOffset; - break; - case _270: - initialAngle = initialAngleOffset; - break; - default: - throw new RuntimeException("Unexpected orientation: " + orientation); - } + controlPoints = new Point[pinCount + 1]; - double angle = initialAngle; + double theta = initialAngleOffset + Math.toRadians(getAngle()); controlPoints[0] = firstPoint; for (int i = 0; i < pinCount; i++) { controlPoints[i + 1] = - new Point((int) (firstPoint.getX() + Math.cos(angle) * pinCircleDiameter / 2), - (int) (firstPoint.getY() + Math.sin(angle) * pinCircleDiameter / 2)); - angle += angleIncrement; + new Point((int) (firstPoint.getX() + Math.cos(theta) * pinCircleDiameter / 2), + (int) (firstPoint.getY() + Math.sin(theta) * pinCircleDiameter / 2)); + theta += angleIncrement; } } @@ -168,23 +180,9 @@ public class TubeSocket extends AbstractTransparentComponent { / 2, holeSize, holeSize))); if (base == Base.OCTAL) { int tickSize = getClosestOdd(TICK_SIZE.convertToPixels()); - double angle = 0; - switch (orientation) { - case DEFAULT: - angle = Math.PI / 2; - break; - case _90: - angle = Math.PI; - break; - case _180: - angle = 3 * Math.PI / 2; - break; - case _270: - angle = 0; - break; - } - int centerX = (int) (controlPoints[0].x + Math.cos(angle) * holeSize / 2); - int centerY = (int) (controlPoints[0].y + Math.sin(angle) * holeSize / 2); + double theta = Math.toRadians(getAngle()); + int centerX = (int) (controlPoints[0].x + Math.cos(theta) * holeSize / 2); + int centerY = (int) (controlPoints[0].y + Math.sin(theta) * holeSize / 2); bodyArea.subtract(new Area(new Ellipse2D.Double(centerX - tickSize / 2, centerY - tickSize / 2, tickSize, tickSize))); } diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index eb2e6cb1..8a7d81ee 100644 Binary files a/diylc/diylc-swing/lib/diylc-core.jar and b/diylc/diylc-swing/lib/diylc-core.jar differ diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index 4055b5c0..b2c10f84 100644 Binary files a/diylc/diylc-swing/library/main.jar and b/diylc/diylc-swing/library/main.jar differ diff --git a/diylc/diylc-swing/update.xml b/diylc/diylc-swing/update.xml index 78789dd4..4727a798 100644 --- a/diylc/diylc-swing/update.xml +++ b/diylc/diylc-swing/update.xml @@ -1561,14 +1561,18 @@ NEW_FEATURE Show/hide the grid - + + + IMPROVEMENT + Ability to rotate tube sockets for arbitrary angle + IMPROVEMENT Applying a template shouldn't affect component placement IMPROVEMENT - Improved rotation and mirroring of multiple components + Improved rotation and mirroring of multiple components at the same time https://github.com/bancika/diy-layout-creator/releases