From 3376aa995a8b5f6ac1f25080193a945bfd78724b Mon Sep 17 00:00:00 2001 From: Bane Stojkovic Date: Mon, 5 Jan 2026 21:10:10 +0100 Subject: [PATCH] 'Open 1/8" Jack' and 'Open 1/4" Jack' can be rotated --- .../diylc-core/src/main/resources/update.xml | 2 +- .../electromechanical/OpenJack1_4.java | 3 +- .../electromechanical/OpenJack1_8.java | 3 +- .../transform/OpenJackTransformer.java | 161 ++++++++++++++++++ 4 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 diylc/diylc-library/src/main/java/org/diylc/components/transform/OpenJackTransformer.java diff --git a/diylc/diylc-core/src/main/resources/update.xml b/diylc/diylc-core/src/main/resources/update.xml index 0c6b1b5e..a29ad09e 100644 --- a/diylc/diylc-core/src/main/resources/update.xml +++ b/diylc/diylc-core/src/main/resources/update.xml @@ -515,7 +515,7 @@ IMPROVEMENT - 'Cliff 1/8" Jack' can be rotated + 'Cliff 1/8" Jack', 'Open 1/8" Jack' and 'Open 1/4" Jack' can be rotated BUG_FIX diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/electromechanical/OpenJack1_4.java b/diylc/diylc-library/src/main/java/org/diylc/components/electromechanical/OpenJack1_4.java index 23c87ddf..6a57d056 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/electromechanical/OpenJack1_4.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/electromechanical/OpenJack1_4.java @@ -42,6 +42,7 @@ import org.diylc.common.Orientation; import org.diylc.common.VerticalAlignment; import org.diylc.components.AbstractMultiPartComponent; import org.diylc.components.electromechanical.OpenJack1_4.OpenJackType; +import org.diylc.components.transform.OpenJackTransformer; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; @@ -56,7 +57,7 @@ import org.diylc.utils.Constants; @ComponentDescriptor(name = "Open 1/4\" Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic", description = "Switchcraft-style open panel mount 1/4\" phono jack, stereo and mono", - zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J", enableCache = true) + zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J", transformer = OpenJackTransformer.class, enableCache = true) public class OpenJack1_4 extends AbstractMultiPartComponent { private static final float FONT_SCALE = 0.8f; diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/electromechanical/OpenJack1_8.java b/diylc/diylc-library/src/main/java/org/diylc/components/electromechanical/OpenJack1_8.java index e045b7fc..34b47f31 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/electromechanical/OpenJack1_8.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/electromechanical/OpenJack1_8.java @@ -42,6 +42,7 @@ import org.diylc.common.Orientation; import org.diylc.common.VerticalAlignment; import org.diylc.components.AbstractMultiPartComponent; import org.diylc.components.electromechanical.OpenJack1_8.OpenJackType; +import org.diylc.components.transform.OpenJackTransformer; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; @@ -56,7 +57,7 @@ import org.diylc.utils.Constants; @ComponentDescriptor(name = "Open 1/8\" Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic", description = "Switchcraft-style open panel mount 1/8\" phono jack, stereo and mono", - zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J", enableCache = true) + zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J", transformer = OpenJackTransformer.class, enableCache = true) public class OpenJack1_8 extends AbstractMultiPartComponent { private static final float FONT_SCALE = 0.6f; diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/transform/OpenJackTransformer.java b/diylc/diylc-library/src/main/java/org/diylc/components/transform/OpenJackTransformer.java new file mode 100644 index 00000000..01b371f8 --- /dev/null +++ b/diylc/diylc-library/src/main/java/org/diylc/components/transform/OpenJackTransformer.java @@ -0,0 +1,161 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2025 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 . + +*/ +package org.diylc.components.transform; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; + +import org.diylc.common.IComponentTransformer; +import org.diylc.components.electromechanical.OpenJack1_4; +import org.diylc.components.electromechanical.OpenJack1_8; +import org.diylc.core.IDIYComponent; + +public class OpenJackTransformer implements IComponentTransformer { + + @Override + public boolean canRotate(IDIYComponent component) { + return component.getClass().equals(OpenJack1_4.class) || component.getClass().equals(OpenJack1_8.class); + } + + @Override + public boolean canMirror(IDIYComponent component) { + return component.getClass().equals(OpenJack1_4.class) || component.getClass().equals(OpenJack1_8.class); + } + + @Override + public boolean mirroringChangesCircuit() { + return false; + } + + @Override + public void rotate(IDIYComponent component, Point2D center, int direction) { + AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2 * direction, center.getX(), center.getY()); + for (int index = 0; index < component.getControlPointCount(); index++) { + Point2D p = new Point2D.Double(); + rotate.transform(component.getControlPoint(index), p); + component.setControlPoint(p, index); + } + + Integer angle; + if (component instanceof OpenJack1_4) { + angle = ((OpenJack1_4) component).getAngle(); + } else if (component instanceof OpenJack1_8) { + angle = ((OpenJack1_8) component).getAngle(); + } else { + return; + } + + if (angle == null) { + angle = 0; + } + + int newAngle = angle + direction * 90; + // Normalize to 0-360 range + while (newAngle < 0) { + newAngle += 360; + } + while (newAngle >= 360) { + newAngle -= 360; + } + + if (component instanceof OpenJack1_4) { + ((OpenJack1_4) component).setAngle(newAngle); + } else if (component instanceof OpenJack1_8) { + ((OpenJack1_8) component).setAngle(newAngle); + } + } + + @Override + public void mirror(IDIYComponent component, Point2D center, int direction) { + if (!(component instanceof OpenJack1_4) && !(component instanceof OpenJack1_8)) { + return; + } + + IDIYComponent ic = component; + + if (direction == IComponentTransformer.HORIZONTAL) { + // Mirror control points horizontally + for (int i = 0; i < ic.getControlPointCount(); i++) { + Point2D p = ic.getControlPoint(i); + double dx = 2 * (center.getX() - p.getX()); + ic.setControlPoint(new Point2D.Double(p.getX() + dx, p.getY()), i); + } + + Integer angle; + if (component instanceof OpenJack1_4) { + angle = ((OpenJack1_4) component).getAngle(); + } else { + angle = ((OpenJack1_8) component).getAngle(); + } + + if (angle == null) { + angle = 0; + } + + // Mirror horizontally: reflect angle across vertical axis + int newAngle = 360 - angle; + while (newAngle >= 360) { + newAngle -= 360; + } + + if (component instanceof OpenJack1_4) { + ((OpenJack1_4) component).setAngle(newAngle); + } else { + ((OpenJack1_8) component).setAngle(newAngle); + } + } else { + // Mirror control points vertically + for (int i = 0; i < ic.getControlPointCount(); i++) { + Point2D p = ic.getControlPoint(i); + double dy = 2 * (center.getY() - p.getY()); + ic.setControlPoint(new Point2D.Double(p.getX(), p.getY() + dy), i); + } + + Integer angle; + if (component instanceof OpenJack1_4) { + angle = ((OpenJack1_4) component).getAngle(); + } else { + angle = ((OpenJack1_8) component).getAngle(); + } + + if (angle == null) { + angle = 0; + } + + // Mirror vertically: reflect angle across horizontal axis + int newAngle = 180 - angle; + while (newAngle < 0) { + newAngle += 360; + } + while (newAngle >= 360) { + newAngle -= 360; + } + + if (component instanceof OpenJack1_4) { + ((OpenJack1_4) component).setAngle(newAngle); + } else { + ((OpenJack1_8) component).setAngle(newAngle); + } + } + } +} +