Added new property in 'LP Switch' that allows having the middle terminals connected (as they were) or disconnected to allow more flexibility

This commit is contained in:
Bane Stojkovic
2025-12-29 10:55:45 +01:00
parent 9be97f5213
commit e9c8686960
3 changed files with 212 additions and 40 deletions
@@ -433,6 +433,10 @@
<changeType>NEW_FEATURE</changeType>
<description>Added 'Multiwatt IC' package with 11 and 15 pin varieties</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added new property in 'LP Switch' that allows having the middle terminals connected (as they were) or disconnected to allow more flexibility</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added 'Ending Style' property to 'Copper Trace' and 'Curved Trace' to allow choosing round or flat style</description>
@@ -63,15 +63,18 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
private static Size LENGTH = new Size(1.3d, SizeUnit.in);
private static Size BASE_LENGTH = new Size(18d, SizeUnit.mm);
private static Size WAFER_THICKNESS = new Size(0.05d, SizeUnit.in);
private static Size TERMINAL_SPACING = new Size(0.2d, SizeUnit.in);
private static Size TERMINAL_SPACING_CONNECTED = new Size(0.2d, SizeUnit.in);
private static Size TERMINAL_SPACING_DISCONNECTED = new Size(0.1d, SizeUnit.in);
private String value = "";
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0), new Point2D.Double(0, 0), new Point2D.Double(0, 0), new Point2D.Double(0, 0)};
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private MiddleTerminalConfiguration middleTerminalConfiguration;
public LPSwitch() {
super();
middleTerminalConfiguration = MiddleTerminalConfiguration.Connected;
updateControlPoints();
}
@@ -127,7 +130,7 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
g2d.setColor(finalBorderColor);
g2d.draw(body[1]);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(3));
g2d.setColor(METAL_COLOR);
drawingObserver.startTracking();
g2d.draw(body[2]);
@@ -178,24 +181,44 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
}
}
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
GeneralPath terminalPath = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
terminalPath.moveTo(x - waferThickness * 3 / 2, bodyY + 1);
terminalPath.lineTo(x - waferThickness * 3 / 2, bodyY + baseLength);
terminalPath.lineTo(x, y + length);
terminalPath.moveTo(x + waferThickness * 3 / 2, bodyY + 1);
terminalPath.lineTo(x + waferThickness * 3 / 2, bodyY + baseLength);
terminalPath.lineTo(x, y + length);
if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Connected) {
int terminalSpacing = (int) TERMINAL_SPACING_CONNECTED.convertToPixels();
terminalPath.moveTo(x - waferThickness * 3 / 2, bodyY + 1);
terminalPath.lineTo(x - waferThickness * 3 / 2, bodyY + baseLength);
terminalPath.lineTo(x, y + length);
terminalPath.moveTo(x - waferThickness * 5 / 2, bodyY + 1);
terminalPath.lineTo(x - waferThickness * 5 / 2, bodyY + baseLength);
terminalPath.lineTo(x - terminalSpacing, y + length);
terminalPath.moveTo(x + waferThickness * 3 / 2, bodyY + 1);
terminalPath.lineTo(x + waferThickness * 3 / 2, bodyY + baseLength);
terminalPath.lineTo(x, y + length);
terminalPath.moveTo(x + waferThickness * 5 / 2, bodyY + 1);
terminalPath.lineTo(x + waferThickness * 5 / 2, bodyY + baseLength);
terminalPath.lineTo(x + terminalSpacing, y + length);
terminalPath.moveTo(x - waferThickness * 5 / 2, bodyY + 1);
terminalPath.lineTo(x - waferThickness * 5 / 2, bodyY + baseLength);
terminalPath.lineTo(x - terminalSpacing, y + length);
terminalPath.moveTo(x + waferThickness * 5 / 2, bodyY + 1);
terminalPath.lineTo(x + waferThickness * 5 / 2, bodyY + baseLength);
terminalPath.lineTo(x + terminalSpacing, y + length);
} else {
int terminalSpacing = (int) TERMINAL_SPACING_DISCONNECTED.convertToPixels();
terminalPath.moveTo(x - waferThickness * 3 / 2, bodyY + 1);
terminalPath.lineTo(x - waferThickness * 3 / 2, bodyY + baseLength);
terminalPath.lineTo(x- terminalSpacing, y + length);
terminalPath.moveTo(x + waferThickness * 3 / 2, bodyY + 1);
terminalPath.lineTo(x + waferThickness * 3 / 2, bodyY + baseLength);
terminalPath.lineTo(x + terminalSpacing, y + length);
terminalPath.moveTo(x - waferThickness * 5 / 2, bodyY + 1);
terminalPath.lineTo(x - waferThickness * 5 / 2, bodyY + baseLength);
terminalPath.lineTo(x - terminalSpacing * 2, y + length);
terminalPath.moveTo(x + waferThickness * 5 / 2, bodyY + 1);
terminalPath.lineTo(x + waferThickness * 5 / 2, bodyY + baseLength);
terminalPath.lineTo(x + terminalSpacing * 2, y + length);
}
body[2] = terminalPath;
// Rotate if needed
@@ -219,14 +242,37 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
@SuppressWarnings("incomplete-switch")
private void updateControlPoints() {
Point2D[] newControlPoints = null;
if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Connected && controlPoints.length == 5) {
newControlPoints = new Point2D[4];
} else if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Disconnected && controlPoints.length == 4) {
newControlPoints = new Point2D[5];
newControlPoints[4] = new Point2D.Double();
}
if (newControlPoints != null) {
for (int i = 0; i < newControlPoints.length && i < controlPoints.length; i++) {
newControlPoints[i] = controlPoints[i];
}
controlPoints = newControlPoints;
}
double x = controlPoints[0].getX();
double y = controlPoints[0].getY();
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
int length = (int) LENGTH.convertToPixels();
controlPoints[1].setLocation(x - terminalSpacing, y + length);
controlPoints[2].setLocation(x, y + length);
controlPoints[3].setLocation(x + terminalSpacing, y + length);
if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Connected) {
int terminalSpacing = (int) TERMINAL_SPACING_CONNECTED.convertToPixels();
controlPoints[1].setLocation(x - terminalSpacing, y + length);
controlPoints[2].setLocation(x, y + length);
controlPoints[3].setLocation(x + terminalSpacing, y + length);
} else {
int terminalSpacing = (int) TERMINAL_SPACING_DISCONNECTED.convertToPixels();
controlPoints[1].setLocation(x - terminalSpacing * 2, y + length);
controlPoints[2].setLocation(x - terminalSpacing, y + length);
controlPoints[3].setLocation(x + terminalSpacing, y + length);
controlPoints[4].setLocation(x + terminalSpacing * 2, y + length);
}
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
@@ -331,8 +377,21 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
// Invalidate the body
body = null;
}
// @Override
@EditableProperty(name = "Middle Terminals")
public MiddleTerminalConfiguration getMiddleTerminalConfiguration() {
return middleTerminalConfiguration;
}
public void setMiddleTerminalConfiguration(
MiddleTerminalConfiguration middleTerminalConfiguration) {
this.middleTerminalConfiguration = middleTerminalConfiguration;
updateControlPoints();
// Invalidate the body
body = null;
}
// @Override
// public String getControlPointNodeName(int index) {
// // we don't want the switch to produce any nodes, it just makes connections
// return null;
@@ -347,27 +406,34 @@ public class LPSwitch extends AbstractTransparentComponent<String> implements IS
@Override
public String getPositionName(int position) {
switch (position) {
case 0:
return "Treble";
case 1:
return "Middle";
case 2:
return "Rhythm";
}
return null;
return switch (position) {
case 0 -> "Treble";
case 1 -> "Middle";
case 2 -> "Rhythm";
default -> null;
};
}
@Override
public boolean arePointsConnected(int index1, int index2, int position) {
switch (position) {
case 0:
return index1 == 1 && index2 == 2;
case 1:
return index1 > 0 && index2 > 0 && index1 < index2;
case 2:
return index1 == 2 && index2 == 3;
if (getMiddleTerminalConfiguration() == MiddleTerminalConfiguration.Connected) {
return switch (position) {
case 0 -> index1 == 1 && index2 == 2;
case 1 -> index1 > 0 && index2 > 0 && index1 < index2;
case 2 -> index1 == 2 && index2 == 3;
default -> false;
};
} else {
return switch (position) {
case 0 -> index1 == 1 && index2 == 2;
case 1 -> (index1 == 1 && index2 == 2) || (index1 == 3 && index2 == 4);
case 2 -> index1 == 3 && index2 == 4;
default -> false;
};
}
return false;
}
public enum MiddleTerminalConfiguration {
Connected, Disconnected
}
}
@@ -1,15 +1,117 @@
package org.diylc.netlist;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.Test;
import org.diylc.components.guitar.LPSwitch;
import org.diylc.components.guitar.LPSwitch.MiddleTerminalConfiguration;
import org.diylc.common.Orientation;
import org.diylc.core.IDIYComponent;
public class LPSwitchTests extends AbstractSwitchTests {
@Test
public void testLPSwitch() {
public void testLPSwitchConnected() {
LPSwitch lpSwitch = new LPSwitch();
// Default configuration is Connected
assertEquals(MiddleTerminalConfiguration.Connected, lpSwitch.getMiddleTerminalConfiguration());
// Connected has 4 control points (0, 1, 2, 3)
assertEquals(4, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
// Position 0 (Treble): 1-2 connected
// Position 1 (Middle): 1-2, 1-3, 2-3 connected (all terminals > 0 connected)
// Position 2 (Rhythm): 2-3 connected
String[] validCombinations = new String[] {"0,1,2", "1,1,2", "1,2,3", "1,1,3", "2,2,3"};
testSwitch(lpSwitch, validCombinations);
}
}
@Test
public void testLPSwitchDisconnected() {
LPSwitch lpSwitch = new LPSwitch();
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Disconnected);
assertEquals(MiddleTerminalConfiguration.Disconnected, lpSwitch.getMiddleTerminalConfiguration());
// Disconnected has 5 control points (0, 1, 2, 3, 4)
assertEquals(5, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
// Position 0 (Treble): 1-2 connected
// Position 1 (Middle): 1-2 and 3-4 connected (both pairs)
// Position 2 (Rhythm): 3-4 connected
String[] validCombinations = new String[] {"0,1,2", "1,1,2", "1,3,4", "2,3,4"};
testSwitch(lpSwitch, validCombinations);
}
@Test
public void testControlPointCountChange() {
LPSwitch lpSwitch = new LPSwitch();
// Start with Connected (4 points)
assertEquals(4, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
// Switch to Disconnected (5 points)
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Disconnected);
assertEquals(5, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
// Switch back to Connected (4 points)
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Connected);
assertEquals(4, ((IDIYComponent<?>) lpSwitch).getControlPointCount());
}
@Test
public void testPositionNames() {
LPSwitch lpSwitch = new LPSwitch();
assertEquals(3, lpSwitch.getPositionCount());
assertEquals("Treble", lpSwitch.getPositionName(0));
assertEquals("Middle", lpSwitch.getPositionName(1));
assertEquals("Rhythm", lpSwitch.getPositionName(2));
assertNull(lpSwitch.getPositionName(3)); // Invalid position
assertNull(lpSwitch.getPositionName(-1)); // Invalid position
}
@Test
public void testOrientationDoesNotAffectConnectivity() {
LPSwitch lpSwitch = new LPSwitch();
// Test with default Connected configuration
String[] validCombinations = new String[] {"0,1,2", "1,1,2", "1,2,3", "1,1,3", "2,2,3"};
// Test all orientations - connectivity should remain the same
for (Orientation orientation : Orientation.values()) {
lpSwitch.setOrientation(orientation);
assertEquals(orientation, lpSwitch.getOrientation());
// Connectivity should be unchanged regardless of orientation
testSwitch(lpSwitch, validCombinations);
}
}
@Test
public void testOrientationWithDisconnectedConfiguration() {
LPSwitch lpSwitch = new LPSwitch();
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Disconnected);
String[] validCombinations = new String[] {"0,1,2", "1,1,2", "1,3,4", "2,3,4"};
// Test all orientations with Disconnected configuration
for (Orientation orientation : Orientation.values()) {
lpSwitch.setOrientation(orientation);
assertEquals(orientation, lpSwitch.getOrientation());
// Connectivity should be unchanged regardless of orientation
testSwitch(lpSwitch, validCombinations);
}
}
@Test
public void testConfigurationSwitchPreservesConnectivity() {
LPSwitch lpSwitch = new LPSwitch();
// Test Connected configuration
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Connected);
String[] connectedCombinations = new String[] {"0,1,2", "1,1,2", "1,2,3", "1,1,3", "2,2,3"};
testSwitch(lpSwitch, connectedCombinations);
// Switch to Disconnected
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Disconnected);
String[] disconnectedCombinations = new String[] {"0,1,2", "1,1,2", "1,3,4", "2,3,4"};
testSwitch(lpSwitch, disconnectedCombinations);
// Switch back to Connected
lpSwitch.setMiddleTerminalConfiguration(MiddleTerminalConfiguration.Connected);
testSwitch(lpSwitch, connectedCombinations);
}
}