From 15277452f41215e86f3264d886f381e4133b860f Mon Sep 17 00:00:00 2001 From: Bane Stojkovic Date: Sat, 31 Oct 2026 20:21:04 +0100 Subject: [PATCH] Re-modeled factory variants of Resistor component type as datasheet in order to make them available to the AI; this will produce more accurate AI-driven edits --- diylc/catalog_full.json | 8 +- .../main/java/org/diylc/core/Template.java | 15 + .../service/ComponentCatalogGenerator.java | 10 + .../org/diylc/presenter/VariantManager.java | 19 +- .../resources/import-defaults/variants.xml | 1286 +---------------- .../diylc-core/src/main/resources/update.xml | 264 +--- .../src/main/resources/update_archive.xml | 248 ++++ .../diylc/components/passive/Resistor.java | 43 +- .../resources/datasheets/Resistor.datasheet | 22 + .../diylc/components/DeletedVariantsTest.java | 196 +++ .../diylc/components/FactoryVariantsTest.java | 3 + .../passive/ResistorDatasheetTest.java | 88 ++ 12 files changed, 690 insertions(+), 1512 deletions(-) create mode 100644 diylc/diylc-library/src/main/resources/datasheets/Resistor.datasheet create mode 100644 diylc/diylc-library/src/test/java/org/diylc/components/DeletedVariantsTest.java create mode 100644 diylc/diylc-library/src/test/java/org/diylc/components/passive/ResistorDatasheetTest.java diff --git a/diylc/catalog_full.json b/diylc/catalog_full.json index 01f59b2d..3eb94eed 100644 --- a/diylc/catalog_full.json +++ b/diylc/catalog_full.json @@ -12229,6 +12229,7 @@ "description" : "Axial electrolytic capacitor, similar to Sprague Atom, F&T, etc", "creationMethod" : "POINT_BY_POINT", "notes" : [ "The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing", "It has no standing mode: keep the control points at least 'Length' apart, or the body is drawn past the holes" ], + "datasheetModels" : [ "F&T Typ A", "Illinois TTA", "JJ ANH", "Sprague TVA Atom" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", @@ -12343,6 +12344,7 @@ "description" : "Vertically mounted electrolytic capacitor, polarized or bipolar", "creationMethod" : "POINT_BY_POINT", "notes" : [ "The two control points are the holes; the body's own leads are 'Lead Spacing' apart and centred between them, with lead wire drawn out to each hole. Place the points exactly 'Lead Spacing' apart for straight leads", "'Diameter' is the can as seen from above; 'Height' is drawn only when 'Folded' lays the can on its side" ], + "datasheetModels" : [ "Elna Silmic II", "Nichicon FG", "Nichicon FW", "Nichicon KZ", "Panasonic FC", "Panasonic FM", "Panasonic NHG" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", @@ -12467,6 +12469,7 @@ "description" : "Axial film capacitor, similar to Mallory 150s", "creationMethod" : "POINT_BY_POINT", "notes" : [ "The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing", "If the control points are closer together than 'Length' (0.5in by default) the part is drawn standing, its body over the first point, or over the second with 'Reverse (standing)'; to keep it lying on a tighter footprint, reduce 'Length'" ], + "datasheetModels" : [ "Mallory 150", "Solen Fast" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", @@ -12563,6 +12566,7 @@ "description" : "Radial film capacitor, similar to Sprague Orange Drop", "creationMethod" : "POINT_BY_POINT", "notes" : [ "The two control points are the holes; the body's own leads are 'Lead Spacing' apart and centred between them, with lead wire drawn out to each hole. Place the points exactly 'Lead Spacing' apart for straight leads", "'Length' and 'Width' are the body as seen from above: 'Length' runs along the line between the leads and 'Width' across it, i.e. the datasheet width and thickness; body height is not drawn" ], + "datasheetModels" : [ "Epcos MKT (5mm)", "Epcos MKT (7.5mm)", "Epcos MKT (10mm)", "Orange Drop 225P", "Orange Drop 715P", "Orange Drop 716P", "WIMA FKP-02 (2.5mm)", "WIMA FKP-2 (5mm)", "WIMA FKS-2 (5mm)", "WIMA MKP-2 (5mm)", "WIMA MKP-4", "WIMA MKS-02 (2.5mm)", "WIMA MKS-2 (5mm)", "WIMA MKS-4" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", @@ -12965,6 +12969,7 @@ "description" : "Standard radial mica capacitor", "creationMethod" : "POINT_BY_POINT", "notes" : [ "The two control points are the holes; the body's own leads are 'Lead Spacing' apart and centred between them, with lead wire drawn out to each hole. Place the points exactly 'Lead Spacing' apart for straight leads" ], + "datasheetModels" : [ "Cornell Dubilier CD10 (3.6mm)", "Cornell Dubilier CD15 (5.9mm)", "Cornell Dubilier CD19 (8.7mm)", "Cornell Dubilier CDV19 (8.7mm)", "Cornell Dubilier CD30 (11.1mm)", "Cornell Dubilier CDV30 (11.1mm)", "Cornell Dubilier CD42 (27mm)" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", @@ -13496,7 +13501,8 @@ "namePrefix" : "R", "description" : "Resistor layout symbol", "creationMethod" : "POINT_BY_POINT", - "notes" : [ "The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing", "If the control points are closer together than 'Length' (0.5in by default) the part is drawn standing, its body over the first point; to keep it lying on a tighter footprint, reduce 'Length'" ], + "notes" : [ "The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing", "If the control points are closer together than 'Length' (0.5in by default) the part is drawn standing, its body over the first point; to keep it lying on a tighter footprint, reduce 'Length'", "A datasheet model sets the body size, shape and colors of a resistor family at one power rating but never the resistance; set 'Power Rating' together with the model to pick the matching size" ], + "datasheetModels" : [ "Carbon Comp", "Carbon Film", "Metal Film", "Metal Oxide", "Ceramic", "Dale CMF55", "Dale CMF60" ], "properties" : [ { "name" : "Alpha", "type" : "Percentage", diff --git a/diylc/diylc-core/src/main/java/org/diylc/core/Template.java b/diylc/diylc-core/src/main/java/org/diylc/core/Template.java index 9129fbf7..990d1b4c 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/core/Template.java +++ b/diylc/diylc-core/src/main/java/org/diylc/core/Template.java @@ -25,6 +25,7 @@ import java.awt.geom.Point2D; import java.time.LocalDateTime; import java.util.List; import java.util.Map; +import java.util.Objects; public class Template { @@ -35,6 +36,8 @@ public class Template { @Deprecated private boolean defaultFlag; private LocalDateTime createdOn; + // set only on a factory variant that has been withdrawn, which then carries nothing but its name + private LocalDateTime deletedOn; public Template() { } @@ -82,11 +85,20 @@ public class Template { this.createdOn = createdOn; } + public LocalDateTime getDeletedOn() { + return deletedOn; + } + + public void setDeletedOn(LocalDateTime deletedOn) { + this.deletedOn = deletedOn; + } + @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((createdOn == null) ? 0 : createdOn.hashCode()); + result = prime * result + ((deletedOn == null) ? 0 : deletedOn.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((points == null) ? 0 : points.hashCode()); result = prime * result + ((values == null) ? 0 : values.hashCode()); @@ -107,6 +119,9 @@ public class Template { return false; } else if (!createdOn.equals(other.createdOn)) return false; + if (!Objects.equals(deletedOn, other.deletedOn)) { + return false; + } if (name == null) { if (other.name != null) return false; diff --git a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ComponentCatalogGenerator.java b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ComponentCatalogGenerator.java index 69a70b42..1104738e 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ComponentCatalogGenerator.java +++ b/diylc/diylc-core/src/main/java/org/diylc/plugins/chatbot/service/ComponentCatalogGenerator.java @@ -175,6 +175,16 @@ public class ComponentCatalogGenerator { comp.put("notes", notes); } + // a datasheet lists one row per part, so the model names are its distinct first column + List datasheet = ct.getDatasheet(); + if (datasheet != null) { + List models = datasheet.stream() + .map(row -> row[0].trim()) + .distinct() + .collect(Collectors.toList()); + comp.put("datasheetModels", models); + } + // Extract editable properties try { List properties = processor.extractProperties(ct.getInstanceClass()); diff --git a/diylc/diylc-core/src/main/java/org/diylc/presenter/VariantManager.java b/diylc/diylc-core/src/main/java/org/diylc/presenter/VariantManager.java index 9fa0a37f..97c5c0d0 100644 --- a/diylc/diylc-core/src/main/java/org/diylc/presenter/VariantManager.java +++ b/diylc/diylc-core/src/main/java/org/diylc/presenter/VariantManager.java @@ -65,6 +65,7 @@ public class VariantManager { .readObject(IPlugInPort.DEFAULT_TEMPLATES_IMPORT_DATE_KEY, LocalDateTime.MIN); int importCount = 0; + int deleteCount = 0; try { InputStream inputStream = Presenter.class.getResourceAsStream("/" + VARIANTS_FILE_NAME); @@ -89,7 +90,20 @@ public class VariantManager { .collect(Collectors.toSet()); for (Template variant : entry.getValue()) { - if ((variant.getCreatedOn() == null || importDate.compareTo(variant.getCreatedOn()) < 0) + // a deletion stub keeps nothing but its name, so a missing createdOn only means an old + // entry when the variant has not been deleted + boolean created = variant.getCreatedOn() == null ? variant.getDeletedOn() == null + : importDate.compareTo(variant.getCreatedOn()) < 0; + boolean deleted = + variant.getDeletedOn() != null && importDate.compareTo(variant.getDeletedOn()) < 0; + // a variant created and deleted since the last import never reached the user, and a + // deletion older than the last import was applied then, so a variant the user has since + // created under the same name stays + if (deleted && !created) { + if (existingVariants.removeIf(x -> variant.getName().equals(x.getName()))) { + deleteCount++; + } + } else if (created && variant.getDeletedOn() == null && !existingNames.contains(variant.getName())) { existingVariants.add(variant); importCount++; @@ -104,6 +118,9 @@ public class VariantManager { if (importCount > 0) { LOG.info(String.format("Imported default %d variants", importCount)); } + if (deleteCount > 0) { + LOG.info(String.format("Deleted %d withdrawn default variants", deleteCount)); + } } catch (Exception e) { LOG.error("Could not load default variants", e); } diff --git a/diylc/diylc-core/src/main/resources/import-defaults/variants.xml b/diylc/diylc-core/src/main/resources/import-defaults/variants.xml index 22063a70..4a95774d 100644 --- a/diylc/diylc-core/src/main/resources/import-defaults/variants.xml +++ b/diylc/diylc-core/src/main/resources/import-defaults/variants.xml @@ -213,1326 +213,92 @@ 1/2W Carbon Comp - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - _5_BAND - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2022-10-30T13:25:15.3894874 + 2026-10-31T20:15:00 1/4W Carbon Comp - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - _5_BAND - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2022-10-30T13:25:15.3894874 + 2026-10-31T20:15:00 1/2W Carbon Film - - - Shape - Standard - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - _5_BAND - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2022-10-30T13:25:15.3894874 + 2026-10-31T20:15:00 1/4W Carbon Film - - - Shape - Standard - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - _5_BAND - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2022-10-30T13:25:15.3894874 + 2026-10-31T20:15:00 1/4W Metal Film - - - Shape - Standard - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - _5_BAND - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2022-10-30T13:25:15.3894874 + 2026-10-31T20:15:00 1/2W Metal Film - - - Shape - Standard - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - _5_BAND - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2022-10-30T13:25:15.3894874 + 2026-10-31T20:15:00 2W Metal Oxide - - - Shape - Standard - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - _5_BAND - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2022-10-30T13:25:15.3894874 + 2026-10-31T20:15:00 Ceramic 2W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 3W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 5W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 7W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 10W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 15W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 20W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 30W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 50W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 80W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 Ceramic 100W - - - Shape - Tubular - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - NONE - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2026-04-02T20:39:46.0000000 + 2026-10-31T20:15:00 1W Metal Oxide - - - Shape - Standard - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - _5_BAND - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2022-10-30T13:25:15.3894874 + 2026-10-31T20:15:00 3W Metal Oxide - - - Shape - Standard - - - Color - - - - Power Rating - - - - Reverse (standing) - false - - - Lead Color - - - - Label Color - - - - Length - - - - Value - - - - Color code - _5_BAND - - - Border - - - - Width - - - - Display - NAME - - - - - - - false - 2022-10-30T13:25:15.3894874 + 2026-10-31T20:15:00 - Dale C*F55 - - - Power Rating - - - - Shape - Tubular_Beveled - - - Color - - - - Moveable Label - false - - - Label Orientation - Directional - - - Reverse (standing) - false - - - Font Size Override - - - - Lead Color - - - - Length - - - - Label Color - - - - Value - - - - Color code - _5_BAND - - - Width - - - - Border - - - - Display - NAME - - - - - - - false - 2022-11-07T23:50:13.9473581 - + Dale C*F55 + 2026-10-31T20:15:00 + - Dale C*F60 - - - Power Rating - - - - Shape - Tubular_Beveled - - - Color - - - - Moveable Label - false - - - Label Orientation - Directional - - - Reverse (standing) - false - - - Font Size Override - - - - Lead Color - - - - Length - - - - Label Color - - - - Value - - - - Color code - _5_BAND - - - Width - - - - Border - - - - Display - NAME - - - - - - - false - 2022-11-07T23:48:34.7774065 - + Dale C*F60 + 2026-10-31T20:15:00 + diff --git a/diylc/diylc-core/src/main/resources/update.xml b/diylc/diylc-core/src/main/resources/update.xml index b8da936b..4cf2d4fa 100644 --- a/diylc/diylc-core/src/main/resources/update.xml +++ b/diylc/diylc-core/src/main/resources/update.xml @@ -1,253 +1,5 @@ - - - 5 - 10 - 0 - - 2026-01-20 00:00:00.000 CET - - - - NEW_FEATURE - Added 'M' and 'N' potentiometer taper options (thank you mm-rnd) - - - NEW_FEATURE - Added E-C-B BJT pinout to TO-92 transistor package - - - BUG_FIX - Fixed the performance issue that happens when groups of components are copy-pasted and the project size grows uncontrollably - - - BUG_FIX - All building blocks of the same type get added to the same group - - - BUG_FIX - 'Tactile Micro Switch' editor doesn't show up on double click - - - https://github.com/bancika/diy-layout-creator/releases - - - - 5 - 11 - 0 - - 2026-02-15 00:00:00.000 CET - - - - NEW_FEATURE - Added ability to export chat history from 'AI Assistant' to a HTML file - - - IMPROVEMENT - Upgraded AI models for AI-powered tools and improved overall quality of the responses - - - IMPROVEMENT - Windows installer prompts for installation folder instead of forcing one - - - IMPROVEMENT - Shape components shouldn't appear in the BOM - - - IMPROVEMENT - Improved rendering of 'Switch (Latching)' symbol to clearly make visual contact between the terminals - - - IMPROVEMENT - Consolidate a few keyboard shortcuts for consistency - - - BUG_FIX - Using "Duplicate Selection" results in duplicates of component ids, breaking Project Explorer panel and causing other issues downstream - - - BUG_FIX - Calculated length disappeared from Hookup Wire and similar curved components - - - BUG_FIX - Resize dimensions do not show for 'Chassis Panel' component when dragging a corner point - - - https://github.com/bancika/diy-layout-creator/releases - - - - 5 - 12 - 0 - - 2026-03-26 00:00:00.000 CET - - - - NEW_FEATURE - Added 'Auto-Unit Conversion' configuration which automatically converts between metric and imperial units based on the ruler unit preference - - - NEW_FEATURE - Added a new section in the output of 'AI Circuit Analyzer' which provides insights into the operation of the circuit and individual components - - - IMPROVEMENT - Better error handling for AI tools - - - IMPROVEMENT - Pressing the 'Esc' key closes selection editor dialog - - - BUG_FIX - Right click (or two finger tap on mac) after selecting a component with a regular click opens editor dialog in addition to the context menu - - - BUG_FIX - Clicking on a component type in the left-hand component tree sometimes does not register and does not instantiate the component - - - https://github.com/bancika/diy-layout-creator/releases - - - - 5 - 13 - 0 - - 2026-04-07 00:00:00.000 CET - - - - NEW_FEATURE - Added new 'Heat Sink Resistor' component with a bunch of factory variants covering the most common types - - - NEW_FEATURE - Added new 'Dial Scale' variations - 'Ticks + Numeric (0/5.5/11)' a'la Friedman and another variation of 'Ticks' with more pronounced 9/12/3 o'clock indices - - - NEW_FEATURE - Added 'Core' property to 'Radial Inductor' component that allows selection between Ferrite and Air core inductor models' - - - NEW_FEATURE - Added 'Envelope' property to tube symbol components which can be used to display one side of the outer envelope dashed indicating section A or section B of a tube - - - NEW_FEATURE - Added more ceramic resistor variants to 'Resistor' component - - - IMPROVEMENT - Uniformized rendering of components while being dragged - - - IMPROVEMENT - Ability to blank-out previously populated values for unit-type measures, e.g. resistance, capacitance, dimensions, etc - - - IMPROVEMENT - Improved data model for storing transparency alpha and other properties that are edited using a slider widget; as a result, the editing is more precise and does not randomly change to neighboring values - - - IMPROVEMENT - Improved editing experience of integer properties (e.g. number of terminals on a tag strip) by using the spinner text field - - - IMPROVEMENT - Improved logic when moving component(s) that have other components stuck with them; in case there are non-sticky control points within the included components, they will be moved along retaining component shape (e.g. wires or curved traces) - - - IMPROVEMENT - Decommission 'Loadline Editor' option from the File menu - - - https://github.com/bancika/diy-layout-creator/releases - - - - 5 - 14 - 0 - - 2026-06-03 00:00:00.000 CET - - - - NEW_FEATURE - Added 'Potentiometer (Miniature)' component with two variations - right-angled and vertically mounted - - - NEW_FEATURE - Added 'Thonk 3.5mm Jack' component with two variations - mono switched and stereo - - - IMPROVEMENT - Enable all types of potentiometers and jacks for guitar diagram analysis - - - IMPROVEMENT - Increase maximum number of switch combination for analysis to 1024 - - - IMPROVEMENT - 'Line' component set to px used to render slightly thicker than 1px, appearing thicker than schematic symbols; changed to match the thickenss of schematic symbols - - - https://github.com/bancika/diy-layout-creator/releases - - - - 5 - 15 - 0 - - 2026-06-13 00:00:00.000 CET - - - - NEW_FEATURE - Add Freeway Blade switches 3B3-01, 5B5-01, 5B5-02 (thank you Martin Morell) - - - NEW_FEATURE - IEC variations of fuse and potentiometer symbols - - - NEW_FEATURE - Detect the style of a treble bleed based on the topology and component values (e.g. Fender, DiMarzio, Kinman, etc) - - - IMPROVEMENT - Improved quality of AI Assistant responses in some cases - - - IMPROVEMENT - Improved precision of rendering, in some cases there was a sub-pixel misalignment between the lines that should meet exactly - - - BUG_FIX - Tone capacitor mistaken for treble bleed when connected to the input lug of the volume pot - - - BUG_FIX - Dragging a component from the component tree to the canvas sometimes does not work as expected without clicking on it first and then dragging it - - - BUG_FIX - 'Schaller Megaswitch' not rendered correctly when rotated for 90 or 270 degrees - - - https://github.com/bancika/diy-layout-creator/releases - 6 @@ -744,5 +496,21 @@ https://github.com/bancika/diy-layout-creator/releases + + + 6 + 10 + 0 + + 2026-10-30 00:00:00.000 CET + + + + IMPROVEMENT + Re-modeled factory variants of Resistor component type as datasheet in order to make them available to the AI; this will produce more accurate AI-driven edits + + + https://github.com/bancika/diy-layout-creator/releases + diff --git a/diylc/diylc-core/src/main/resources/update_archive.xml b/diylc/diylc-core/src/main/resources/update_archive.xml index 614d543d..34b15306 100644 --- a/diylc/diylc-core/src/main/resources/update_archive.xml +++ b/diylc/diylc-core/src/main/resources/update_archive.xml @@ -5325,5 +5325,253 @@ https://github.com/bancika/diy-layout-creator/releases + + + 5 + 10 + 0 + + 2026-01-20 00:00:00.000 CET + + + + NEW_FEATURE + Added 'M' and 'N' potentiometer taper options (thank you mm-rnd) + + + NEW_FEATURE + Added E-C-B BJT pinout to TO-92 transistor package + + + BUG_FIX + Fixed the performance issue that happens when groups of components are copy-pasted and the project size grows uncontrollably + + + BUG_FIX + All building blocks of the same type get added to the same group + + + BUG_FIX + 'Tactile Micro Switch' editor doesn't show up on double click + + + https://github.com/bancika/diy-layout-creator/releases + + + + 5 + 11 + 0 + + 2026-02-15 00:00:00.000 CET + + + + NEW_FEATURE + Added ability to export chat history from 'AI Assistant' to a HTML file + + + IMPROVEMENT + Upgraded AI models for AI-powered tools and improved overall quality of the responses + + + IMPROVEMENT + Windows installer prompts for installation folder instead of forcing one + + + IMPROVEMENT + Shape components shouldn't appear in the BOM + + + IMPROVEMENT + Improved rendering of 'Switch (Latching)' symbol to clearly make visual contact between the terminals + + + IMPROVEMENT + Consolidate a few keyboard shortcuts for consistency + + + BUG_FIX + Using "Duplicate Selection" results in duplicates of component ids, breaking Project Explorer panel and causing other issues downstream + + + BUG_FIX + Calculated length disappeared from Hookup Wire and similar curved components + + + BUG_FIX + Resize dimensions do not show for 'Chassis Panel' component when dragging a corner point + + + https://github.com/bancika/diy-layout-creator/releases + + + + 5 + 12 + 0 + + 2026-03-26 00:00:00.000 CET + + + + NEW_FEATURE + Added 'Auto-Unit Conversion' configuration which automatically converts between metric and imperial units based on the ruler unit preference + + + NEW_FEATURE + Added a new section in the output of 'AI Circuit Analyzer' which provides insights into the operation of the circuit and individual components + + + IMPROVEMENT + Better error handling for AI tools + + + IMPROVEMENT + Pressing the 'Esc' key closes selection editor dialog + + + BUG_FIX + Right click (or two finger tap on mac) after selecting a component with a regular click opens editor dialog in addition to the context menu + + + BUG_FIX + Clicking on a component type in the left-hand component tree sometimes does not register and does not instantiate the component + + + https://github.com/bancika/diy-layout-creator/releases + + + + 5 + 13 + 0 + + 2026-04-07 00:00:00.000 CET + + + + NEW_FEATURE + Added new 'Heat Sink Resistor' component with a bunch of factory variants covering the most common types + + + NEW_FEATURE + Added new 'Dial Scale' variations - 'Ticks + Numeric (0/5.5/11)' a'la Friedman and another variation of 'Ticks' with more pronounced 9/12/3 o'clock indices + + + NEW_FEATURE + Added 'Core' property to 'Radial Inductor' component that allows selection between Ferrite and Air core inductor models' + + + NEW_FEATURE + Added 'Envelope' property to tube symbol components which can be used to display one side of the outer envelope dashed indicating section A or section B of a tube + + + NEW_FEATURE + Added more ceramic resistor variants to 'Resistor' component + + + IMPROVEMENT + Uniformized rendering of components while being dragged + + + IMPROVEMENT + Ability to blank-out previously populated values for unit-type measures, e.g. resistance, capacitance, dimensions, etc + + + IMPROVEMENT + Improved data model for storing transparency alpha and other properties that are edited using a slider widget; as a result, the editing is more precise and does not randomly change to neighboring values + + + IMPROVEMENT + Improved editing experience of integer properties (e.g. number of terminals on a tag strip) by using the spinner text field + + + IMPROVEMENT + Improved logic when moving component(s) that have other components stuck with them; in case there are non-sticky control points within the included components, they will be moved along retaining component shape (e.g. wires or curved traces) + + + IMPROVEMENT + Decommission 'Loadline Editor' option from the File menu + + + https://github.com/bancika/diy-layout-creator/releases + + + + 5 + 14 + 0 + + 2026-06-03 00:00:00.000 CET + + + + NEW_FEATURE + Added 'Potentiometer (Miniature)' component with two variations - right-angled and vertically mounted + + + NEW_FEATURE + Added 'Thonk 3.5mm Jack' component with two variations - mono switched and stereo + + + IMPROVEMENT + Enable all types of potentiometers and jacks for guitar diagram analysis + + + IMPROVEMENT + Increase maximum number of switch combination for analysis to 1024 + + + IMPROVEMENT + 'Line' component set to px used to render slightly thicker than 1px, appearing thicker than schematic symbols; changed to match the thickenss of schematic symbols + + + https://github.com/bancika/diy-layout-creator/releases + + + + 5 + 15 + 0 + + 2026-06-13 00:00:00.000 CET + + + + NEW_FEATURE + Add Freeway Blade switches 3B3-01, 5B5-01, 5B5-02 (thank you Martin Morell) + + + NEW_FEATURE + IEC variations of fuse and potentiometer symbols + + + NEW_FEATURE + Detect the style of a treble bleed based on the topology and component values (e.g. Fender, DiMarzio, Kinman, etc) + + + IMPROVEMENT + Improved quality of AI Assistant responses in some cases + + + IMPROVEMENT + Improved precision of rendering, in some cases there was a sub-pixel misalignment between the lines that should meet exactly + + + BUG_FIX + Tone capacitor mistaken for treble bleed when connected to the input lug of the volume pot + + + BUG_FIX + Dragging a component from the component tree to the canvas sometimes does not work as expected without clicking on it first and then dragging it + + + BUG_FIX + 'Schaller Megaswitch' not rendered correctly when rotated for 90 or 270 degrees + + + https://github.com/bancika/diy-layout-creator/releases + diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/passive/Resistor.java b/diylc/diylc-library/src/main/java/org/diylc/components/passive/Resistor.java index b69cd839..2f4641b7 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/passive/Resistor.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/passive/Resistor.java @@ -37,6 +37,7 @@ import org.diylc.components.AbstractLeadedComponent; import org.diylc.components.transform.SimpleComponentTransformer; import org.diylc.core.CreationMethod; import org.diylc.core.IDIYComponent; +import org.diylc.core.IDatasheetSupport; import org.diylc.core.annotations.AiNote; import org.diylc.core.annotations.ComponentDescriptor; import org.diylc.core.annotations.EditableProperty; @@ -48,10 +49,13 @@ import org.diylc.core.measures.SizeUnit; @AiNote("The two control points are the holes the leads go into and the body is centred between them; 'Length' is the body length, not the hole spacing") @AiNote("If the control points are closer together than 'Length' (0.5in by default) the part is drawn standing, its body over the first point; to keep it lying on a tighter footprint, reduce 'Length'") +@AiNote("A datasheet model sets the body size, shape and colors of a resistor family at one power rating but never the resistance; set 'Power Rating' together with the model to pick the matching size") @ComponentDescriptor(name = "Resistor", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "R", description = "Resistor layout symbol", - zOrder = IDIYComponent.COMPONENT, transformer = SimpleComponentTransformer.class, enableCache = true) -public class Resistor extends AbstractLeadedComponent implements IGerberComponentSimple { + zOrder = IDIYComponent.COMPONENT, transformer = SimpleComponentTransformer.class, enableCache = true, + enableDatasheet = true, datasheetCreationStepCount = 2) +public class Resistor extends AbstractLeadedComponent + implements IGerberComponentSimple, IDatasheetSupport { private static final long serialVersionUID = 1L; @@ -75,6 +79,41 @@ public class Resistor extends AbstractLeadedComponent implements IGe this.borderColor = BORDER_COLOR; } + public Resistor(String[] model) { + this(); + + applyModel(model); + } + + // columns: family, power, body length, body width, shape, color code, body color, border color; + // the resistance is not part of a row because the body size depends only on family and power + @Override + public void applyModel(String[] model) { + setPowerNew(org.diylc.core.measures.Power.parseCapacitance(model[1])); + setLength(parseDatasheetSize(model[2])); + setWidth(parseDatasheetSize(model[3])); + setShape(parseDatasheetEnum(ResistorShape.values(), model[4])); + setColorCode(parseDatasheetEnum(ResistorColorCode.values(), model[5])); + setBodyColor(Color.decode(model[6])); + setBorderColor(Color.decode(model[7])); + } + + // sizes are in mm unless a unit follows the number, as some families are specified in inches + private static Size parseDatasheetSize(String value) { + String[] parts = value.split(" "); + SizeUnit unit = parts.length > 1 ? SizeUnit.valueOf(parts[1]) : SizeUnit.mm; + return new Size(Double.parseDouble(parts[0]), unit); + } + + private static > E parseDatasheetEnum(E[] values, String name) { + for (E value : values) { + if (value.toString().equalsIgnoreCase(name)) { + return value; + } + } + throw new IllegalArgumentException("Unknown datasheet value: " + name); + } + @Override protected boolean supportsStandingMode() { return true; diff --git a/diylc/diylc-library/src/main/resources/datasheets/Resistor.datasheet b/diylc/diylc-library/src/main/resources/datasheets/Resistor.datasheet new file mode 100644 index 00000000..262a59e4 --- /dev/null +++ b/diylc/diylc-library/src/main/resources/datasheets/Resistor.datasheet @@ -0,0 +1,22 @@ +Carbon Comp,0.25 W,0.3 in,0.1 in,Tubular,5 band,#8A5E20,#735832 +Carbon Comp,0.5 W,0.41 in,0.15 in,Tubular,5 band,#8A5E20,#735832 +Carbon Film,0.25 W,7,2.5,Standard,5 band,#E0C68B,#A59268 +Carbon Film,0.5 W,9,3.2,Standard,5 band,#E0C68B,#A59268 +Metal Film,0.25 W,7,2.5,Standard,5 band,#82CFFD,#5B90B1 +Metal Film,0.5 W,9,3.2,Standard,5 band,#82CFFD,#5B90B1 +Metal Oxide,1 W,9,3,Standard,5 band,#D2D7DB,#B2B7BB +Metal Oxide,2 W,12,4,Standard,5 band,#D2D7DB,#B2B7BB +Metal Oxide,3 W,16,6,Standard,5 band,#D2D7DB,#B2B7BB +Ceramic,2 W,18,7,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,3 W,22,8,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,5 W,22,9.5,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,7 W,35,9.5,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,10 W,48,9.5,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,15 W,48,13,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,20 W,63,13,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,30 W,75,19,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,50 W,90,19,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,80 W,109,19,Tubular,None,#F6F5F5,#CCCCCC +Ceramic,100 W,135,22,Tubular,None,#F6F5F5,#CCCCCC +Dale CMF55,0.5 W,6.22,2.29,Tubular Beveled,5 band,#D37D5B,#A04C2B +Dale CMF60,1 W,8.75,3.53,Tubular Beveled,5 band,#D37D5B,#A04C2B diff --git a/diylc/diylc-library/src/test/java/org/diylc/components/DeletedVariantsTest.java b/diylc/diylc-library/src/test/java/org/diylc/components/DeletedVariantsTest.java new file mode 100644 index 00000000..fbb8a8e8 --- /dev/null +++ b/diylc/diylc-library/src/test/java/org/diylc/components/DeletedVariantsTest.java @@ -0,0 +1,196 @@ +/* + + DIY Layout Creator (DIYLC). + Copyright (c) 2009-2025 held jointly by the individual authors. + + This file is part of DIYLC. + + DIYLC is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DIYLC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DIYLC. If not, see . + +*/ +package org.diylc.components; + +import java.awt.geom.Point2D; +import java.io.InputStream; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.appframework.miscutils.IConfigListener; +import org.diylc.appframework.miscutils.IConfigurationManager; +import org.diylc.common.IPlugInPort; +import org.diylc.core.Template; +import org.diylc.presenter.VariantManager; +import org.diylc.serialization.ProjectFileManager; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Checks that a factory variant marked {@code deletedOn} in {@code import-defaults/variants.xml} is + * taken out of the user's configuration only when the last import predates the deletion, and is + * never imported. + */ +public class DeletedVariantsTest { + + private static final String RESISTOR = "org.diylc.components.passive.Resistor"; + + @BeforeClass + public static void setUp() { + try { + ConfigurationManager.getInstance().initialize("diylc"); + } catch (Exception ignored) { + } + } + + @SuppressWarnings("unchecked") + private static Map> loadVariants() { + InputStream in = DeletedVariantsTest.class.getClassLoader() + .getResourceAsStream("import-defaults/variants.xml"); + Assert.assertNotNull("variants.xml is not on the classpath", in); + return (Map>) ProjectFileManager.xStreamSerializer.fromXML(in); + } + + private static Template deletedResistor() { + return loadVariants().get(RESISTOR).stream().filter(t -> t.getDeletedOn() != null) + .findFirst().get(); + } + + private static InMemoryConfigurationManager configWith(List