mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-08 04:44:55 +10:00
Compare commits
17 Commits
v5.6.0
...
dark-theme
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d8bf5471a | |||
| 6fa0e7d56a | |||
| 12726338ef | |||
| f3a8e3cfb1 | |||
| 1ac8ba8a24 | |||
| 7b5bb3a152 | |||
| ce7753744a | |||
| 3adaa16537 | |||
| aa4f4c9c66 | |||
| ef01d52905 | |||
| 892de712b2 | |||
| 79aa25f14c | |||
| 165b61329c | |||
| c251e5ace2 | |||
| 550e221265 | |||
| 7110897e9d | |||
| 74badd8a01 |
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.diylc</groupId>
|
||||
<artifactId>diylc-parent</artifactId>
|
||||
<version>5.6.0</version>
|
||||
<version>5.7.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>diylc-core</artifactId>
|
||||
|
||||
@@ -380,5 +380,61 @@
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>7</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2025-12-21 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added '6P5T (5-Position 6 Pole AxLabs)' lever switch type (thank you mm-rnd)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added '4P3T (3-Position 4 Pole AxLabs)' lever switch type (thank you mm-rnd)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added 'DP3T (Import 5-Position 2502N)' lever switch type (thank you mm-rnd)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Corrected 'S1 Switch' up/down position designators (thank you mm-rnd)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Corrected 'Mini Toggle Switch' position names for center-OFF variants to be in the correct order (thank you mm-rnd)</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>'Drill Hole' changes color to red when selected</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>5</major>
|
||||
<minor>8</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2025-12-21 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved sensitivity of 'Multimeter Probe' that required pixel-level precision to detect connectivity; improved rendering of the probe in outline mode</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Fixed underside rendering and mirroring position issues that affected only SPDT 'Mini Toggle Switch' types</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
</a>
|
||||
</java.util.Arrays_-ArrayList>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.diylc</groupId>
|
||||
<artifactId>diylc-parent</artifactId>
|
||||
<version>5.6.0</version>
|
||||
<version>5.7.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>diylc-library</artifactId>
|
||||
|
||||
+46
-24
@@ -28,21 +28,20 @@ import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.Orientation45;
|
||||
import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.*;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "Multimeter Probe", category = "Connectivity",
|
||||
author = "Branislav Stojkovic", description = "Multimeter Probe", instanceNamePrefix = "Probe",
|
||||
@@ -59,6 +58,7 @@ public class MultimeterProbe extends AbstractTransparentComponent<Color> {
|
||||
public static Size HANDLE_DIAMETER = new Size(0.2d, SizeUnit.in);
|
||||
public static Size HANDLE_LENGTH = new Size(0.4d, SizeUnit.in);
|
||||
public static Color HANDLE_COLOR = Color.red;
|
||||
public static Size SENSITIVITY = new Size(0.05d, SizeUnit.in);
|
||||
|
||||
private Point2D.Double point = new Point2D.Double(0, 0);
|
||||
private Color handleColor = HANDLE_COLOR;
|
||||
@@ -77,27 +77,49 @@ public class MultimeterProbe extends AbstractTransparentComponent<Color> {
|
||||
Shape[] shapes = getBody();
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
|
||||
|
||||
if (!outlineMode) {
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(
|
||||
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(PROBE_COLOR);
|
||||
g2d.fill(shapes[0]);
|
||||
g2d.setColor(handleColor);
|
||||
g2d.fill(shapes[1]);
|
||||
g2d.setComposite(oldComposite);
|
||||
// draw an invisible conductive circle around the point to increase sensitivity
|
||||
g2d.setColor(Constants.TRANSPARENT_COLOR);
|
||||
drawingObserver.startTrackingContinuityArea(true);
|
||||
double sensitivity = SENSITIVITY.convertToPixels();
|
||||
g2d.fillOval((int) (point.getX() - sensitivity), (int) (point.getY() - sensitivity),
|
||||
(int) (sensitivity * 2), (int) (sensitivity * 2));
|
||||
drawingObserver.stopTrackingContinuityArea();
|
||||
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(
|
||||
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(
|
||||
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? SELECTION_COLOR
|
||||
: handleColor.darker());
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : PROBE_COLOR);
|
||||
g2d.fill(shapes[0]);
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : handleColor);
|
||||
g2d.fill(shapes[1]);
|
||||
g2d.setComposite(oldComposite);
|
||||
drawingObserver.stopTracking();
|
||||
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY,
|
||||
Constants.DEFAULT_THEME);
|
||||
|
||||
Color handleBorderColor;
|
||||
if (outlineMode) {
|
||||
handleBorderColor = theme.getOutlineColor();
|
||||
} else {
|
||||
handleBorderColor = componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? SELECTION_COLOR
|
||||
: handleColor.darker();
|
||||
}
|
||||
g2d.setColor(handleBorderColor);
|
||||
g2d.draw(shapes[1]);
|
||||
g2d.setColor(
|
||||
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? SELECTION_COLOR
|
||||
: PROBE_COLOR.darker());
|
||||
|
||||
Color probeBorderColor;
|
||||
if (outlineMode) {
|
||||
probeBorderColor = theme.getOutlineColor();
|
||||
} else {
|
||||
probeBorderColor = componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? SELECTION_COLOR
|
||||
: PROBE_COLOR.darker();
|
||||
}
|
||||
g2d.setColor(probeBorderColor);
|
||||
g2d.draw(shapes[0]);
|
||||
}
|
||||
|
||||
|
||||
+7
-11
@@ -43,7 +43,7 @@ import org.diylc.core.gerber.IGerberDrawingObserver;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Drill Hole", category = "Electromechanical", author = "Branislav Stojkovic",
|
||||
@ComponentDescriptor(name = "Drill Hole", category = "Electro-Mechanical", author = "Branislav Stojkovic",
|
||||
description = "Drill hole marker for PCB, chassis or faceplate", instanceNamePrefix = "Hole",
|
||||
zOrder = IDIYComponent.BOARD + 0.1, bomPolicy = BomPolicy.NEVER_SHOW,
|
||||
keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB",
|
||||
@@ -66,19 +66,13 @@ public class DrillHole extends AbstractTransparentComponent<Void>
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver,
|
||||
IGerberDrawingObserver gerberDrawingObserver) {
|
||||
|
||||
if (checkPointsClipped(g2d.getClip())) {
|
||||
return;
|
||||
}
|
||||
double holeDiameter = getDiameter().convertToPixels();
|
||||
double borderWidth = STROKE_WIDTH.convertToPixels(); // Use constant stroke width
|
||||
|
||||
g2d.setColor(
|
||||
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? SELECTION_COLOR
|
||||
: color);
|
||||
|
||||
drawingObserver.startTrackingContinuityArea(true);
|
||||
|
||||
// Export to Gerber drill layer
|
||||
if (gerberDrawingObserver != null) {
|
||||
GerberLayer drillLayer = GerberLayer.DrillNonPlated;
|
||||
@@ -96,7 +90,10 @@ public class DrillHole extends AbstractTransparentComponent<Void>
|
||||
holeDiameter, holeDiameter));
|
||||
|
||||
// Draw colored border
|
||||
g2d.setColor(color);
|
||||
g2d.setColor(
|
||||
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||
? SELECTION_COLOR
|
||||
: color);
|
||||
g2d.setStroke(new BasicStroke((float) borderWidth));
|
||||
g2d.draw(new Ellipse2D.Double(point.getX() - holeDiameter / 2, point.getY() - holeDiameter / 2,
|
||||
holeDiameter, holeDiameter));
|
||||
@@ -118,8 +115,7 @@ public class DrillHole extends AbstractTransparentComponent<Void>
|
||||
point.getX(), point.getY() + crosshairLength / 2));
|
||||
|
||||
drawingObserver.stopTracking();
|
||||
drawingObserver.stopTrackingContinuityArea();
|
||||
|
||||
|
||||
if (gerberDrawingObserver != null) {
|
||||
gerberDrawingObserver.stopGerberOutput();
|
||||
}
|
||||
|
||||
+11
-4
@@ -502,10 +502,17 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPositionName(int position) {
|
||||
if (switchType.name().endsWith("_off") && position == 2)
|
||||
return "OFF";
|
||||
return "ON" + Integer.toString(position + 1);
|
||||
public String getPositionName(int position) {
|
||||
int pos = position;
|
||||
if (switchType.name().endsWith("_off")) {
|
||||
int midPosition = (getPositionCount() - 1) / 2;
|
||||
if (position == midPosition) {
|
||||
return "OFF";
|
||||
} else if (position > midPosition) {
|
||||
--pos;
|
||||
}
|
||||
}
|
||||
return "ON" + Integer.toString(pos + 1);
|
||||
}
|
||||
|
||||
@DynamicEditableProperty(source = ToggleSwitchPositionPropertyValueSource.class)
|
||||
|
||||
@@ -151,8 +151,13 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitch.LeverSwitch
|
||||
g2d.draw(body[2]);
|
||||
|
||||
if (getShowMarkers()) {
|
||||
String[] markers =
|
||||
SwitchUtils.getSwitchingMarkers(this, getControlPointCount(), false);
|
||||
String[] markers;
|
||||
if(type == LeverSwitchType.DP3T_5pos_2502N) {
|
||||
markers = new String[]{"1", "2", "3", "4", "5", "6", "7", "8"};
|
||||
} else {
|
||||
markers = SwitchUtils.getSwitchingMarkers(this, getControlPointCount(), false);
|
||||
}
|
||||
|
||||
double theta = getAngle().getValueRad();
|
||||
g2d.setColor(MARKER_COLOR);
|
||||
|
||||
@@ -203,11 +208,13 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitch.LeverSwitch
|
||||
|| type == LeverSwitchType.DP3T_5pos) {
|
||||
x += terminalLength;
|
||||
yOffset = 7;
|
||||
} else if (type == LeverSwitchType.DP3T_5pos_Import) {
|
||||
} else if (type == LeverSwitchType.DP3T_5pos_Import || type == LeverSwitchType.DP3T_5pos_2502N) {
|
||||
yOffset = 10;
|
||||
} else if (type == LeverSwitchType._6_WAY_OG) {
|
||||
x += terminalLength;
|
||||
yOffset = 8;
|
||||
} else if (type == LeverSwitchType._4P3T) {
|
||||
yOffset = 8;
|
||||
} else {
|
||||
yOffset = 12;
|
||||
}
|
||||
@@ -226,11 +233,21 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitch.LeverSwitch
|
||||
- (waferLength - terminalSpacing * yOffset) / 2, waferThickness,
|
||||
waferLength));
|
||||
|
||||
if (type == LeverSwitchType._4P5T) {
|
||||
if (type == LeverSwitchType._4P5T || type == LeverSwitchType._6P5T) {
|
||||
waferArea.add(new Area(new Rectangle2D.Double(x - terminalLength / 2 - waferThickness / 2 + waferSpacing, y
|
||||
- (waferLength - terminalSpacing * 12) / 2, waferThickness,
|
||||
waferLength)));
|
||||
}
|
||||
if (type == LeverSwitchType._6P5T) {
|
||||
waferArea.add(new Area(new Rectangle2D.Double(x - terminalLength / 2 - waferThickness / 2 + waferSpacing * 2, y
|
||||
- (waferLength - terminalSpacing * 12) / 2, waferThickness,
|
||||
waferLength)));
|
||||
}
|
||||
if (type == LeverSwitchType._4P3T) {
|
||||
waferArea.add(new Area(new Rectangle2D.Double(x - terminalLength / 2 - waferThickness / 2 + waferSpacing, y
|
||||
- (waferLength - terminalSpacing * 8) / 2, waferThickness,
|
||||
waferLength)));
|
||||
}
|
||||
|
||||
double theta = getAngle().getValueRad();
|
||||
|
||||
@@ -294,6 +311,7 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitch.LeverSwitch
|
||||
}
|
||||
break;
|
||||
case DP3T_5pos_Import:
|
||||
case DP3T_5pos_2502N:
|
||||
controlPoints = new Point2D[8];
|
||||
terminalSpacing *= 1.5;
|
||||
for (int i = 0; i < controlPoints.length; i++) {
|
||||
@@ -319,6 +337,21 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitch.LeverSwitch
|
||||
controlPoints[i + 12] = new Point2D.Double(x + waferSpacing, y + i * terminalSpacing + (i >= 6 ? terminalSpacing : 0));
|
||||
}
|
||||
break;
|
||||
case _6P5T:
|
||||
controlPoints = new Point2D[36];
|
||||
for (int i = 0; i < controlPoints.length / 3; i++) {
|
||||
controlPoints[i] = new Point2D.Double(x, y + i * terminalSpacing + (i >= 6 ? terminalSpacing : 0));
|
||||
controlPoints[i + 12] = new Point2D.Double(x + waferSpacing, y + i * terminalSpacing + (i >= 6 ? terminalSpacing : 0));
|
||||
controlPoints[i + 24] = new Point2D.Double(x + waferSpacing * 2, y + i * terminalSpacing + (i >= 6 ? terminalSpacing : 0));
|
||||
}
|
||||
break;
|
||||
case _4P3T:
|
||||
controlPoints = new Point2D[16];
|
||||
for (int i = 0; i < controlPoints.length / 2; i++) {
|
||||
controlPoints[i] = new Point2D.Double(x, y + i * terminalSpacing + (i >= 4 ? terminalSpacing : 0));
|
||||
controlPoints[i + 8] = new Point2D.Double(x + waferSpacing, y + i * terminalSpacing + (i >= 4 ? terminalSpacing : 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Rotate if needed
|
||||
@@ -447,7 +480,16 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitch.LeverSwitch
|
||||
|| (index2 == 11 && index2 - index1 == 5 - position);
|
||||
case _4P5T:
|
||||
return ((index1 == 0 || index1 == 12) && index2 - index1 == position + 1)
|
||||
|| ((index2 == 11 || index2 == 23) && index2 - index1 == 5 - position);
|
||||
|| ((index2 == 11 || index2 == 23) && index2 - index1 == 5 - position);
|
||||
case _6P5T:
|
||||
return ((index1 == 0 || index1 == 12 || index1 == 24) && index2 - index1 == position + 1)
|
||||
|| ((index2 == 11 || index2 == 23 || index2 == 35) && index2 - index1 == 5 - position);
|
||||
case _4P3T:
|
||||
return ((index1 == 0 || index1 == 8) && index2 - index1 == position + 1)
|
||||
|| ((index2 == 7 || index2 == 15) && index2 - index1 == 3 - position);
|
||||
case DP3T_5pos_2502N:
|
||||
positionConnections = DP3T_5pos_2502N_CONNECTIONS.get(position);
|
||||
break;
|
||||
}
|
||||
|
||||
if (positionConnections != null) {
|
||||
@@ -526,6 +568,32 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitch.LeverSwitch
|
||||
) // position 6
|
||||
);
|
||||
|
||||
private static final List<List<int[]>> DP3T_5pos_2502N_CONNECTIONS = Arrays.asList(
|
||||
Arrays.asList(
|
||||
new int[] { 0, 3 }
|
||||
), // position 1
|
||||
Arrays.asList(
|
||||
new int[] { 0, 3 },
|
||||
new int[] { 1, 3 },
|
||||
new int[] { 4, 7 },
|
||||
new int[] { 5, 7 }
|
||||
), // position 2
|
||||
Arrays.asList(
|
||||
new int[] { 0, 3 },
|
||||
new int[] { 2, 3 },
|
||||
new int[] { 6, 7 }
|
||||
), // position 3
|
||||
Arrays.asList(
|
||||
new int[] { 1, 3 },
|
||||
new int[] { 2, 3 },
|
||||
new int[] { 5, 7 }
|
||||
), // position 4
|
||||
Arrays.asList(
|
||||
new int[] { 2, 3 },
|
||||
new int[] { 6, 7 }
|
||||
) // position 5
|
||||
);
|
||||
|
||||
@DynamicEditableProperty(source = LeverSwitchPositionPropertyValueSource.class)
|
||||
@EditableProperty(name = "Selected Position")
|
||||
@Override
|
||||
@@ -559,7 +627,10 @@ public class LeverSwitch extends AbstractAngledComponent<LeverSwitch.LeverSwitch
|
||||
_4P5T("4P5T (Super/Mega)", 5),
|
||||
DP4T("DP4T (4-Position Tele)", 4),
|
||||
_6_WAY_OG("DP4T (6-Position Oak Grigsby)", 6),
|
||||
DP5T("DP5T", 5);
|
||||
DP5T("DP5T", 5),
|
||||
_6P5T("6P5T (5-Position 6 Pole AxLabs)", 5),
|
||||
_4P3T("4P3T (3-Position 4 Pole AxLabs)", 3),
|
||||
DP3T_5pos_2502N("DP3T (Import 5-Position 2502N)", 5);
|
||||
|
||||
private final int positionCount;
|
||||
private String title;
|
||||
|
||||
@@ -208,9 +208,9 @@ public class S1Switch extends AbstractTransparentComponent<Void> implements ISwi
|
||||
|
||||
double dy = 0;
|
||||
if (i % 3 == 1) {
|
||||
dy = -1;
|
||||
} else if (i % 3 == 0) {
|
||||
dy = 1;
|
||||
} else if (i % 3 == 0) {
|
||||
dy = -1;
|
||||
}
|
||||
|
||||
Stroke stroke = g2d.getStroke();
|
||||
@@ -280,9 +280,9 @@ public class S1Switch extends AbstractTransparentComponent<Void> implements ISwi
|
||||
@Override
|
||||
public String getPositionName(int position) {
|
||||
if (position == 0) {
|
||||
return "Up";
|
||||
return "Down";
|
||||
}
|
||||
return "Down";
|
||||
return "Up";
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Markers")
|
||||
|
||||
+5
-2
@@ -27,6 +27,7 @@ import java.awt.geom.Point2D;
|
||||
import org.diylc.common.IComponentTransformer;
|
||||
import org.diylc.common.OrientationHV;
|
||||
import org.diylc.components.electromechanical.MiniToggleSwitch;
|
||||
import org.diylc.components.electromechanical.ToggleSwitchType;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
public class MiniToggleSwitchTransformer implements IComponentTransformer {
|
||||
@@ -107,7 +108,8 @@ public class MiniToggleSwitchTransformer implements IComponentTransformer {
|
||||
MiniToggleSwitch sw = (MiniToggleSwitch) component;
|
||||
|
||||
if (direction == IComponentTransformer.HORIZONTAL) {
|
||||
double dx = 2 * (center.getX() - sw.getControlPoint(1).getX());
|
||||
double dx = 2 * (center.getX() -
|
||||
(sw.getControlPoint(0).getX() + sw.getControlPoint(sw.getControlPointCount() - 1).getX()) / 2);
|
||||
double dy = 0;
|
||||
|
||||
for (int i = 0; i < sw.getControlPointCount(); i++) {
|
||||
@@ -116,7 +118,8 @@ public class MiniToggleSwitchTransformer implements IComponentTransformer {
|
||||
}
|
||||
} else {
|
||||
double dx = 0;
|
||||
double dy = 2 * (center.getY() - sw.getControlPoint(1).getY());
|
||||
double dy = 2 * (center.getY() -
|
||||
(sw.getControlPoint(0).getY() + sw.getControlPoint(sw.getControlPointCount() - 1).getY()) / 2);
|
||||
|
||||
for (int i = 0; i < sw.getControlPointCount(); i++) {
|
||||
Point2D p = sw.getControlPoint(i);
|
||||
|
||||
@@ -28,6 +28,34 @@ public class LeverSwitchTests extends AbstractSwitchTests {
|
||||
leverSwitch.setValue(LeverSwitchType._4P5T);
|
||||
testSwitch(leverSwitch, validCombinations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLeverSwitch6P5T() {
|
||||
LeverSwitch leverSwitch = new LeverSwitch();
|
||||
|
||||
String[] validCombinations = new String[] {
|
||||
"0,0,1", "0,6,11", "0,12,13", "0,18,23", "0,24,25", "0,30,35",
|
||||
"1,0,2", "1,7,11", "1,12,14", "1,19,23", "1,24,26", "1,31,35",
|
||||
"2,0,3", "2,8,11", "2,12,15", "2,20,23", "2,24,27", "2,32,35",
|
||||
"3,0,4", "3,9,11", "3,12,16", "3,21,23", "3,24,28", "3,33,35",
|
||||
"4,0,5", "4,10,11", "4,12,17", "4,22,23", "4,24,29", "4,34,35"
|
||||
};
|
||||
leverSwitch.setValue(LeverSwitchType._6P5T);
|
||||
testSwitch(leverSwitch, validCombinations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLeverSwitch4P3T() {
|
||||
LeverSwitch leverSwitch = new LeverSwitch();
|
||||
|
||||
String[] validCombinations = new String[] {
|
||||
"0,0,1", "0,4,7", "0,8,9", "0,12,15",
|
||||
"1,0,2", "1,5,7", "1,8,10", "1,13,15",
|
||||
"2,0,3", "2,6,7", "2,8,11", "2,14,15",
|
||||
};
|
||||
leverSwitch.setValue(LeverSwitchType._4P3T);
|
||||
testSwitch(leverSwitch, validCombinations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLeverSwitchImport() {
|
||||
@@ -50,4 +78,20 @@ public class LeverSwitchTests extends AbstractSwitchTests {
|
||||
leverSwitch.setValue(LeverSwitchType._6_WAY_OG);
|
||||
testSwitch(leverSwitch, validCombinations);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLeverSwitchImport2502N() {
|
||||
LeverSwitch leverSwitch = new LeverSwitch();
|
||||
|
||||
String[] validCombinations = new String[] {
|
||||
"0,0,3",
|
||||
"1,0,3", "1,1,3", "1,4,7", "1,5,7",
|
||||
"2,0,3", "2,2,3", "2,6,7",
|
||||
"3,1,3", "3,2,3", "3,5,7",
|
||||
"4,2,3", "4,6,7",
|
||||
};
|
||||
|
||||
leverSwitch.setValue(LeverSwitchType.DP3T_5pos_2502N);
|
||||
testSwitch(leverSwitch, validCombinations);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +182,7 @@ DP3T (Standard 5-Position Strat)
|
||||
DP4T (4-Position Tele)
|
||||
DP4T (6-Position Oak Grigsby)
|
||||
DP5T
|
||||
6P5T
|
||||
DPDT
|
||||
DPDT (On/Off/On)
|
||||
DPDT (On/On)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.diylc</groupId>
|
||||
<artifactId>diylc-parent</artifactId>
|
||||
<version>5.6.0</version>
|
||||
<version>5.7.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>diylc-swing</artifactId>
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.diylc.appframework.miscutils.PropertyInjector;
|
||||
import org.diylc.appframework.miscutils.Utils;
|
||||
import org.diylc.swingframework.export.DrawingExporter;
|
||||
import org.diylc.swingframework.fonts.FontOptimizer;
|
||||
import org.diylc.utils.ThemeUtils;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.IView;
|
||||
@@ -71,6 +72,9 @@ public class DIYLCStarter {
|
||||
}
|
||||
|
||||
public static void runDIYLC(String[] args) {
|
||||
// Apply OS dark theme settings before creating any UI components
|
||||
ThemeUtils.applyOSDarkTheme();
|
||||
|
||||
// Initialize splash screen
|
||||
DIYLCSplash splash = null;
|
||||
Exception splashException = null;
|
||||
@@ -137,6 +141,8 @@ public class DIYLCStarter {
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
// Apply dark theme colors if dark mode is detected
|
||||
ThemeUtils.applyDarkThemeColors();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not set Look&Feel", e);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
*
|
||||
* 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
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.diylc.utils;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import javax.swing.UIManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.appframework.miscutils.Utils;
|
||||
|
||||
/**
|
||||
* Utility class for detecting and applying OS dark theme settings.
|
||||
*
|
||||
* Note: Modern Java (11+) with system Look and Feel should automatically
|
||||
* respect OS dark theme settings, but this utility provides explicit detection
|
||||
* and ensures compatibility with older Java versions.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class ThemeUtils {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ThemeUtils.class);
|
||||
|
||||
/**
|
||||
* Detects and applies OS dark theme settings.
|
||||
* This must be called before creating any AWT/Swing components.
|
||||
*/
|
||||
public static void applyOSDarkTheme() {
|
||||
try {
|
||||
if (Utils.isMac()) {
|
||||
applyMacOSDarkTheme();
|
||||
} else if (Utils.isWindows()) {
|
||||
detectWindowsDarkTheme();
|
||||
} else {
|
||||
detectLinuxDarkTheme();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Error detecting OS dark theme: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies dark theme colors to UIManager after the Look and Feel is set.
|
||||
* This should be called after UIManager.setLookAndFeel().
|
||||
*
|
||||
* @return true if dark mode was detected and colors were applied, false otherwise
|
||||
*/
|
||||
public static boolean applyDarkThemeColors() {
|
||||
try {
|
||||
if (Utils.isMac()) {
|
||||
return applyMacOSDarkThemeColors();
|
||||
} else if (Utils.isWindows()) {
|
||||
return applyWindowsDarkThemeColors();
|
||||
} else {
|
||||
return applyLinuxDarkThemeColors();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Error applying dark theme colors: " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects and applies macOS dark theme settings.
|
||||
*/
|
||||
private static void applyMacOSDarkTheme() {
|
||||
// macOS: Check if dark mode is enabled
|
||||
// Modern Java (11+) should automatically detect this, but we'll check explicitly
|
||||
String appearance = System.getProperty("apple.awt.application.appearance");
|
||||
if (appearance == null) {
|
||||
// Try to detect dark mode via system command (for older Java versions)
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec(
|
||||
new String[]{"defaults", "read", "-g", "AppleInterfaceStyle"});
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream()));
|
||||
String result = reader.readLine();
|
||||
if ("Dark".equals(result)) {
|
||||
// Note: Setting this property after JVM start may not always work,
|
||||
// but it's worth trying for older Java versions
|
||||
System.setProperty("apple.awt.application.appearance", "NSAppearanceNameDarkAqua");
|
||||
LOG.info("Detected macOS dark mode - attempting to apply dark theme");
|
||||
} else {
|
||||
LOG.debug("macOS light mode detected");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// If detection fails, that's okay - modern Java will handle it automatically
|
||||
LOG.debug("Could not detect macOS theme via defaults command: " + e.getMessage());
|
||||
}
|
||||
} else if ("NSAppearanceNameDarkAqua".equals(appearance)) {
|
||||
LOG.info("macOS dark mode already detected by JVM");
|
||||
} else {
|
||||
LOG.debug("macOS appearance: " + appearance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects Windows dark theme settings.
|
||||
*/
|
||||
private static void detectWindowsDarkTheme() {
|
||||
// Windows: Try to detect dark theme via registry
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec(
|
||||
new String[]{"reg", "query",
|
||||
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
|
||||
"/v", "AppsUseLightTheme"});
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.contains("AppsUseLightTheme")) {
|
||||
// If value is 0, dark theme is enabled
|
||||
if (line.contains("0x0") || line.endsWith("0")) {
|
||||
// For Windows, the system Look and Feel should automatically respect dark mode
|
||||
// in Java 11+, but we can log it for debugging
|
||||
LOG.info("Detected Windows dark mode");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not detect Windows theme via registry: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects Linux dark theme settings.
|
||||
*/
|
||||
private static void detectLinuxDarkTheme() {
|
||||
// Linux: Check GTK theme or environment variables
|
||||
try {
|
||||
String gtkTheme = System.getenv("GTK_THEME");
|
||||
if (gtkTheme != null && (gtkTheme.toLowerCase().contains("dark") ||
|
||||
gtkTheme.toLowerCase().contains("Dark"))) {
|
||||
LOG.info("Detected Linux dark theme: " + gtkTheme);
|
||||
}
|
||||
// Also check COLORFGBG environment variable (used by some terminals/desktops)
|
||||
String colorFgBg = System.getenv("COLORFGBG");
|
||||
if (colorFgBg != null) {
|
||||
// Format is typically "15;0" where second number < 8 indicates dark background
|
||||
String[] parts = colorFgBg.split(";");
|
||||
if (parts.length > 1) {
|
||||
try {
|
||||
int bgColor = Integer.parseInt(parts[parts.length - 1]);
|
||||
if (bgColor < 8) {
|
||||
LOG.info("Detected Linux dark background via COLORFGBG");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not detect Linux theme: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies macOS dark theme colors to UIManager.
|
||||
* @return true if dark mode is active
|
||||
*/
|
||||
private static boolean applyMacOSDarkThemeColors() {
|
||||
boolean isDarkMode = false;
|
||||
|
||||
// Check if dark mode is active
|
||||
String appearance = System.getProperty("apple.awt.application.appearance");
|
||||
if (appearance == null) {
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec(
|
||||
new String[]{"defaults", "read", "-g", "AppleInterfaceStyle"});
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream()));
|
||||
String result = reader.readLine();
|
||||
isDarkMode = "Dark".equals(result);
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not detect macOS theme: " + e.getMessage());
|
||||
// Try to infer from current UI colors
|
||||
Color menuBarBg = UIManager.getColor("MenuBar.background");
|
||||
if (menuBarBg != null && isDarkColor(menuBarBg)) {
|
||||
isDarkMode = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isDarkMode = "NSAppearanceNameDarkAqua".equals(appearance);
|
||||
}
|
||||
|
||||
if (isDarkMode) {
|
||||
LOG.info("Applying macOS dark theme colors");
|
||||
applyDarkColors();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies Windows dark theme colors to UIManager.
|
||||
* @return true if dark mode is active
|
||||
*/
|
||||
private static boolean applyWindowsDarkThemeColors() {
|
||||
boolean isDarkMode = false;
|
||||
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec(
|
||||
new String[]{"reg", "query",
|
||||
"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
|
||||
"/v", "AppsUseLightTheme"});
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.contains("AppsUseLightTheme")) {
|
||||
// If value is 0, dark theme is enabled
|
||||
if (line.contains("0x0") || line.endsWith("0")) {
|
||||
isDarkMode = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not detect Windows theme: " + e.getMessage());
|
||||
// Try to infer from current UI colors
|
||||
Color menuBarBg = UIManager.getColor("MenuBar.background");
|
||||
if (menuBarBg != null && isDarkColor(menuBarBg)) {
|
||||
isDarkMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDarkMode) {
|
||||
LOG.info("Applying Windows dark theme colors");
|
||||
applyDarkColors();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies Linux dark theme colors to UIManager.
|
||||
* @return true if dark mode is active
|
||||
*/
|
||||
private static boolean applyLinuxDarkThemeColors() {
|
||||
boolean isDarkMode = false;
|
||||
|
||||
try {
|
||||
String gtkTheme = System.getenv("GTK_THEME");
|
||||
if (gtkTheme != null && (gtkTheme.toLowerCase().contains("dark") ||
|
||||
gtkTheme.toLowerCase().contains("Dark"))) {
|
||||
isDarkMode = true;
|
||||
}
|
||||
|
||||
// Also check COLORFGBG
|
||||
if (!isDarkMode) {
|
||||
String colorFgBg = System.getenv("COLORFGBG");
|
||||
if (colorFgBg != null) {
|
||||
String[] parts = colorFgBg.split(";");
|
||||
if (parts.length > 1) {
|
||||
try {
|
||||
int bgColor = Integer.parseInt(parts[parts.length - 1]);
|
||||
if (bgColor < 8) {
|
||||
isDarkMode = true;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to infer from current UI colors
|
||||
if (!isDarkMode) {
|
||||
Color menuBarBg = UIManager.getColor("MenuBar.background");
|
||||
if (menuBarBg != null && isDarkColor(menuBarBg)) {
|
||||
isDarkMode = true;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not detect Linux theme: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (isDarkMode) {
|
||||
LOG.info("Applying Linux dark theme colors");
|
||||
applyDarkColors();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies dark theme colors to common UI components.
|
||||
* Only overrides colors that would cause visibility issues (e.g., dark text on dark background).
|
||||
*/
|
||||
private static void applyDarkColors() {
|
||||
// Menu bar and menu colors - fix text colors if background is dark
|
||||
Color menuBarBg = UIManager.getColor("MenuBar.background");
|
||||
Color menuBarFg = UIManager.getColor("MenuBar.foreground");
|
||||
|
||||
if (menuBarBg != null && isDarkColor(menuBarBg)) {
|
||||
// Background is dark, ensure text is light
|
||||
if (menuBarFg == null || isDarkColor(menuBarFg)) {
|
||||
UIManager.put("MenuBar.foreground", Color.WHITE);
|
||||
}
|
||||
|
||||
// Fix menu colors
|
||||
Color menuBg = UIManager.getColor("Menu.background");
|
||||
Color menuFg = UIManager.getColor("Menu.foreground");
|
||||
if (menuBg == null || isDarkColor(menuBg)) {
|
||||
UIManager.put("Menu.background", new Color(50, 50, 50));
|
||||
}
|
||||
if (menuFg == null || (menuBg != null && isDarkColor(menuBg) && isDarkColor(menuFg))) {
|
||||
UIManager.put("Menu.foreground", Color.WHITE);
|
||||
}
|
||||
UIManager.put("Menu.selectionBackground", new Color(60, 60, 60));
|
||||
UIManager.put("Menu.selectionForeground", Color.WHITE);
|
||||
|
||||
// Fix menu item colors
|
||||
Color menuItemBg = UIManager.getColor("MenuItem.background");
|
||||
Color menuItemFg = UIManager.getColor("MenuItem.foreground");
|
||||
if (menuItemBg == null || isDarkColor(menuItemBg)) {
|
||||
UIManager.put("MenuItem.background", new Color(50, 50, 50));
|
||||
}
|
||||
if (menuItemFg == null || (menuItemBg != null && isDarkColor(menuItemBg) && isDarkColor(menuItemFg))) {
|
||||
UIManager.put("MenuItem.foreground", Color.WHITE);
|
||||
}
|
||||
UIManager.put("MenuItem.selectionBackground", new Color(60, 60, 60));
|
||||
UIManager.put("MenuItem.selectionForeground", Color.WHITE);
|
||||
}
|
||||
|
||||
// Popup menu colors
|
||||
Color popupBg = UIManager.getColor("PopupMenu.background");
|
||||
if (popupBg == null || isDarkColor(popupBg)) {
|
||||
UIManager.put("PopupMenu.background", new Color(50, 50, 50));
|
||||
UIManager.put("PopupMenu.foreground", Color.WHITE);
|
||||
UIManager.put("PopupMenu.borderColor", new Color(70, 70, 70));
|
||||
}
|
||||
|
||||
// Checkbox and radio button menu items
|
||||
Color checkBoxMenuItemBg = UIManager.getColor("CheckBoxMenuItem.background");
|
||||
if (checkBoxMenuItemBg == null || isDarkColor(checkBoxMenuItemBg)) {
|
||||
UIManager.put("CheckBoxMenuItem.background", new Color(50, 50, 50));
|
||||
UIManager.put("CheckBoxMenuItem.foreground", Color.WHITE);
|
||||
UIManager.put("CheckBoxMenuItem.selectionBackground", new Color(60, 60, 60));
|
||||
UIManager.put("CheckBoxMenuItem.selectionForeground", Color.WHITE);
|
||||
}
|
||||
|
||||
Color radioMenuItemBg = UIManager.getColor("RadioButtonMenuItem.background");
|
||||
if (radioMenuItemBg == null || isDarkColor(radioMenuItemBg)) {
|
||||
UIManager.put("RadioButtonMenuItem.background", new Color(50, 50, 50));
|
||||
UIManager.put("RadioButtonMenuItem.foreground", Color.WHITE);
|
||||
UIManager.put("RadioButtonMenuItem.selectionBackground", new Color(60, 60, 60));
|
||||
UIManager.put("RadioButtonMenuItem.selectionForeground", Color.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a color is dark (suitable for dark theme).
|
||||
*/
|
||||
private static boolean isDarkColor(Color color) {
|
||||
if (color == null) {
|
||||
return false;
|
||||
}
|
||||
// Calculate luminance
|
||||
double luminance = (0.299 * color.getRed() + 0.587 * color.getGreen() + 0.114 * color.getBlue()) / 255;
|
||||
return luminance < 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>org.diylc</groupId>
|
||||
<artifactId>diylc-parent</artifactId>
|
||||
<version>5.6.0</version>
|
||||
<version>5.7.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>DIY Layout Creator</name>
|
||||
|
||||
@@ -129,7 +129,7 @@ INSERT INTO diylc_knowledge_base (category, section, content) ('Component Types'
|
||||
"type" : "java.lang.Boolean"
|
||||
}, {
|
||||
"name" : "Type",
|
||||
"type" : "org.diylc.components.guitar.LeverSwitch$LeverSwitchType(DP3T (Standard 3-Position Strat),DP3T (Standard 5-Position Strat),DP3T (Import 5-Position Strat),4P5T (Super/Mega),DP4T (4-Position Tele),DP4T (6-Position Oak Grigsby),DP5T)"
|
||||
"type" : "org.diylc.components.guitar.LeverSwitch$LeverSwitchType(DP3T (Standard 3-Position Strat),DP3T (Standard 5-Position Strat),DP3T (Import 5-Position Strat),4P5T (Super/Mega),DP4T (4-Position Tele),DP4T (6-Position Oak Grigsby),DP5T,6P5T (5-Position 6 Pole AxLabs)),4P3T (3-Position 3 Pole AxLabs),DP3T (Import 5-Position 2502N)"
|
||||
}, {
|
||||
"name" : "Angle",
|
||||
"type" : "org.diylc.core.Angle"
|
||||
|
||||
Reference in New Issue
Block a user