Building blocks (#1072)

* composite block support

* naming

* Added ability to set node name (or names) for some connectivity components

* cleanup

* Include building blocks in the Recently Used category

* Prompt to confirm the overwrite when saving over the existing building blocks; When saving building blocks, present a drop down list with most recently used building blocks

* add alpha to composite

* Update CompositeComponentTest.java

* cleanup

* Update CompositeComponent.java

* cleanup

* Update CompositeComponent.java

* <org.diylc.appframework.update.Change> 					<changeType>IMPROVEMENT</changeType> 					<description>When saving building blocks, present a drop down list with most recently used building blocks for quick selection</description> 				</org.diylc.appframework.update.Change>

* Diode components now label their terminal nodes as 'A' (anode) and 'K' (cathode) instead of '1' and '2'

* Capacitor components now label their terminal nodes as '+' and '-' instead of '1' and '2' when 'Polarized' property is ticked
This commit is contained in:
Bane Stojkovic
2026-09-04 15:32:46 +02:00
committed by GitHub
parent 26d6ca48fd
commit 047196499a
40 changed files with 1939 additions and 95 deletions
@@ -62,6 +62,7 @@ public class Eyelet extends AbstractTransparentComponent<String> {
private Color color = COLOR;
private Point2D.Double point = new Point2D.Double(0, 0);
private String value = "";
private String nodeName = "";
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
@@ -173,9 +174,22 @@ public class Eyelet extends AbstractTransparentComponent<String> {
this.value = value;
}
@EditableProperty(name = "Node Name", defaultable = false)
public String getNodeName() {
if (nodeName == null) {
nodeName = "";
}
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
@Override
public String getControlPointNodeName(int index) {
return null;
public String getControlPointNodeName(int index) {
String n = getNodeName();
return n.trim().isEmpty() ? null : n.trim();
}
@Override
@@ -71,6 +71,7 @@ public class PCBTerminalBlock extends AbstractTransparentComponent<PCBTerminalBl
private Size pitch = new Size(0.2d, SizeUnit.in);
private Size width = new Size(0.3d, SizeUnit.in);
private ScrewPosition screwPosition = ScrewPosition.Offset;
private String nodeNames = "";
public PCBTerminalBlock() {
super();
@@ -330,10 +331,30 @@ public class PCBTerminalBlock extends AbstractTransparentComponent<PCBTerminalBl
}
@EditableProperty(name = "Node Names", defaultable = false)
public String getNodeNames() {
if (nodeNames == null) {
nodeNames = "";
}
return nodeNames;
}
public void setNodeNames(String nodeNames) {
this.nodeNames = nodeNames;
}
@Override
public String getControlPointNodeName(int index) {
// we don't want the block to produce any nodes, it just makes connections
return null;
// By default the block produces no nodes, it just makes connections. Once the user
// assigns explicit node names, each labeled point becomes a named node; unlabeled
// points fall back to their ordinal number.
String raw = getNodeNames();
if (raw.trim().isEmpty()) {
return null;
}
String[] parts = raw.split(",", -1);
String label = index < parts.length ? parts[index].trim() : "";
return label.isEmpty() ? Integer.toString(index + 1) : label;
}
@Override
@@ -71,6 +71,7 @@ public class SolderPad extends AbstractTransparentComponent<Void>
private Size holeSize = HOLE_SIZE;
private PCBLayer layer = PCBLayer._1;
private HoleType holeType = HoleType.NTPH;
private String nodeName = "";
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
@@ -246,9 +247,22 @@ public class SolderPad extends AbstractTransparentComponent<Void>
return null;
}
@EditableProperty(name = "Node Name", defaultable = false)
public String getNodeName() {
if (nodeName == null) {
nodeName = "";
}
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
@Override
public String getControlPointNodeName(int index) {
return null;
String n = getNodeName();
return n.trim().isEmpty() ? null : n.trim();
}
@Override
@@ -60,6 +60,7 @@ public class Turret extends AbstractTransparentComponent<String> {
private Color color = COLOR;
private Point2D.Double point = new Point2D.Double(0, 0);
private String value = "";
private String nodeName = "";
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
@@ -168,9 +169,22 @@ public class Turret extends AbstractTransparentComponent<String> {
this.value = value;
}
@EditableProperty(name = "Node Name", defaultable = false)
public String getNodeName() {
if (nodeName == null) {
nodeName = "";
}
return nodeName;
}
public void setNodeName(String nodeName) {
this.nodeName = nodeName;
}
@Override
public String getControlPointNodeName(int index) {
return null;
public String getControlPointNodeName(int index) {
String n = getNodeName();
return n.trim().isEmpty() ? null : n.trim();
}
@Override
@@ -71,6 +71,7 @@ public class PinHeader extends AbstractTransparentComponent<Void> {
private int columnCount = 5;
private Size spacing = PIN_SPACING;
private Boolean shrouded = false;
private String nodeNames = "";
private Color bodyColor = BODY_COLOR;
private Color shroudColor = BODY_COLOR.darker();
@@ -342,6 +343,31 @@ public class PinHeader extends AbstractTransparentComponent<Void> {
this.shroudColor = shroudColor;
}
@EditableProperty(name = "Node Names", defaultable = false)
public String getNodeNames() {
if (nodeNames == null) {
nodeNames = "";
}
return nodeNames;
}
public void setNodeNames(String nodeNames) {
this.nodeNames = nodeNames;
}
@Override
public String getControlPointNodeName(int index) {
// Comma-separated list, one entry per pin in control point order. When the list is
// blank, or an individual entry is missing/blank, the pin keeps its ordinal number.
String raw = getNodeNames();
if (raw.trim().isEmpty()) {
return Integer.toString(index + 1);
}
String[] parts = raw.split(",", -1);
String label = index < parts.length ? parts[index].trim() : "";
return label.isEmpty() ? Integer.toString(index + 1) : label;
}
@Override
public boolean canPointMoveFreely(int pointIndex) {
return false;
@@ -203,6 +203,19 @@ public class AxialElectrolyticCapacitor extends AbstractLeadedComponent<Capacita
this.polarized = polarized;
}
@Override
public String getControlPointNodeName(int index) {
if (getPolarized()) {
switch (index) {
case 0:
return "+";
case 1:
return "-";
}
}
return super.getControlPointNodeName(index);
}
@Override
protected Shape getBodyShape() {
double lengthFinal = getLength().convertToPixels();
@@ -96,6 +96,19 @@ public class CapacitorSymbol extends AbstractSchematicLeadedSymbol<Capacitance>
this.polarized = polarized;
}
@Override
public String getControlPointNodeName(int index) {
if (getPolarized()) {
switch (index) {
case 0:
return "+";
case 1:
return "-";
}
}
return super.getControlPointNodeName(index);
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR);
@@ -72,6 +72,7 @@ public class RadialElectrolytic extends AbstractRadialComponent<Capacitance> imp
private boolean polarized = true;
private boolean folded = false;
private Size height = HEIGHT;
@Deprecated
private boolean invert = false;
public RadialElectrolytic() {
@@ -304,7 +305,7 @@ public class RadialElectrolytic extends AbstractRadialComponent<Capacitance> imp
this.height = height;
}
@EditableProperty(name = "Invert Polarity")
// @EditableProperty(name = "Invert Polarity")
public boolean getInvert() {
return invert;
}
@@ -313,6 +314,19 @@ public class RadialElectrolytic extends AbstractRadialComponent<Capacitance> imp
this.invert = invert;
}
@Override
public String getControlPointNodeName(int index) {
if (getPolarized()) {
switch (index) {
case 0:
return getInvert() ? "-" : "+";
case 1:
return getInvert() ? "+" : "-";
}
}
return super.getControlPointNodeName(index);
}
@Override
protected Shape getBodyShape() {
double height = (int) getHeight().convertToPixels();
@@ -85,6 +85,18 @@ public abstract class AbstractDiodeSymbol extends AbstractSchematicLeadedSymbol<
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {}
@Override
public String getControlPointNodeName(int index) {
switch (index) {
case 0:
return "A";
case 1:
return "K";
default:
return null;
}
}
@Deprecated
@Override
public Size getLength() {
@@ -244,6 +244,9 @@ public abstract class AbstractTransistorPackage extends AbstractLabeledComponent
public String getControlPointNodeName(int index) {
if (index >= 3)
return null;
if (getPinout() != null) {
return getPinout().toPinout().substring(index, index + 1);
}
return Integer.toString(index + 1);
}
@@ -92,6 +92,18 @@ public class DiodeGlass extends AbstractLeadedComponent<String> implements IGerb
this.value = value;
}
@Override
public String getControlPointNodeName(int index) {
switch (index) {
case 0:
return "A";
case 1:
return "K";
default:
return null;
}
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR_ICON);
@@ -90,6 +90,18 @@ public class DiodePlastic extends AbstractLeadedComponent<String> implements IGe
this.value = value;
}
@Override
public String getControlPointNodeName(int index) {
switch (index) {
case 0:
return "A";
case 1:
return "K";
default:
return null;
}
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR_ICON);
@@ -67,6 +67,18 @@ public class LED extends AbstractLeadedComponent<String> implements IGerberCompo
this.value = value;
}
@Override
public String getControlPointNodeName(int index) {
switch (index) {
case 0:
return "A";
case 1:
return "K";
default:
return null;
}
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.rotate(-Math.PI / 4, width / 2, height / 2);