All PCB parts with a top silkscreen, including tube sockets, rotary switches, relays and transformers, have the 'Board Side' property

This commit is contained in:
Bane Stojkovic
2026-11-11 15:34:40 +01:00
parent 9721307586
commit 246763419c
19 changed files with 221 additions and 83 deletions
@@ -633,6 +633,14 @@
<changeType>NEW_FEATURE</changeType>
<description>Added 'Value Notation' to the Config menu to show resistance, capacitance, inductance and voltage values in RKM notation, e.g. 4K7, 0R22, 2n2, 4u7 or 6V3, instead of decimal; values can be typed in either notation, and typing the unit together with the value, e.g. 4K7 or 2.2nF, sets the unit at the same time</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Resistors, capacitors, diodes, ICs, transistors, switches, jacks, tube sockets and other PCB parts have a new 'Board Side' property to place them on the bottom of the board; bottom parts are drawn faded on the canvas and solid in the board's Underside Display, and Gerber export puts their silkscreen on the bottom layer with the text mirrored</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Components can be selected, dragged and stretched by clicking them in a board's Underside Display, not only in the main view</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>BUG_FIX</changeType>
<description>Rotated labels in pasted components and building blocks were drawn in the wrong place and at the wrong angle while following the mouse, until the components were placed</description>
@@ -36,8 +36,10 @@ import org.diylc.common.Display;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.PCBLayer;
import org.diylc.components.AbstractLabeledComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -58,7 +60,7 @@ import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Mini Relay", author = "Branislav Stojkovic", category = "Electro-Mechanical",
instanceNamePrefix = "RY", description = "Miniature PCB mount relay, like Omron G5V-1/G5V-2 or Fujitsu FTR-B3",
zOrder = IDIYComponent.COMPONENT, enableCache = true)
public class MiniRelay extends AbstractLabeledComponent<String> implements IGerberComponentSimple {
public class MiniRelay extends AbstractLabeledComponent<String> implements IGerberComponentSimple, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -97,6 +99,7 @@ public class MiniRelay extends AbstractLabeledComponent<String> implements IGerb
private RelayType type = RelayType.DPDT;
private RelaySize size = RelaySize.Miniature;
private Voltage voltage = new Voltage(12d, VoltageUnit.V);
private PCBLayer boardSide;
transient private Area[] body;
public MiniRelay() {
@@ -471,6 +474,16 @@ public class MiniRelay extends AbstractLabeledComponent<String> implements IGerb
return new Rectangle2D.Double(minX - margin, minY - margin, maxX - minX + 2 * margin, maxY - minY + 2 * margin);
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
public static enum RelayType {
SPDT, DPDT;
}
@@ -36,9 +36,11 @@ import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractMultiPartComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -56,7 +58,7 @@ import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Plastic DC Jack", category = "Electro-Mechanical", author = "Branislav Stojkovic",
description = "Panel mount plastic DC jack", zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "J", autoEdit = false, enableCache = true)
public class PlasticDCJack extends AbstractMultiPartComponent<String> implements IGerberComponentSimple {
public class PlasticDCJack extends AbstractMultiPartComponent<String> implements IGerberComponentSimple, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -71,6 +73,7 @@ public class PlasticDCJack extends AbstractMultiPartComponent<String> implements
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0), new Point2D.Double(0, 0), new Point2D.Double(0, 0)};
private String value = "";
private DCPolarity polarity = DCPolarity.CENTER_NEGATIVE;
private PCBLayer boardSide;
transient private Area[] body;
public PlasticDCJack() {
@@ -294,4 +297,14 @@ public class PlasticDCJack extends AbstractMultiPartComponent<String> implements
public Integer getFontSizeOverride() {
return super.getFontSizeOverride();
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
}
@@ -36,11 +36,13 @@ import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.PCBLayer;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractMultiPartComponent;
import org.diylc.components.transform.PotentiometerTransformer;
import org.diylc.core.ComponentState;
import org.diylc.core.CreationMethod;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -61,7 +63,7 @@ import org.diylc.utils.Constants;
description = "Single pole rotary switch, typically used for impedance selector",
zOrder = IDIYComponent.COMPONENT, transformer = PotentiometerTransformer.class,
enableCache = true)
public class RotarySelectorSwitch extends AbstractMultiPartComponent<String> implements IGerberComponentSimple {
public class RotarySelectorSwitch extends AbstractMultiPartComponent<String> implements IGerberComponentSimple, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -83,6 +85,7 @@ public class RotarySelectorSwitch extends AbstractMultiPartComponent<String> imp
private boolean showLabels = true;
private RotaryPositionCount positionCount = RotaryPositionCount.THREE;
private SwitchTiming timing;
private PCBLayer boardSide;
public RotarySelectorSwitch() {
super();
@@ -370,6 +373,16 @@ public class RotarySelectorSwitch extends AbstractMultiPartComponent<String> imp
return false;
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
public static enum RotaryPositionCount {
TWO(2), THREE(3), FOUR(4);
@@ -42,12 +42,14 @@ import org.diylc.awt.TwoCircleTangent;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractAngledComponent;
import org.diylc.components.guitar.RotarySwitchOpenPositionPropertyValueSource;
import org.diylc.components.transform.AngledComponentTransformer;
import org.diylc.core.Angle;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.ISwitch;
@@ -71,7 +73,7 @@ import org.diylc.utils.SwitchUtils;
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true,
transformer = AngledComponentTransformer.class)
public class RotarySwitchOpen extends AbstractAngledComponent<RotarySwitchOpenType>
implements ISwitch, IGerberComponentSimple {
implements ISwitch, IGerberComponentSimple, IBoardSideComponent {
private static final int ANGLE_OFFSET = -15;
private static final int INNER_COMMON_ANGLE_OFFSET = -90;
@@ -106,6 +108,7 @@ public class RotarySwitchOpen extends AbstractAngledComponent<RotarySwitchOpenTy
private double[] pointAngles;
private Integer selectedPosition;
private PCBLayer boardSide;
public RotarySwitchOpen() {
super();
@@ -609,6 +612,16 @@ public class RotarySwitchOpen extends AbstractAngledComponent<RotarySwitchOpenTy
maxY - minY + 2 * margin);
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
public static enum Mount {
CHASSIS("Chassis"), PCB("PCB");
@@ -37,10 +37,12 @@ import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractAngledComponent;
import org.diylc.components.transform.AngledComponentTransformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.ISwitch;
@@ -60,7 +62,7 @@ import org.diylc.utils.Constants;
instanceNamePrefix = "SW", description = "Sealed plastic rotary switch in several different switching configurations",
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true,
transformer = AngledComponentTransformer.class)
public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSealedType> implements ISwitch, IGerberComponentSimple {
public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSealedType> implements ISwitch, IGerberComponentSimple, IBoardSideComponent {
private static final int OUTER_ANGLE_OFFSET = 15;
private static final int INNER_ANGLE_OFFSET = 30;
@@ -88,6 +90,7 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)};
private double[] pointAngles;
private PCBLayer boardSide;
public RotarySwitchSealed() {
super();
@@ -358,6 +361,16 @@ public class RotarySwitchSealed extends AbstractAngledComponent<RotarySwitchSeal
return new Rectangle2D.Double(rect.getX() - margin, rect.getY() - margin, rect.getWidth() + 2 * margin, rect.getHeight() + 2 * margin);
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
public static enum Mount {
CHASSIS("Chassis"), PCB("PCB");
@@ -41,6 +41,7 @@ import org.diylc.components.AbstractTransparentComponent;
import org.diylc.components.guitar.Freeway3x4_03SwitchPositionPropertyValueSource;
import org.diylc.components.transform.MiniToggleSwitchTransformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.ISwitch;
@@ -61,7 +62,7 @@ import org.diylc.utils.SwitchUtils;
author = "Branislav Stojkovic", description = "Panel mounted slide switch",
zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "SW",
enableCache = true, transformer = MiniToggleSwitchTransformer.class)
public class SlideSwitch extends AbstractTransparentComponent<SlideSwitchType> implements ISwitch, IGerberComponentSimple {
public class SlideSwitch extends AbstractTransparentComponent<SlideSwitchType> implements ISwitch, IGerberComponentSimple, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -95,6 +96,7 @@ public class SlideSwitch extends AbstractTransparentComponent<SlideSwitchType> i
private Integer selectedPosition;
private Boolean showMarkers;
private PCBLayer boardSide;
public SlideSwitch() {
super();
@@ -535,4 +537,14 @@ public class SlideSwitch extends AbstractTransparentComponent<SlideSwitchType> i
return new Rectangle2D.Double(bounds.getX() - margin, bounds.getY() - margin,
bounds.getWidth() + 2 * margin, bounds.getHeight() + 2 * margin);
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
}
@@ -34,6 +34,7 @@ import org.diylc.common.Display;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.PCBLayer;
import org.diylc.components.AbstractLabeledComponent;
import org.diylc.components.guitar.LeverSwitchPositionPropertyValueSource;
import org.diylc.core.*;
@@ -51,7 +52,7 @@ import org.diylc.utils.Constants;
description = "4-pin tactile momentary switch", zOrder = IDIYComponent.COMPONENT,
keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true)
public class TactileMicroSwitch extends AbstractLabeledComponent<String> implements IGerberComponentSimple,
ISwitch {
ISwitch, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -79,6 +80,7 @@ public class TactileMicroSwitch extends AbstractLabeledComponent<String> impleme
private Size rowSpacing;
private PinPairingMode pinPairingMode;
private int selectedPosition;
private PCBLayer boardSide;
public TactileMicroSwitch() {
super();
@@ -518,6 +520,16 @@ public class TactileMicroSwitch extends AbstractLabeledComponent<String> impleme
this.selectedPosition = selectedPosition;
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
public enum PinPairingMode {
Opposite, Diagonal, Adjacent;
}
@@ -40,9 +40,11 @@ import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.PCBLayer;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractMultiPartComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -62,7 +64,7 @@ import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Mini Signal Transformer", author = "Branislav Stojkovic", category = "Passive",
instanceNamePrefix = "TR", description = "Miniature PCB-mount signal transformer with EI core",
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE)
public class AudioTransformer extends AbstractMultiPartComponent<String> implements IGerberComponentSimple {
public class AudioTransformer extends AbstractMultiPartComponent<String> implements IGerberComponentSimple, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -91,6 +93,7 @@ public class AudioTransformer extends AbstractMultiPartComponent<String> impleme
private Color labelColor = LABEL_COLOR;
private boolean primaryCT = true;
private boolean secondaryCT = true;
private PCBLayer boardSide;
transient private Area[] body;
@@ -525,4 +528,14 @@ public class AudioTransformer extends AbstractMultiPartComponent<String> impleme
public boolean canPointMoveFreely(int pointIndex) {
return false;
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
}
@@ -40,9 +40,11 @@ import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.PCBLayer;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractLabeledComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -63,7 +65,7 @@ import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Multi-Section Capacitor", author = "Branislav Stojkovic", category = "Passive",
instanceNamePrefix = "C", description = "Multi-section vertically mounted electrolytic capacitor, similar to JJ, CE and others",
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true)
public class MultiSectionCapacitor extends AbstractLabeledComponent<Capacitance[]> implements IGerberComponentSimple {
public class MultiSectionCapacitor extends AbstractLabeledComponent<Capacitance[]> implements IGerberComponentSimple, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -92,6 +94,7 @@ public class MultiSectionCapacitor extends AbstractLabeledComponent<Capacitance[
protected Display display = Display.NAME;
// private Size pinSpacing = PIN_SPACING;
private Size diameter = BODY_DIAMETER;
private PCBLayer boardSide;
public MultiSectionCapacitor() {
super();
@@ -541,4 +544,14 @@ public class MultiSectionCapacitor extends AbstractLabeledComponent<Capacitance[
Rectangle2D bounds = getBody()[0].getBounds2D();
return new Rectangle2D.Double(bounds.getX() - margin, bounds.getY() - margin, bounds.getWidth() + 2 * margin, bounds.getHeight() + 2 * margin);
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
}
@@ -34,8 +34,10 @@ import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.PCBLayer;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractLabeledComponent;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDatasheetSupport;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
@@ -43,7 +45,7 @@ import org.diylc.core.gerber.IGerberComponentSimple;
import org.diylc.netlist.ISpiceMapper;
public abstract class AbstractTransistorPackage extends AbstractLabeledComponent<String> implements ISpiceMapper, IGerberComponentSimple,
IDatasheetSupport {
IDatasheetSupport, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -59,6 +61,7 @@ public abstract class AbstractTransistorPackage extends AbstractLabeledComponent
protected TransistorDisplay display = TransistorDisplay.NAME;
protected boolean folded = false;
private PCBLayer boardSide;
public AbstractTransistorPackage() {
}
@@ -328,6 +331,16 @@ public abstract class AbstractTransistorPackage extends AbstractLabeledComponent
}
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
public enum TransistorDisplay {
NAME, VALUE, NONE, BOTH, PINOUT;
@@ -39,6 +39,7 @@ import org.diylc.components.AbstractLabeledComponent;
import org.diylc.components.RoundedPolygon;
import org.diylc.components.AbstractLeadedComponent.LabelOrientation;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -58,7 +59,7 @@ import org.diylc.utils.Constants;
category = "Semiconductors", instanceNamePrefix = "BR",
description = "Few variations of bridge rectifier chips", zOrder = IDIYComponent.COMPONENT,
keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true)
public class BridgeRectifier extends AbstractLabeledComponent<String> implements IGerberComponentSimple {
public class BridgeRectifier extends AbstractLabeledComponent<String> implements IGerberComponentSimple, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -108,6 +109,7 @@ public class BridgeRectifier extends AbstractLabeledComponent<String> implements
@Deprecated
private LabelOrientation labelOriantation;
private LabelOrientation labelOrientation = LabelOrientation.Directional;
private PCBLayer boardSide;
public BridgeRectifier() {
super();
@@ -709,6 +711,16 @@ public class BridgeRectifier extends AbstractLabeledComponent<String> implements
bounds.getWidth() + 2 * margin, bounds.getHeight() + 2 * margin);
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
public static enum RectifierType {
MiniDIP1("DFM A", PinShape.Square), MiniDIP2("DFM B", PinShape.Square), MiniRound1(
@@ -37,6 +37,7 @@ import org.diylc.common.*;
import org.diylc.components.AbstractMakerBoard;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDatasheetSupport;
import org.diylc.core.IDrawingObserver;
@@ -61,7 +62,7 @@ import org.diylc.utils.Constants;
enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2,
datasheetModelColumn = 1)
public class MultiwattIC extends AbstractTransparentComponent<String>
implements IGerberComponentSimple, IDatasheetSupport {
implements IGerberComponentSimple, IDatasheetSupport, IBoardSideComponent {
private static final long serialVersionUID = 1L;
@@ -92,6 +93,7 @@ public class MultiwattIC extends AbstractTransparentComponent<String>
private Color tabBorderColor = TAB_BORDER_COLOR;
private String pinNames = null;
private PinLabels pinLabels = null;
private PCBLayer boardSide;
transient private Area[] body;
transient private String[] parsedPinNames;
@@ -745,6 +747,16 @@ public class MultiwattIC extends AbstractTransparentComponent<String>
return new Rectangle2D.Double(minX - margin, minY - margin, maxX - minX + 2 * margin, maxY - minY + 2 * margin);
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
public static enum MultiwattType {
// Multiwatt-11: 6 pins on left, 5 pins on right (staggered)
MULTIWATT_11(11, 6, 5, new Size(1.7d, SizeUnit.mm), "Multiwatt 11"),
@@ -37,11 +37,9 @@ import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
import org.diylc.common.Percentage;
import org.diylc.components.transform.TO1Transformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -62,7 +60,7 @@ import org.diylc.utils.Constants;
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO1Transformer.class,
enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2,
datasheetModelColumn = 1)
public class TransistorTO1 extends AbstractTransistorPackage implements IBoardSideComponent {
public class TransistorTO1 extends AbstractTransistorPackage {
private static final long serialVersionUID = 1L;
@@ -79,7 +77,6 @@ public class TransistorTO1 extends AbstractTransistorPackage implements IBoardSi
private Size pinSpacing = PIN_SPACING;
private Boolean flange = true;
private PCBLayer boardSide;
public TransistorTO1() {
super();
@@ -332,14 +329,4 @@ public class TransistorTO1 extends AbstractTransistorPackage implements IBoardSi
protected boolean flipPinoutLabel() {
return true;
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
}
@@ -37,11 +37,9 @@ import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
import org.diylc.common.Percentage;
import org.diylc.components.transform.TO220Transformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -62,7 +60,7 @@ import org.diylc.utils.Constants;
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO220Transformer.class,
enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2,
datasheetModelColumn = 1)
public class TransistorTO220 extends AbstractTransistorPackage implements IBoardSideComponent {
public class TransistorTO220 extends AbstractTransistorPackage {
private static final long serialVersionUID = 1L;
@@ -85,7 +83,6 @@ public class TransistorTO220 extends AbstractTransistorPackage implements IBoard
private Color tabColor = TAB_COLOR;
private Color tabBorderColor = TAB_BORDER_COLOR;
private Size leadLength = LEAD_LENGTH;
private PCBLayer boardSide;
public TransistorTO220() {
super();
@@ -440,14 +437,4 @@ public class TransistorTO220 extends AbstractTransistorPackage implements IBoard
protected boolean flipPinoutLabel() {
return true;
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
}
@@ -36,11 +36,9 @@ import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
import org.diylc.common.Percentage;
import org.diylc.components.transform.TO92Transformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
@@ -62,7 +60,7 @@ import org.diylc.utils.Constants;
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, transformer = TO92Transformer.class,
enableCache = true, enableDatasheet = true, datasheetCreationStepCount = 2,
datasheetModelColumn = 1)
public class TransistorTO92 extends AbstractTransistorPackage implements IBoardSideComponent {
public class TransistorTO92 extends AbstractTransistorPackage {
private static final long serialVersionUID = 1L;
@@ -74,7 +72,6 @@ public class TransistorTO92 extends AbstractTransistorPackage implements IBoardS
public static Size BODY_DIAMETER = new Size(0.2d, SizeUnit.in);
private Size pinSpacing = PIN_SPACING;
private PCBLayer boardSide;
public TransistorTO92() {
super();
@@ -288,14 +285,4 @@ public class TransistorTO92 extends AbstractTransistorPackage implements IBoardS
g2d.fillOval(width / 2 - pinSize / 2, (height / 4) * (i + 1), pinSize, pinSize);
}
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
}
@@ -38,12 +38,14 @@ import org.diylc.awt.StringUtils;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractAngledComponent;
import org.diylc.components.AbstractMakerBoard;
import org.diylc.components.semiconductors.PinLabels;
import org.diylc.components.transform.AngledComponentTransformer;
import org.diylc.core.ComponentState;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDatasheetSupport;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
@@ -68,7 +70,7 @@ import org.diylc.utils.Constants;
transformer = AngledComponentTransformer.class, enableDatasheet = true,
datasheetCreationStepCount = 2, datasheetModelColumn = 1)
public class TubeSocket extends AbstractAngledComponent<String>
implements IGerberComponentSimple, IDatasheetSupport {
implements IGerberComponentSimple, IDatasheetSupport, IBoardSideComponent {
private static final Size B9A_PIN_SPACING_CHASSIS = new Size(12.5d, SizeUnit.mm);
private static final Size B9A_PIN_SPACING_PCB = new Size(21d, SizeUnit.mm);
@@ -109,6 +111,7 @@ public class TubeSocket extends AbstractAngledComponent<String>
private PinLabels pinLabels = null;
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)};
private PCBLayer boardSide;
public TubeSocket() {
super();
@@ -484,6 +487,16 @@ public class TubeSocket extends AbstractAngledComponent<String>
return new Rectangle2D.Double(rect.getX() - margin, rect.getY() - margin, rect.getWidth() + 2 * margin, rect.getHeight() + 2 * margin);
}
@EditableProperty(name = "Board Side")
@Override
public PCBLayer getBoardSide() {
return boardSide == null ? PCBLayer._2 : boardSide;
}
public void setBoardSide(PCBLayer boardSide) {
this.boardSide = boardSide;
}
public static enum Base {
B9A("Noval B9A"), OCTAL("Octal"), B7G("Small-button B7G"), B12C("Duodecar B12C"), UX4("UX4");
@@ -28,11 +28,12 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.diylc.common.ComponentType;
import org.diylc.common.PCBLayer;
import org.diylc.components.misc.Label;
import org.diylc.core.IBoardSideComponent;
import org.diylc.core.IDIYComponent;
import org.diylc.presenter.ComponentProcessor;
import org.diylc.core.gerber.GerberLayer;
import org.diylc.core.gerber.IGerberComponentSimple;
import org.diylc.utils.ReflectionUtils;
import org.junit.Test;
@@ -55,14 +56,20 @@ public class BoardSideComponentsTest {
}
}
// a part moved to the bottom is seen mirrored from the top, so it must be possible to mirror it
// a part that writes its silkscreen to the top layer can sit on either side; Label is text rather
// than a mounted part, and PCBText has a layer of its own
@Test
public void testBoardSideComponentsCanBeMirrored() throws Exception {
for (IDIYComponent<?> component : createBoardSideComponents()) {
@SuppressWarnings("unchecked")
ComponentType type = ComponentProcessor.getInstance().extractComponentTypeFrom(
(Class<? extends IDIYComponent<?>>) component.getClass());
assertTrue(component.getClass().getName(), type.getTransformer().canMirror(component));
public void testEveryTopSilkscreenPartHasABoardSide() throws Exception {
for (Class<?> type : ReflectionUtils.getIndexedClasses(IDIYComponent.class)) {
if (Modifier.isAbstract(type.getModifiers())
|| !IGerberComponentSimple.class.isAssignableFrom(type) || type == Label.class) {
continue;
}
IGerberComponentSimple component =
(IGerberComponentSimple) type.getDeclaredConstructor().newInstance();
if (component.getGerberLayer() == GerberLayer.SilkscreenTop) {
assertTrue(type.getName(), component instanceof IBoardSideComponent);
}
}
}
+16 -19
View File
@@ -3,7 +3,7 @@
Let a component be mounted on the bottom of a PCB, so that its silkscreen goes to the bottom
Gerber layers and the canvas shows it as a part on the far side of the board.
Status: 32 parts have a Board Side property, and Gerber export sends a bottom-side part's
Status: 45 parts have a Board Side property, and Gerber export sends a bottom-side part's
silkscreen to the bottom layer with its text mirrored. Parts can be selected, dragged and stretched
through the Underside Display mirror. The canvas draws a bottom-side part faded in the main view and
solid in the mirror. The next steps below remain.
@@ -61,26 +61,23 @@ solid in the mirror. The next steps below remain.
### diylc-library
- **Done.** Every part that uses the `SilkscreenTop` default and whose transformer can mirror it
implements `IBoardSideComponent`: a nullable `PCBLayer boardSide` field and a getter/setter pair
with `@EditableProperty(name = "Board Side")` on the getter, which returns `_2` (Top) when the
field is `null`. The key is in every language file.
- **Done.** Every part that uses the `SilkscreenTop` default implements `IBoardSideComponent`: a
nullable `PCBLayer boardSide` field and a getter/setter pair with
`@EditableProperty(name = "Board Side")` on the getter, which returns `_2` (Top) when the field
is `null`. The key is in every language file. 45 parts have it.
- On a shared base, covering every subclass: `AbstractFilmCapacitor`, `AbstractPotentiometer`,
`AbstractRadialComponent`, `PassiveSMDComponent`.
`AbstractRadialComponent`, `AbstractTransistorPackage`, `PassiveSMDComponent`.
- On the class itself: `Resistor`, `HeatSinkResistor`, `AxialElectrolyticCapacitor`,
`CrystalOscillator`, `ToroidalInductor`, `DiodePlastic`, `DiodeGlass`, `DIL_IC`, `SIL_IC`,
`TransistorTO1`, `TransistorTO92`, `TransistorTO220`, `CliffJack1_4`, `CliffJack1_8`,
`ClosedJack1_4`, `MiniToggleSwitch`, `PCBTerminalBlock`. The transistors are not done on
`AbstractTransistorPackage` because `TransistorTO126` cannot be mirrored, and a property on the
base cannot be hidden from one subclass.
- Left out because they cannot be mirrored: `TubeSocket`, `RotarySwitchOpen`,
`RotarySwitchSealed`, `RotarySelectorSwitch`, `SlideSwitch`, `PlasticDCJack`,
`TactileMicroSwitch`, `MiniRelay`, `AudioTransformer`, `MultiSectionCapacitor`, `MultiwattIC`,
`BridgeRectifier`, `TransistorTO126`. Making one of them mirrorable is what it takes to give it
a side.
- `Label` is left out too: it is text, not a mounted part, and `PCBText` already has a layer.
- `BoardSideComponentsTest` checks that every such part starts on Top, takes Bottom, and can be
mirrored.
`CrystalOscillator`, `ToroidalInductor`, `AudioTransformer`, `MultiSectionCapacitor`,
`DiodePlastic`, `DiodeGlass`, `BridgeRectifier`, `DIL_IC`, `SIL_IC`, `MultiwattIC`,
`TubeSocket`, `CliffJack1_4`, `CliffJack1_8`, `ClosedJack1_4`, `PlasticDCJack`,
`MiniToggleSwitch`, `SlideSwitch`, `TactileMicroSwitch`, `RotarySwitchOpen`,
`RotarySwitchSealed`, `RotarySelectorSwitch`, `MiniRelay`, `PCBTerminalBlock`.
- Whether a part can be mirrored does not matter: the app never mirrors it for the user.
- `Label` is left out: it is text, not a mounted part, and `PCBText` already has a layer.
- `BoardSideComponentsTest` checks that every such part starts on Top and takes Bottom, and
that every part writing `SilkscreenTop` has a side, so a new part cannot be left out by
accident.
- `CopperTrace`, `CurvedTrace`, `GroundFill`, `SolderPad`, `PCBText` and `DrillHole` do **not**
implement it. Their `PCBLayer` already says where they are.