mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 12:24:58 +10:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b3b0ef746f | |||
| a678b52f4d | |||
| 47f9056588 | |||
| c5a462a385 | |||
| b15a6e3f64 |
+239
-223
@@ -7142,45 +7142,6 @@
|
||||
"label" : "-"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Chassis Panel",
|
||||
"className" : "chassis.ChassisPanel",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "CP",
|
||||
"description" : "One side of a chassis, with or withouth rounded edges",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "Each instance is one side of the chassis: an exploded view of a whole chassis takes five panels, while the top, front and back alone take three, which is typical for pedals and amplifiers. The top panel goes in the centre with the front panel against its upper edge and the back panel against its lower edge; in the five-panel view the left side panel goes against its left edge and the right side panel against its right edge", "The panel is not conductive in the netlist: jacks, pots and lugs drawn on it are not joined through it, so chassis ground points must be connected explicitly" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#EEEEEE"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Radius",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Cliff 1/4\" Jack",
|
||||
"className" : "electromechanical.CliffJack1_4",
|
||||
@@ -7672,66 +7633,6 @@
|
||||
}
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Drill Hole",
|
||||
"className" : "electromechanical.DrillHole",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "Hole",
|
||||
"description" : "Drill hole marker for PCB, chassis or faceplate",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Diameter",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "3mm"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 1,
|
||||
"labels" : "none"
|
||||
}
|
||||
}, {
|
||||
"name" : "Elliptical Cutout",
|
||||
"className" : "chassis.EllipticalCutout",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "ELC",
|
||||
"description" : "Elliptical chassis cutout",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Fuse Holder (Panel)",
|
||||
"className" : "electromechanical.FuseHolderPanel",
|
||||
@@ -8632,43 +8533,6 @@
|
||||
"label" : "Center"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Polygonal Cutout",
|
||||
"className" : "chassis.PolygonalCutout",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "POLYC",
|
||||
"description" : "Polygonal chassis cutout",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Edges",
|
||||
"type" : "PointCount",
|
||||
"possibleValues" : [ "_3", "_4", "_5", "_6", "_7", "_8" ],
|
||||
"defaultValue" : "_4"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "RCA Jack",
|
||||
"className" : "electromechanical.RCAJack",
|
||||
@@ -8700,44 +8564,6 @@
|
||||
"label" : "Sleeve"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Rectangular Cutout",
|
||||
"className" : "chassis.RectangularCutout",
|
||||
"category" : "Electro-Mechanical",
|
||||
"namePrefix" : "RECTC",
|
||||
"description" : "Rectangular chassis cutout, with or without rounded edges",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Radius",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Rotary Selector Switch",
|
||||
"className" : "electromechanical.RotarySelectorSwitch",
|
||||
@@ -11587,6 +11413,242 @@
|
||||
"label" : "South Start"
|
||||
} ]
|
||||
}
|
||||
}, {
|
||||
"name" : "Dial Scale",
|
||||
"className" : "chassis.DialScale",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "DS",
|
||||
"description" : "Control panel dial scale",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Diameter",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1in"
|
||||
}, {
|
||||
"name" : "Font",
|
||||
"type" : "Font"
|
||||
}, {
|
||||
"name" : "Marker Size",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.1in"
|
||||
}, {
|
||||
"name" : "Tick Width",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.5mm"
|
||||
}, {
|
||||
"name" : "Type",
|
||||
"type" : "DialScaleType",
|
||||
"possibleValues" : [ "Ticks_Mixed", "Ticks", "Ticks_0_5_5_11", "Dots", "Dots_Gradual", "Numeric_0_10", "Numeric_1_11", "Numeric_1_10", "Numeric_1_12", "Numeric_Even", "Numeric_Even_Ticks" ],
|
||||
"defaultValue" : "Ticks"
|
||||
}, {
|
||||
"name" : "Value",
|
||||
"type" : "String"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 1,
|
||||
"labels" : "none"
|
||||
}
|
||||
}, {
|
||||
"name" : "Drill Hole",
|
||||
"className" : "electromechanical.DrillHole",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "Hole",
|
||||
"description" : "Drill hole marker for PCB, chassis or faceplate",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Diameter",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "3mm"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 1,
|
||||
"labels" : "none"
|
||||
}
|
||||
}, {
|
||||
"name" : "Elliptical Cutout",
|
||||
"className" : "chassis.EllipticalCutout",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "ELC",
|
||||
"description" : "Elliptical chassis cutout",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Enclosure",
|
||||
"className" : "chassis.ChassisPanel",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "ENC",
|
||||
"description" : "Top panel of an enclosure or chassis, optionally with its sides unfolded",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"notes" : [ "The two control points are opposite corners of the enclosure's top panel. With 'Height' above zero the sides are unfolded around it as an exploded view, each as tall as 'Height' and set 'Spacing' apart from it: the front against the top panel's upper edge, the back against its lower edge and, when 'Sides' is All, the left and right sides against its left and right edges. The bottom is never drawn. With 'Sides' set to None, or 'Height' at zero, it is a single flat panel of any size, such as one side of a chassis drawn on its own", "The enclosure is not conductive in the netlist: jacks, pots and lugs drawn on it are not joined through it, so chassis ground points must be connected explicitly", "A datasheet model is a Hammond enclosure part number such as 1590BB, 1550B or 1444-32, or a generic size such as 125B, and is stored as 'Value'; it sets the top panel to the enclosure's length and width, upright for pedal-sized die-cast boxes up to 125 mm long and horizontal for bigger boxes and amplifier chassis and 'Height' to its wall height. 125B is a generic size sold by several makers; its Hammond equivalent is 1590N1" ],
|
||||
"datasheetModels" : [ "1590LLB", "1590LB", "1590H", "1590Y", "1590A", "1590G", "1590G2", "1590S", "1590B", "1590B2", "1590BS", "1590B3", "1590BB", "1590BB2", "1590BBS", "1590Q", "1590U", "1590V", "1590C", "1590T", "1590CE", "1590N1", "1590KK", "1590K", "1590J", "1590XX", "1590X", "1590P1", "1590D", "1590DD", "1590E", "1590F", "1590R1", "1590DE", "1590EE", "1590BX2", "1590BX", "1550Q", "1550P", "1550A", "1550B", "1550D", "1550C", "1550M", "1550K", "1550L", "1550E", "1550F", "1550G", "1550H", "1550N", "1550J", "125B", "1441-9", "1441-15", "1441-6", "1441-8", "1441-12", "1441-10", "1441-14", "1441-16", "1441-22", "1441-29", "1441-18", "1441-26", "1441-30", "1441-34", "1441-24", "1441-28", "1441-20", "1441-32", "1441-36", "1441-38", "1441-33", "1441-40", "1441-42", "1444-45351", "1444-9", "1444-15", "1444-6415", "1444-84515", "1444-6", "1444-542", "1444-8", "1444-12", "1444-772", "1444-10", "1444-862", "1444-14", "1444-972", "1444-9552", "1444-16", "1444-1172", "1444-22", "1444-29", "1444-1372", "1444-18", "1444-26", "1444-30", "1444-17132", "1444-95525", "1444-10825", "1444-12825", "1444-643", "1444-753", "1444-9553", "1444-1053", "1444-1273", "1444-24", "1444-12103", "1444-12123", "1444-1463", "1444-14103", "1444-1573", "1444-1593", "1444-28", "1444-20", "1444-1763", "1444-1773", "1444-1783", "1444-32", "1444-17123", "1444-17133", "1444-17143", "1444-17173", "1444-33", "1444-17134", "1444-17154", "1444-17174", "1444-17105", "1444-17135", "1444-17156" ],
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#EEEEEE"
|
||||
}, {
|
||||
"name" : "Height",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "36mm"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Radius",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
}, {
|
||||
"name" : "Sides",
|
||||
"type" : "Sides",
|
||||
"possibleValues" : [ "ALL", "FRONT_AND_BACK", "NONE" ],
|
||||
"defaultValue" : "ALL"
|
||||
}, {
|
||||
"name" : "Spacing",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
}, {
|
||||
"name" : "Value",
|
||||
"type" : "String",
|
||||
"defaultValue" : "125B"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Polygonal Cutout",
|
||||
"className" : "chassis.PolygonalCutout",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "POLYC",
|
||||
"description" : "Polygonal chassis cutout",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Edges",
|
||||
"type" : "PointCount",
|
||||
"possibleValues" : [ "_3", "_4", "_5", "_6", "_7", "_8" ],
|
||||
"defaultValue" : "_4"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Rectangular Cutout",
|
||||
"className" : "chassis.RectangularCutout",
|
||||
"category" : "Hardware",
|
||||
"namePrefix" : "RECTC",
|
||||
"description" : "Rectangular chassis cutout, with or without rounded edges",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Alpha",
|
||||
"type" : "Percentage",
|
||||
"format" : "number without the % sign, e.g. 100",
|
||||
"defaultValue" : "100"
|
||||
}, {
|
||||
"name" : "Border",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#A6A6A6"
|
||||
}, {
|
||||
"name" : "Border Thickness",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#FFFFFF"
|
||||
}, {
|
||||
"name" : "Name",
|
||||
"type" : "String"
|
||||
}, {
|
||||
"name" : "Radius",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0mm"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Auto-Wrap Label",
|
||||
"className" : "misc.WrapLabel",
|
||||
@@ -11688,52 +11750,6 @@
|
||||
"type" : "String",
|
||||
"defaultValue" : "X"
|
||||
} ]
|
||||
}, {
|
||||
"name" : "Dial Scale",
|
||||
"className" : "chassis.DialScale",
|
||||
"category" : "Misc",
|
||||
"namePrefix" : "DS",
|
||||
"description" : "Control panel dial scale",
|
||||
"creationMethod" : "SINGLE_CLICK",
|
||||
"properties" : [ {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
"format" : "hex",
|
||||
"defaultValue" : "#000000"
|
||||
}, {
|
||||
"name" : "Diameter",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "1in"
|
||||
}, {
|
||||
"name" : "Font",
|
||||
"type" : "Font"
|
||||
}, {
|
||||
"name" : "Marker Size",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.1in"
|
||||
}, {
|
||||
"name" : "Tick Width",
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.5mm"
|
||||
}, {
|
||||
"name" : "Type",
|
||||
"type" : "DialScaleType",
|
||||
"possibleValues" : [ "Ticks_Mixed", "Ticks", "Ticks_0_5_5_11", "Dots", "Dots_Gradual", "Numeric_0_10", "Numeric_1_11", "Numeric_1_10", "Numeric_1_12", "Numeric_Even", "Numeric_Even_Ticks" ],
|
||||
"defaultValue" : "Ticks"
|
||||
}, {
|
||||
"name" : "Value",
|
||||
"type" : "String"
|
||||
} ],
|
||||
"pinout" : {
|
||||
"pinCount" : 1,
|
||||
"labels" : "none"
|
||||
}
|
||||
}, {
|
||||
"name" : "Image",
|
||||
"className" : "misc.Image",
|
||||
@@ -18719,7 +18735,7 @@
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
@@ -18820,7 +18836,7 @@
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
@@ -18857,7 +18873,7 @@
|
||||
"type" : "Size",
|
||||
"format" : "(value)(unit)",
|
||||
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
|
||||
"defaultValue" : "0.2mm"
|
||||
"defaultValue" : "1px"
|
||||
}, {
|
||||
"name" : "Color",
|
||||
"type" : "Color",
|
||||
|
||||
+19
-18
@@ -174,9 +174,6 @@
|
||||
}, {
|
||||
"name" : "9V Battery Snap",
|
||||
"className" : "electromechanical.BatterySnap9V"
|
||||
}, {
|
||||
"name" : "Chassis Panel",
|
||||
"className" : "chassis.ChassisPanel"
|
||||
}, {
|
||||
"name" : "Cliff 1/4\" Jack",
|
||||
"className" : "electromechanical.CliffJack1_4"
|
||||
@@ -189,12 +186,6 @@
|
||||
}, {
|
||||
"name" : "DIP Switch",
|
||||
"className" : "electromechanical.DIPSwitch"
|
||||
}, {
|
||||
"name" : "Drill Hole",
|
||||
"className" : "electromechanical.DrillHole"
|
||||
}, {
|
||||
"name" : "Elliptical Cutout",
|
||||
"className" : "chassis.EllipticalCutout"
|
||||
}, {
|
||||
"name" : "Fuse Holder (Panel)",
|
||||
"className" : "electromechanical.FuseHolderPanel"
|
||||
@@ -225,15 +216,9 @@
|
||||
}, {
|
||||
"name" : "Plastic DC Jack",
|
||||
"className" : "electromechanical.PlasticDCJack"
|
||||
}, {
|
||||
"name" : "Polygonal Cutout",
|
||||
"className" : "chassis.PolygonalCutout"
|
||||
}, {
|
||||
"name" : "RCA Jack",
|
||||
"className" : "electromechanical.RCAJack"
|
||||
}, {
|
||||
"name" : "Rectangular Cutout",
|
||||
"className" : "chassis.RectangularCutout"
|
||||
}, {
|
||||
"name" : "Rotary Selector Switch",
|
||||
"className" : "electromechanical.RotarySelectorSwitch"
|
||||
@@ -293,6 +278,25 @@
|
||||
"name" : "Stingray Bass Pickup",
|
||||
"className" : "guitar.StingrayBassPickup"
|
||||
} ],
|
||||
"Hardware" : [ {
|
||||
"name" : "Dial Scale",
|
||||
"className" : "chassis.DialScale"
|
||||
}, {
|
||||
"name" : "Drill Hole",
|
||||
"className" : "electromechanical.DrillHole"
|
||||
}, {
|
||||
"name" : "Elliptical Cutout",
|
||||
"className" : "chassis.EllipticalCutout"
|
||||
}, {
|
||||
"name" : "Enclosure",
|
||||
"className" : "chassis.ChassisPanel"
|
||||
}, {
|
||||
"name" : "Polygonal Cutout",
|
||||
"className" : "chassis.PolygonalCutout"
|
||||
}, {
|
||||
"name" : "Rectangular Cutout",
|
||||
"className" : "chassis.RectangularCutout"
|
||||
} ],
|
||||
"Misc" : [ {
|
||||
"name" : "Auto-Wrap Label",
|
||||
"className" : "misc.WrapLabel"
|
||||
@@ -302,9 +306,6 @@
|
||||
}, {
|
||||
"name" : "Common Node",
|
||||
"className" : "misc.CommonNode"
|
||||
}, {
|
||||
"name" : "Dial Scale",
|
||||
"className" : "chassis.DialScale"
|
||||
}, {
|
||||
"name" : "Image",
|
||||
"className" : "misc.Image"
|
||||
|
||||
@@ -118,16 +118,10 @@ public class ComparatorFactory {
|
||||
if (componentZOrderComparator == null) {
|
||||
componentZOrderComparator = new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||
ComponentType type1 =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o1.getClass());
|
||||
ComponentType type2 =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o2.getClass());
|
||||
return Double.valueOf(type1.getZOrder()).compareTo(type2.getZOrder());
|
||||
return Double.compare(ComponentProcessor.getInstance().getZOrder(o1),
|
||||
ComponentProcessor.getInstance().getZOrder(o2));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -409,6 +409,31 @@ public class ComponentProcessor {
|
||||
return type.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the z-order (layer) of the component. A {@link CompositeComponent} sits on the lowest
|
||||
* layer among its children rather than the one its class declares: it is drawn as a
|
||||
* single unit, so it takes one place in the stack, and that place has to be under
|
||||
* whatever is later put on top of it. A block of chassis panels therefore stays on the
|
||||
* chassis layer, and a block built from a board, pads and silkscreen text on the board
|
||||
* layer.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public double getZOrder(IDIYComponent<?> component) {
|
||||
if (component instanceof CompositeComponent) {
|
||||
double zOrder = Double.MAX_VALUE;
|
||||
for (IDIYComponent<?> child : ((CompositeComponent) component).getChildComponents()) {
|
||||
zOrder = Math.min(zOrder, getZOrder(child));
|
||||
}
|
||||
if (zOrder < Double.MAX_VALUE) {
|
||||
return zOrder;
|
||||
}
|
||||
}
|
||||
ComponentType type =
|
||||
extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
// internal types without a descriptor do not take part in layering
|
||||
return type == null ? Double.MAX_VALUE : type.getZOrder();
|
||||
}
|
||||
|
||||
public static boolean hasStickyPoint(IDIYComponent<?> c) {
|
||||
for (int i = 0; i < c.getControlPointCount(); i++)
|
||||
if (c.isControlPointSticky(0))
|
||||
|
||||
@@ -94,7 +94,8 @@ public class GroupAndLockIndex {
|
||||
if (componentType == null) {
|
||||
return false;
|
||||
}
|
||||
return project.getLockedLayers().contains((int) Math.round(componentType.getZOrder()))
|
||||
return project.getLockedLayers()
|
||||
.contains((int) Math.round(ComponentProcessor.getInstance().getZOrder(component)))
|
||||
|| project.getLockedComponents().contains(component);
|
||||
}
|
||||
|
||||
|
||||
@@ -494,7 +494,8 @@ public class Presenter implements IPlugInPort {
|
||||
// for internal types
|
||||
if (componentType == null)
|
||||
return true;
|
||||
return !currentProject.getHiddenLayers().contains((int) Math.round(componentType.getZOrder()));
|
||||
return !currentProject.getHiddenLayers()
|
||||
.contains((int) Math.round(ComponentProcessor.getInstance().getZOrder(component)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1076,10 +1077,9 @@ public class Presenter implements IPlugInPort {
|
||||
Iterator<IDIYComponent<?>> i = newSelection.iterator();
|
||||
while (i.hasNext()) {
|
||||
IDIYComponent<?> c = i.next();
|
||||
ComponentType type =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) c.getClass());
|
||||
if ((int) type.getZOrder() != layer)
|
||||
if ((int) ComponentProcessor.getInstance().getZOrder(c) != layer) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
updateSelection(newSelection);
|
||||
@@ -2229,6 +2229,7 @@ public class Presenter implements IPlugInPort {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
long layer = Math.round(ComponentProcessor.getInstance().getZOrder(component));
|
||||
int index = currentProject.getComponents().indexOf(component);
|
||||
if (index < 0) {
|
||||
LOG.warn("Component not found in the project: " + component.getName());
|
||||
@@ -2236,11 +2237,8 @@ public class Presenter implements IPlugInPort {
|
||||
while (index > 0) {
|
||||
IDIYComponent<?> componentBefore = currentProject.getComponents().get(index - 1);
|
||||
if (!selectedComponents.contains(componentBefore)) {
|
||||
ComponentType componentBeforeType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) componentBefore.getClass());
|
||||
if (!componentType.isFlexibleZOrder()
|
||||
&& Math.round(componentBeforeType.getZOrder()) < Math.round(componentType.getZOrder())
|
||||
&& Math.round(ComponentProcessor.getInstance().getZOrder(componentBefore)) < layer
|
||||
&& forceConfirmation != IView.YES_OPTION
|
||||
&& (forceConfirmation =
|
||||
this.view
|
||||
@@ -2278,6 +2276,7 @@ public class Presenter implements IPlugInPort {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
long layer = Math.round(ComponentProcessor.getInstance().getZOrder(component));
|
||||
int index = currentProject.getComponents().indexOf(component);
|
||||
if (index < 0) {
|
||||
LOG.warn("Component not found in the project: " + component.getName());
|
||||
@@ -2285,11 +2284,8 @@ public class Presenter implements IPlugInPort {
|
||||
while (index < currentProject.getComponents().size() - 1) {
|
||||
IDIYComponent<?> componentAfter = currentProject.getComponents().get(index + 1);
|
||||
if (!selectedComponents.contains(componentAfter)) {
|
||||
ComponentType componentAfterType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) componentAfter.getClass());
|
||||
if (!componentType.isFlexibleZOrder()
|
||||
&& Math.round(componentAfterType.getZOrder()) > Math.round(componentType.getZOrder())
|
||||
&& Math.round(ComponentProcessor.getInstance().getZOrder(componentAfter)) > layer
|
||||
&& forceConfirmation != IView.YES_OPTION
|
||||
&& (forceConfirmation =
|
||||
this.view
|
||||
@@ -2684,13 +2680,9 @@ public class Presenter implements IPlugInPort {
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addComponent(IDIYComponent<?> component, boolean allowAutoCreate) {
|
||||
int index = currentProject.getComponents().size();
|
||||
while (index > 0
|
||||
&& ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass()).getZOrder() < ComponentProcessor
|
||||
.getInstance()
|
||||
.extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) currentProject.getComponents().get(index - 1).getClass())
|
||||
.getZOrder()) {
|
||||
double zOrder = ComponentProcessor.getInstance().getZOrder(component);
|
||||
while (index > 0 && zOrder < ComponentProcessor.getInstance()
|
||||
.getZOrder(currentProject.getComponents().get(index - 1))) {
|
||||
index--;
|
||||
}
|
||||
if (index < currentProject.getComponents().size()) {
|
||||
@@ -2724,12 +2716,9 @@ public class Presenter implements IPlugInPort {
|
||||
int maxIndex = 0;
|
||||
for (IDIYComponent<?> component : components) {
|
||||
int index = currentProject.getComponents().size();
|
||||
while (index > maxIndex && ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) component.getClass())
|
||||
.getZOrder() < ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) currentProject
|
||||
.getComponents().get(index - 1).getClass())
|
||||
.getZOrder()) {
|
||||
double zOrder = ComponentProcessor.getInstance().getZOrder(component);
|
||||
while (index > maxIndex && zOrder < ComponentProcessor.getInstance()
|
||||
.getZOrder(currentProject.getComponents().get(index - 1))) {
|
||||
index--;
|
||||
}
|
||||
|
||||
@@ -3132,12 +3121,9 @@ public class Presenter implements IPlugInPort {
|
||||
return GroupAndLockIndex.isLocked(currentProject, component);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean isComponentLayerLocked(IDIYComponent<?> component) {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass());
|
||||
return currentProject.getLockedLayers().contains((int) Math.round(componentType.getZOrder()));
|
||||
return currentProject.getLockedLayers()
|
||||
.contains((int) Math.round(ComponentProcessor.getInstance().getZOrder(component)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1902,111 +1902,19 @@
|
||||
<list>
|
||||
<org.diylc.core.Template>
|
||||
<name>125B</name>
|
||||
<values>
|
||||
<entry>
|
||||
<string>Radius</string>
|
||||
<org.diylc.core.measures.Size value="5.0" unit="mm"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Color</string>
|
||||
<awt-color hex="eeeeee"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Border</string>
|
||||
<awt-color hex="a6a6a6"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Border Thickness</string>
|
||||
<org.diylc.core.measures.Size value="0.2" unit="mm"/>
|
||||
</entry>
|
||||
</values>
|
||||
<points>
|
||||
<point x="0.0" y="0.0"/>
|
||||
<point x="4.815" y="2.64"/>
|
||||
</points>
|
||||
<defaultFlag>false</defaultFlag>
|
||||
<createdOn>2022-10-30T13:25:15.3894874</createdOn>
|
||||
<deletedOn>2026-11-01T23:00:00</deletedOn>
|
||||
</org.diylc.core.Template>
|
||||
<org.diylc.core.Template>
|
||||
<name>A</name>
|
||||
<values>
|
||||
<entry>
|
||||
<string>Radius</string>
|
||||
<org.diylc.core.measures.Size value="5.0" unit="mm"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Color</string>
|
||||
<awt-color hex="eeeeee"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Border</string>
|
||||
<awt-color hex="a6a6a6"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Border Thickness</string>
|
||||
<org.diylc.core.measures.Size value="0.2" unit="mm"/>
|
||||
</entry>
|
||||
</values>
|
||||
<points>
|
||||
<point x="0.0" y="0.0"/>
|
||||
<point x="3.545" y="1.525"/>
|
||||
</points>
|
||||
<defaultFlag>false</defaultFlag>
|
||||
<createdOn>2022-10-30T13:25:15.3894874</createdOn>
|
||||
<deletedOn>2026-11-01T23:00:00</deletedOn>
|
||||
</org.diylc.core.Template>
|
||||
<org.diylc.core.Template>
|
||||
<name>B</name>
|
||||
<values>
|
||||
<entry>
|
||||
<string>Radius</string>
|
||||
<org.diylc.core.measures.Size value="5.0" unit="mm"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Color</string>
|
||||
<awt-color hex="eeeeee"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Border</string>
|
||||
<awt-color hex="a6a6a6"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Border Thickness</string>
|
||||
<org.diylc.core.measures.Size value="0.2" unit="mm"/>
|
||||
</entry>
|
||||
</values>
|
||||
<points>
|
||||
<point x="0.0" y="0.0"/>
|
||||
<point x="4.41" y="2.36"/>
|
||||
</points>
|
||||
<defaultFlag>false</defaultFlag>
|
||||
<createdOn>2022-10-30T13:25:15.3894874</createdOn>
|
||||
<deletedOn>2026-11-01T23:00:00</deletedOn>
|
||||
</org.diylc.core.Template>
|
||||
<org.diylc.core.Template>
|
||||
<name>BB</name>
|
||||
<values>
|
||||
<entry>
|
||||
<string>Radius</string>
|
||||
<org.diylc.core.measures.Size value="5.0" unit="mm"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Color</string>
|
||||
<awt-color hex="eeeeee"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Border</string>
|
||||
<awt-color hex="a6a6a6"/>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Border Thickness</string>
|
||||
<org.diylc.core.measures.Size value="0.2" unit="mm"/>
|
||||
</entry>
|
||||
</values>
|
||||
<points>
|
||||
<point x="0.0" y="0.0"/>
|
||||
<point x="4.695" y="3.69"/>
|
||||
</points>
|
||||
<defaultFlag>false</defaultFlag>
|
||||
<createdOn>2022-10-30T13:25:15.3894874</createdOn>
|
||||
<deletedOn>2026-11-01T23:00:00</deletedOn>
|
||||
</org.diylc.core.Template>
|
||||
</list>
|
||||
</entry>
|
||||
|
||||
@@ -517,10 +517,26 @@
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>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</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Derive the z-order of a building blocks placed as a single component based on its child components</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added datasheets to 'DIP IC', 'SIP IC' and 'Multiwatt IC' - pick a part by its number from the component's submenu to set its pin count, spacing and pin names at once - more than 100 chips in total; the AI Assistant can place these parts by part number too</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>'Chassis Panel' is now 'Enclosure' and can draw an exploded view of the whole box; set 'Height' and choose which 'Sides' to unfold</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added a datasheet to 'Enclosure' with Hammond 1590, 1550, 1441 and 1444 enclosures and the 125B size - more than 130 variations</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Moved 'Enclosure', cutouts, 'Drill Hole' and 'Dial Scale' to the new 'Hardware' category</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>'DIP IC' with 'Display Pin #s' set to 'No' numbered its pins in the wrong order in netlists and AI analysis, e.g. pin 8 of an 8-pin IC was reported as pin 5</description>
|
||||
|
||||
+78
@@ -35,7 +35,12 @@ import java.util.UUID;
|
||||
|
||||
import org.diylc.common.Percentage;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.netlist.Node;
|
||||
import org.diylc.presenter.ComparatorFactory;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
import org.diylc.presenter.GroupAndLockIndex;
|
||||
import org.diylc.serialization.ProjectFileManager;
|
||||
import org.diylc.testcomponents.OnePointTestComponent;
|
||||
import org.diylc.testcomponents.TwoPointTestComponent;
|
||||
@@ -326,4 +331,77 @@ public class CompositeComponentTest {
|
||||
assertNotNull(blank.getChildComponents());
|
||||
assertTrue(blank.getChildComponents().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfAChassisOnlyCompositeIsTheChassisLayer() {
|
||||
CompositeComponent composite = customBoard(new ChassisTestComponent(),
|
||||
new ChassisTestComponent());
|
||||
|
||||
assertEquals(IDIYComponent.CHASSIS, ComponentProcessor.getInstance().getZOrder(composite), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfAMixedCompositeIsItsLowestChildLayer() {
|
||||
CompositeComponent composite = customBoard(new TextTestComponent(), twoPoint("R1"),
|
||||
new BoardTestComponent());
|
||||
|
||||
assertEquals(IDIYComponent.BOARD, ComponentProcessor.getInstance().getZOrder(composite), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfANestedCompositeLooksThroughTheInnerComposite() {
|
||||
CompositeComponent inner = customBoard(new ChassisTestComponent());
|
||||
CompositeComponent outer = customBoard(twoPoint("R1"), inner);
|
||||
|
||||
assertEquals(IDIYComponent.CHASSIS, ComponentProcessor.getInstance().getZOrder(outer), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerOfAChildlessCompositeIsTheDeclaredOne() {
|
||||
assertEquals(IDIYComponent.COMPONENT,
|
||||
ComponentProcessor.getInstance().getZOrder(new CompositeComponent()), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lockingTheChildLayerLocksTheComposite() {
|
||||
Project project = new Project();
|
||||
CompositeComponent chassis = customBoard(new ChassisTestComponent());
|
||||
project.getComponents().add(chassis);
|
||||
|
||||
project.getLockedLayers().add(IDIYComponent.COMPONENT);
|
||||
assertFalse(GroupAndLockIndex.isLocked(project, chassis));
|
||||
|
||||
project.getLockedLayers().add(IDIYComponent.CHASSIS);
|
||||
assertTrue(GroupAndLockIndex.isLocked(project, chassis));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compositeSortsByItsChildLayer() {
|
||||
CompositeComponent chassis = customBoard(new ChassisTestComponent());
|
||||
BoardTestComponent board = new BoardTestComponent();
|
||||
|
||||
assertTrue(ComparatorFactory.getInstance().getComponentZOrderComparator().compare(chassis,
|
||||
board) < 0);
|
||||
}
|
||||
|
||||
@ComponentDescriptor(name = "Chassis Test", category = "Test", author = "Test",
|
||||
description = "test", instanceNamePrefix = "CT", zOrder = IDIYComponent.CHASSIS)
|
||||
public static class ChassisTestComponent extends TwoPointTestComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@ComponentDescriptor(name = "Board Test", category = "Test", author = "Test",
|
||||
description = "test", instanceNamePrefix = "BT", zOrder = IDIYComponent.BOARD)
|
||||
public static class BoardTestComponent extends TwoPointTestComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
@ComponentDescriptor(name = "Text Test", category = "Test", author = "Test",
|
||||
description = "test", instanceNamePrefix = "TT", zOrder = IDIYComponent.TEXT)
|
||||
public static class TextTestComponent extends TwoPointTestComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,17 +21,21 @@
|
||||
*/
|
||||
package org.diylc.components.chassis;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.components.shapes.AbstractShape;
|
||||
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.IDatasheetSupport;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.AiNote;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
@@ -39,60 +43,206 @@ import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@AiNote("Each instance is one side of the chassis: an exploded view of a whole chassis takes five panels, while the top, front and back alone take three, which is typical for pedals and amplifiers. The top panel goes in the centre with the front panel against its upper edge and the back panel against its lower edge; in the five-panel view the left side panel goes against its left edge and the right side panel against its right edge")
|
||||
@AiNote("The panel is not conductive in the netlist: jacks, pots and lugs drawn on it are not joined through it, so chassis ground points must be connected explicitly")
|
||||
@ComponentDescriptor(name = "Chassis Panel", author = "Branislav Stojkovic", category = "Electro-Mechanical",
|
||||
instanceNamePrefix = "CP", description = "One side of a chassis, with or withouth rounded edges",
|
||||
@AiNote("The two control points are opposite corners of the enclosure's top panel. With 'Height' above zero the sides are unfolded around it as an exploded view, each as tall as 'Height' and set 'Spacing' apart from it: the front against the top panel's upper edge, the back against its lower edge and, when 'Sides' is All, the left and right sides against its left and right edges. The bottom is never drawn. With 'Sides' set to None, or 'Height' at zero, it is a single flat panel of any size, such as one side of a chassis drawn on its own")
|
||||
@AiNote("The enclosure is not conductive in the netlist: jacks, pots and lugs drawn on it are not joined through it, so chassis ground points must be connected explicitly")
|
||||
@AiNote("A datasheet model is a Hammond enclosure part number such as 1590BB, 1550B or 1444-32, or a generic size such as 125B, and is stored as 'Value'; it sets the top panel to the enclosure's length and width, upright for pedal-sized die-cast boxes up to 125 mm long and horizontal for bigger boxes and amplifier chassis and 'Height' to its wall height. 125B is a generic size sold by several makers; its Hammond equivalent is 1590N1")
|
||||
@ComponentDescriptor(name = "Enclosure", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "ENC",
|
||||
description = "Top panel of an enclosure or chassis, optionally with its sides unfolded",
|
||||
zOrder = IDIYComponent.CHASSIS, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false,
|
||||
transformer = SimpleComponentTransformer.class)
|
||||
public class ChassisPanel extends AbstractShape {
|
||||
transformer = SimpleComponentTransformer.class, enableDatasheet = true,
|
||||
datasheetCreationStepCount = 2, datasheetModelColumn = 1)
|
||||
public class ChassisPanel extends AbstractTransparentComponent<String>
|
||||
implements IDatasheetSupport {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected Size edgeRadius = new Size(0d, SizeUnit.mm);
|
||||
|
||||
public static Color COLOR = LIGHT_METAL_COLOR;
|
||||
public static Color BORDER_COLOR = LIGHT_METAL_COLOR.darker();
|
||||
// a new enclosure is a 125B, the most common pedal enclosure, upright as in its datasheet row
|
||||
public static String DEFAULT_MODEL = "125B";
|
||||
public static Size DEFAULT_TOP_WIDTH = new Size(66d, SizeUnit.mm);
|
||||
public static Size DEFAULT_TOP_LENGTH = new Size(122d, SizeUnit.mm);
|
||||
public static Size DEFAULT_WALL_HEIGHT = new Size(36d, SizeUnit.mm);
|
||||
public static Size DEFAULT_RADIUS = new Size(0d, SizeUnit.mm);
|
||||
public static Size DEFAULT_SPACING = new Size(0d, SizeUnit.mm);
|
||||
|
||||
// the fields below up to borderThickness carry the names they had when this class extended
|
||||
// AbstractShape, because old files store them under those names
|
||||
private String value = DEFAULT_MODEL;
|
||||
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0), new Point2D.Double(
|
||||
DEFAULT_TOP_WIDTH.convertToPixels(), DEFAULT_TOP_LENGTH.convertToPixels())};
|
||||
private Point2D.Double firstPoint = new Point2D.Double();
|
||||
private Point2D.Double secondPoint = new Point2D.Double();
|
||||
private Color color = COLOR;
|
||||
private Color borderColor = BORDER_COLOR;
|
||||
// no longer used; kept so that old files that store it still load
|
||||
@Deprecated
|
||||
private Size borderThickness;
|
||||
protected Size edgeRadius = DEFAULT_RADIUS;
|
||||
private Size height = DEFAULT_WALL_HEIGHT;
|
||||
private Sides sides = Sides.ALL;
|
||||
private Size spacing = DEFAULT_SPACING;
|
||||
|
||||
public ChassisPanel() {
|
||||
this.color = LIGHT_METAL_COLOR;
|
||||
this.borderColor = LIGHT_METAL_COLOR.darker();
|
||||
updateCorners();
|
||||
}
|
||||
|
||||
public ChassisPanel(String[] model) {
|
||||
this();
|
||||
|
||||
applyModel(model);
|
||||
}
|
||||
|
||||
// columns: group, model, top panel size along x and along y, wall height. The wall height leaves
|
||||
// out the lid, which is the bottom left out of the view. Pedal-sized boxes are listed upright,
|
||||
// as pedals use them, and the bigger ones horizontal
|
||||
@Override
|
||||
public void applyModel(String[] model) {
|
||||
setValue(model[1]);
|
||||
setHeight(Size.parseSize(model[4]));
|
||||
// the first control point stays put and the top panel keeps the direction it is drawn in
|
||||
Point2D first = controlPoints[0];
|
||||
Point2D second = controlPoints[1];
|
||||
double x = Size.parseSize(model[2]).convertToPixels();
|
||||
double y = Size.parseSize(model[3]).convertToPixels();
|
||||
setControlPoint(new Point2D.Double(first.getX() + (second.getX() < first.getX() ? -x : x),
|
||||
first.getY() + (second.getY() < first.getY() ? -y : y)), 1);
|
||||
}
|
||||
|
||||
private void updateCorners() {
|
||||
firstPoint.setLocation(Math.min(controlPoints[0].getX(), controlPoints[1].getX()),
|
||||
Math.min(controlPoints[0].getY(), controlPoints[1].getY()));
|
||||
secondPoint.setLocation(Math.max(controlPoints[0].getX(), controlPoints[1].getX()),
|
||||
Math.max(controlPoints[0].getY(), controlPoints[1].getY()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the side panels of the exploded view, folded out from the edges of the top panel:
|
||||
* front, back and then, when all sides are shown, left and right. Empty when no sides are
|
||||
* shown or the enclosure has no height.
|
||||
*/
|
||||
Rectangle2D[] getSidePanels() {
|
||||
double h = getHeight() == null ? 0 : getHeight().convertToPixels();
|
||||
if (h <= 0 || getSides() == Sides.NONE) {
|
||||
return new Rectangle2D[0];
|
||||
}
|
||||
double s = getSpacing() == null ? 0 : getSpacing().convertToPixels();
|
||||
double x = firstPoint.getX();
|
||||
double y = firstPoint.getY();
|
||||
double w = secondPoint.getX() - x;
|
||||
double d = secondPoint.getY() - y;
|
||||
Rectangle2D front = new Rectangle2D.Double(x, y - s - h, w, h);
|
||||
Rectangle2D back = new Rectangle2D.Double(x, y + d + s, w, h);
|
||||
if (getSides() == Sides.FRONT_AND_BACK) {
|
||||
return new Rectangle2D[] {front, back};
|
||||
}
|
||||
return new Rectangle2D[] {front, back, new Rectangle2D.Double(x - s - h, y, h, d),
|
||||
new Rectangle2D.Double(x + w + s, y, h, d)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels()));
|
||||
int radius = (int) edgeRadius.convertToPixels();
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
int x = (int) Math.round(firstPoint.getX());
|
||||
int y = (int) Math.round(firstPoint.getY());
|
||||
int width = (int) (secondPoint.getX() - firstPoint.getX());
|
||||
int length = (int) (secondPoint.getY() - firstPoint.getY());
|
||||
int radius = (int) getEdgeRadius().convertToPixels();
|
||||
Rectangle2D[] sidePanels = getSidePanels();
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
g2d.setColor(color);
|
||||
if (radius == 0) {
|
||||
g2d.fillRect((int) Math.round(firstPoint.getX()), (int) Math.round(firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()));
|
||||
g2d.fillRect(x, y, width, length);
|
||||
} else {
|
||||
g2d.fillRoundRect((int) Math.round(firstPoint.getX()), (int) Math.round(firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()), radius, radius);
|
||||
g2d.fillRoundRect(x, y, width, length, radius, radius);
|
||||
}
|
||||
for (Rectangle2D panel : sidePanels) {
|
||||
g2d.fill(panel);
|
||||
}
|
||||
g2d.setComposite(oldComposite);
|
||||
// the panels drawn so far are the whole area of the enclosure
|
||||
drawingObserver.stopTracking();
|
||||
}
|
||||
// Do not track any changes that follow because the whole rect has been
|
||||
// tracked so far.
|
||||
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||
: borderColor);
|
||||
g2d.setColor(componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : borderColor);
|
||||
if (radius == 0) {
|
||||
g2d.drawRect((int) Math.round(firstPoint.getX()), (int) Math.round(firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()));
|
||||
g2d.drawRect(x, y, width, length);
|
||||
} else {
|
||||
g2d.drawRoundRect((int) Math.round(firstPoint.getX()), (int) Math.round(firstPoint.getY()),
|
||||
(int) (secondPoint.getX() - firstPoint.getX()),
|
||||
(int) (secondPoint.getY() - firstPoint.getY()), radius, radius);
|
||||
g2d.drawRoundRect(x, y, width, length, radius, radius);
|
||||
}
|
||||
for (Rectangle2D panel : sidePanels) {
|
||||
g2d.draw(panel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point2D getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point2D point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
updateCorners();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Color")
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Border")
|
||||
public Color getBorderColor() {
|
||||
return borderColor;
|
||||
}
|
||||
|
||||
public void setBorderColor(Color borderColor) {
|
||||
this.borderColor = borderColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Radius")
|
||||
public Size getEdgeRadius() {
|
||||
if (edgeRadius == null) {
|
||||
edgeRadius = DEFAULT_RADIUS;
|
||||
}
|
||||
return edgeRadius;
|
||||
}
|
||||
|
||||
@@ -100,12 +250,70 @@ public class ChassisPanel extends AbstractShape {
|
||||
this.edgeRadius = edgeRadius;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Size getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Size height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Sides getSides() {
|
||||
if (sides == null) {
|
||||
sides = Sides.ALL;
|
||||
}
|
||||
return sides;
|
||||
}
|
||||
|
||||
public void setSides(Sides sides) {
|
||||
this.sides = sides;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Size getSpacing() {
|
||||
if (spacing == null) {
|
||||
spacing = DEFAULT_SPACING;
|
||||
}
|
||||
return spacing;
|
||||
}
|
||||
|
||||
public void setSpacing(Size spacing) {
|
||||
this.spacing = spacing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int factor = 32 / width;
|
||||
g2d.setColor(LIGHT_METAL_COLOR);
|
||||
g2d.fillRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor);
|
||||
g2d.setColor(LIGHT_METAL_COLOR.darker());
|
||||
g2d.drawRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor);
|
||||
int flap = 6 / factor;
|
||||
int left = 2 / factor + flap;
|
||||
int top = 2 / factor + flap;
|
||||
int topWidth = width - 2 * left;
|
||||
int topHeight = height - 2 * top;
|
||||
int[][] panels = {{left, top, topWidth, topHeight}, {left, top - flap, topWidth, flap},
|
||||
{left, top + topHeight, topWidth, flap}, {left - flap, top, flap, topHeight},
|
||||
{left + topWidth, top, flap, topHeight}};
|
||||
for (int[] panel : panels) {
|
||||
g2d.setColor(LIGHT_METAL_COLOR);
|
||||
g2d.fillRect(panel[0], panel[1], panel[2], panel[3]);
|
||||
g2d.setColor(LIGHT_METAL_COLOR.darker());
|
||||
g2d.drawRect(panel[0], panel[1], panel[2], panel[3]);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Sides {
|
||||
ALL("All"), FRONT_AND_BACK("Front and Back"), NONE("None");
|
||||
|
||||
private final String label;
|
||||
|
||||
Sides(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Dial Scale", author = "Branislav Stojkovic", category = "Misc",
|
||||
@ComponentDescriptor(name = "Dial Scale", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "DS", description = "Control panel dial scale", zOrder = IDIYComponent.CHASSIS + 0.1,
|
||||
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class)
|
||||
public class DialScale extends AbstractComponent<String> {
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ import org.diylc.core.Project;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
|
||||
@ComponentDescriptor(name = "Elliptical Cutout", author = "Branislav Stojkovic", category = "Electro-Mechanical",
|
||||
@ComponentDescriptor(name = "Elliptical Cutout", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "ELC", description = "Elliptical chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1,
|
||||
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class)
|
||||
public class EllipticalCutout extends AbstractShape {
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
@ComponentDescriptor(name = "Polygonal Cutout", author = "Branislav Stojkovic", category = "Electro-Mechanical",
|
||||
@ComponentDescriptor(name = "Polygonal Cutout", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "POLYC", description = "Polygonal chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1,
|
||||
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class)
|
||||
public class PolygonalCutout extends AbstractShape {
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Rectangular Cutout", author = "Branislav Stojkovic", category = "Electro-Mechanical",
|
||||
@ComponentDescriptor(name = "Rectangular Cutout", author = "Branislav Stojkovic", category = "Hardware",
|
||||
instanceNamePrefix = "RECTC", description = "Rectangular chassis cutout, with or without rounded edges",
|
||||
zOrder = IDIYComponent.CHASSIS + 0.1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
|
||||
transformer = SimpleComponentTransformer.class)
|
||||
|
||||
+1
-1
@@ -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 = "Electro-Mechanical", author = "Branislav Stojkovic",
|
||||
@ComponentDescriptor(name = "Drill Hole", category = "Hardware", 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",
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class AbstractShape extends AbstractTransparentComponent<Void> {
|
||||
|
||||
protected Color color = COLOR;
|
||||
protected Color borderColor = BORDER_COLOR;
|
||||
protected Size borderThickness = new Size(0.2d, SizeUnit.mm);
|
||||
protected Size borderThickness = new Size(1.0, SizeUnit.px);
|
||||
|
||||
@EditableProperty(name = "Color")
|
||||
public Color getColor() {
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
Diecast (1590),1590LLB,50.5 mm,50.5 mm,21 mm
|
||||
Diecast (1590),1590LB,50.6 mm,50.55 mm,27 mm
|
||||
Diecast (1590),1590H,38 mm,53 mm,27 mm
|
||||
Diecast (1590),1590Y,92 mm,92 mm,38 mm
|
||||
Diecast (1590),1590A,38.5 mm,92.6 mm,27 mm
|
||||
Diecast (1590),1590G,50 mm,100 mm,21.5 mm
|
||||
Diecast (1590),1590G2,50 mm,100 mm,27 mm
|
||||
Diecast (1590),1590S,82.4 mm,110.5 mm,40 mm
|
||||
Diecast (1590),1590B,60.5 mm,112.4 mm,27 mm
|
||||
Diecast (1590),1590B2,60.5 mm,112.4 mm,33.5 mm
|
||||
Diecast (1590),1590BS,60.5 mm,112 mm,38 mm
|
||||
Diecast (1590),1590B3,77 mm,116 mm,33.5 mm
|
||||
Diecast (1590),1590BB,94 mm,119.5 mm,30 mm
|
||||
Diecast (1590),1590BB2,94 mm,119.5 mm,33.75 mm
|
||||
Diecast (1590),1590BBS,94 mm,119.5 mm,38.1 mm
|
||||
Diecast (1590),1590Q,120 mm,120 mm,30 mm
|
||||
Diecast (1590),1590U,120 mm,120 mm,55 mm
|
||||
Diecast (1590),1590V,120 mm,120 mm,90 mm
|
||||
Diecast (1590),1590C,94 mm,119.5 mm,52.5 mm
|
||||
Diecast (1590),1590T,80 mm,120 mm,55 mm
|
||||
Diecast (1590),1590CE,100 mm,120 mm,61 mm
|
||||
Diecast (1590),1590N1,65.5 mm,121.2 mm,35.8 mm
|
||||
Diecast (1590),1590KK,125 mm,125 mm,53 mm
|
||||
Diecast (1590),1590K,125 mm,125 mm,75 mm
|
||||
Diecast (1590),1590J,145 mm,95 mm,45.1 mm
|
||||
Diecast (1590),1590XX,145.2 mm,121.2 mm,35.2 mm
|
||||
Diecast (1590),1590X,145.2 mm,121.2 mm,52.3 mm
|
||||
Diecast (1590),1590P1,153 mm,83.1 mm,46.4 mm
|
||||
Diecast (1590),1590D,187.75 mm,119.5 mm,52 mm
|
||||
Diecast (1590),1590DD,188 mm,120 mm,33 mm
|
||||
Diecast (1590),1590E,188 mm,120 mm,78 mm
|
||||
Diecast (1590),1590F,188 mm,188 mm,63 mm
|
||||
Diecast (1590),1590R1,192 mm,112 mm,57 mm
|
||||
Diecast (1590),1590DE,200 mm,120 mm,60 mm
|
||||
Diecast (1590),1590EE,200 mm,120 mm,81 mm
|
||||
Diecast (1590),1590BX2,254 mm,70 mm,31 mm
|
||||
Diecast (1590),1590BX,254 mm,70 mm,46 mm
|
||||
Diecast (1550),1550Q,55 mm,60 mm,26 mm
|
||||
Diecast (1550),1550P,55 mm,80 mm,21 mm
|
||||
Diecast (1550),1550A,35 mm,89 mm,26 mm
|
||||
Diecast (1550),1550B,64 mm,114.5 mm,26 mm
|
||||
Diecast (1550),1550D,64 mm,115 mm,51 mm
|
||||
Diecast (1550),1550C,90 mm,115 mm,51 mm
|
||||
Diecast (1550),1550M,100 mm,120 mm,31 mm
|
||||
Diecast (1550),1550K,140 mm,102 mm,73 mm
|
||||
Diecast (1550),1550L,165 mm,127 mm,73 mm
|
||||
Diecast (1550),1550E,171 mm,121 mm,51 mm
|
||||
Diecast (1550),1550F,171 mm,121 mm,101 mm
|
||||
Diecast (1550),1550G,222 mm,146 mm,51 mm
|
||||
Diecast (1550),1550H,222 mm,146 mm,101 mm
|
||||
Diecast (1550),1550N,250 mm,250 mm,97 mm
|
||||
Diecast (1550),1550J,275 mm,175 mm,63 mm
|
||||
Others,125B,66 mm,122 mm,36 mm
|
||||
Chassis - Steel (1441),1441-9,8 in,4 in,1 in
|
||||
Chassis - Steel (1441),1441-15,10 in,6 in,1 in
|
||||
Chassis - Steel (1441),1441-6,4 in,4 in,2 in
|
||||
Chassis - Steel (1441),1441-8,6 in,4 in,2 in
|
||||
Chassis - Steel (1441),1441-12,7 in,5 in,2 in
|
||||
Chassis - Steel (1441),1441-10,8 in,4 in,2 in
|
||||
Chassis - Steel (1441),1441-14,9 in,5 in,2 in
|
||||
Chassis - Steel (1441),1441-16,10 in,6 in,2 in
|
||||
Chassis - Steel (1441),1441-22,12 in,8 in,2 in
|
||||
Chassis - Steel (1441),1441-29,12 in,10 in,2 in
|
||||
Chassis - Steel (1441),1441-18,13.5 in,5 in,2 in
|
||||
Chassis - Steel (1441),1441-26,16 in,8 in,2 in
|
||||
Chassis - Steel (1441),1441-30,17 in,10 in,2 in
|
||||
Chassis - Steel (1441),1441-34,17 in,12 in,2 in
|
||||
Chassis - Steel (1441),1441-24,12 in,8 in,3 in
|
||||
Chassis - Steel (1441),1441-28,16 in,8 in,3 in
|
||||
Chassis - Steel (1441),1441-20,17 in,4 in,3 in
|
||||
Chassis - Steel (1441),1441-32,17 in,10 in,3 in
|
||||
Chassis - Steel (1441),1441-36,17 in,12 in,3 in
|
||||
Chassis - Steel (1441),1441-38,17 in,14 in,3 in
|
||||
Chassis - Steel (1441),1441-33,17 in,10 in,4 in
|
||||
Chassis - Steel (1441),1441-40,17 in,14 in,4 in
|
||||
Chassis - Steel (1441),1441-42,17 in,14 in,5 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-45351,4.5 in,3.5 in,1 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-9,8 in,4 in,1 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-15,10 in,6 in,1 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-6415,6 in,4 in,1.5 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-84515,8 in,4.5 in,1.5 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-6,4 in,4 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-542,5 in,4 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-8,6 in,4 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-12,7 in,5 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-772,7 in,7 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-10,8 in,4 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-862,8 in,6 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-14,9 in,5 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-972,9 in,7 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-9552,9.5 in,5 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-16,10 in,6 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-1172,11 in,7 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-22,12 in,8 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-29,12 in,10 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-1372,13 in,7 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-18,13.5 in,5 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-26,16 in,8 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-30,17 in,10 in,2 in
|
||||
Chassis - Aluminium (1444) 1-2 in,1444-17132,17 in,13 in,2 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-95525,9.5 in,5 in,2.5 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-10825,10 in,8 in,2.5 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-12825,12 in,8 in,2.5 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-643,6 in,4 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-753,7 in,5 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-9553,9.5 in,5 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-1053,10 in,5 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-1273,12 in,7 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-24,12 in,8 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-12103,12 in,10 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-12123,12 in,12 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-1463,14 in,6 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-14103,14 in,10 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-1573,15 in,7 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-1593,15 in,9 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-28,16 in,8 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-20,17 in,4 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-1763,17 in,6 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-1773,17 in,7 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-1783,17 in,8 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-32,17 in,10 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-17123,17 in,12 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-17133,17 in,13 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-17143,17 in,14 in,3 in
|
||||
Chassis - Aluminium (1444) 2.5-3 in,1444-17173,17 in,17 in,3 in
|
||||
Chassis - Aluminium (1444) 4-6 in,1444-33,17 in,10 in,4 in
|
||||
Chassis - Aluminium (1444) 4-6 in,1444-17134,17 in,13 in,4 in
|
||||
Chassis - Aluminium (1444) 4-6 in,1444-17154,17 in,15 in,4 in
|
||||
Chassis - Aluminium (1444) 4-6 in,1444-17174,17 in,17 in,4 in
|
||||
Chassis - Aluminium (1444) 4-6 in,1444-17105,17 in,10 in,5 in
|
||||
Chassis - Aluminium (1444) 4-6 in,1444-17135,17 in,13 in,5 in
|
||||
Chassis - Aluminium (1444) 4-6 in,1444-17156,17 in,15 in,6 in
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
|
||||
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.components.chassis;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.components.chassis.ChassisPanel.Sides;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.presenter.DatasheetService;
|
||||
import org.diylc.serialization.ProjectFileManager;
|
||||
import org.diylc.utils.BomEntry;
|
||||
import org.diylc.utils.BomMaker;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ChassisPanelDatasheetTest {
|
||||
|
||||
private static final double TOLERANCE = 1e-6;
|
||||
|
||||
private static String[] row(String model) {
|
||||
return DatasheetService.getInstance().loadDatasheet(ChassisPanel.class).stream()
|
||||
.filter(row -> row[1].equals(model)).findFirst().get();
|
||||
}
|
||||
|
||||
private static double mm(double value) {
|
||||
return new Size(value, SizeUnit.mm).convertToPixels();
|
||||
}
|
||||
|
||||
private static void assertRect(Rectangle2D expected, Rectangle2D actual) {
|
||||
Assert.assertEquals(expected.getX(), actual.getX(), TOLERANCE);
|
||||
Assert.assertEquals(expected.getY(), actual.getY(), TOLERANCE);
|
||||
Assert.assertEquals(expected.getWidth(), actual.getWidth(), TOLERANCE);
|
||||
Assert.assertEquals(expected.getHeight(), actual.getHeight(), TOLERANCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void everyRowApplies() {
|
||||
List<String[]> datasheet = DatasheetService.getInstance().loadDatasheet(ChassisPanel.class);
|
||||
Assert.assertNotNull(datasheet);
|
||||
Assert.assertFalse(datasheet.isEmpty());
|
||||
for (String[] row : datasheet) {
|
||||
Assert.assertEquals(String.join(",", row), 5, row.length);
|
||||
ChassisPanel enclosure = new ChassisPanel(row);
|
||||
Assert.assertEquals(row[1], enclosure.getValue());
|
||||
Assert.assertEquals(row[1], Size.parseSize(row[4]), enclosure.getHeight());
|
||||
Point2D first = enclosure.getControlPoint(0);
|
||||
Point2D second = enclosure.getControlPoint(1);
|
||||
Assert.assertEquals(row[1], Size.parseSize(row[2]).convertToPixels(),
|
||||
second.getX() - first.getX(), TOLERANCE);
|
||||
Assert.assertEquals(row[1], Size.parseSize(row[3]).convertToPixels(),
|
||||
second.getY() - first.getY(), TOLERANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aNewEnclosureIsA125BWithAllSides() {
|
||||
ChassisPanel enclosure = new ChassisPanel();
|
||||
ChassisPanel fromDatasheet = new ChassisPanel(row("125B"));
|
||||
|
||||
Assert.assertEquals(fromDatasheet.getValue(), enclosure.getValue());
|
||||
Assert.assertEquals(fromDatasheet.getHeight(), enclosure.getHeight());
|
||||
Assert.assertEquals(fromDatasheet.getEdgeRadius(), enclosure.getEdgeRadius());
|
||||
Assert.assertEquals(fromDatasheet.getControlPoint(1), enclosure.getControlPoint(1));
|
||||
Assert.assertEquals(Sides.ALL, enclosure.getSides());
|
||||
Assert.assertEquals(4, enclosure.getSidePanels().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pedalSizedBoxesAreUprightAndBiggerOnesHorizontal() {
|
||||
for (String model : new String[] {"125B", "1590A", "1590B", "1590BB", "1550B"}) {
|
||||
Point2D second = new ChassisPanel(row(model)).getControlPoint(1);
|
||||
Assert.assertTrue(model, second.getY() > second.getX());
|
||||
}
|
||||
for (String model : new String[] {"1590XX", "1590DD", "1441-10", "1444-32"}) {
|
||||
Point2D second = new ChassisPanel(row(model)).getControlPoint(1);
|
||||
Assert.assertTrue(model, second.getX() > second.getY());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modelNamesAreUnique() {
|
||||
List<String[]> datasheet = DatasheetService.getInstance().loadDatasheet(ChassisPanel.class);
|
||||
Assert.assertEquals(datasheet.size(),
|
||||
datasheet.stream().map(row -> row[1]).distinct().count());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modelLeavesTheRadiusAlone() {
|
||||
ChassisPanel enclosure = new ChassisPanel();
|
||||
enclosure.setEdgeRadius(new Size(3d, SizeUnit.mm));
|
||||
|
||||
enclosure.applyModel(row("1590BB"));
|
||||
|
||||
Assert.assertEquals(new Size(3d, SizeUnit.mm), enclosure.getEdgeRadius());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inchRowsKeepTheirUnit() {
|
||||
ChassisPanel enclosure = new ChassisPanel(row("1444-32"));
|
||||
Assert.assertEquals(new Size(3d, SizeUnit.in), enclosure.getHeight());
|
||||
Point2D first = enclosure.getControlPoint(0);
|
||||
Point2D second = enclosure.getControlPoint(1);
|
||||
Assert.assertEquals(new Size(17d, SizeUnit.in).convertToPixels(),
|
||||
second.getX() - first.getX(), TOLERANCE);
|
||||
Assert.assertEquals(new Size(10d, SizeUnit.in).convertToPixels(),
|
||||
second.getY() - first.getY(), TOLERANCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sidesUnfoldAroundTheTopPanel() {
|
||||
ChassisPanel enclosure = new ChassisPanel(row("1590BB"));
|
||||
|
||||
Rectangle2D[] panels = enclosure.getSidePanels();
|
||||
|
||||
Assert.assertEquals(4, panels.length);
|
||||
assertRect(new Rectangle2D.Double(0, -mm(30), mm(94), mm(30)), panels[0]);
|
||||
assertRect(new Rectangle2D.Double(0, mm(119.5), mm(94), mm(30)), panels[1]);
|
||||
assertRect(new Rectangle2D.Double(-mm(30), 0, mm(30), mm(119.5)), panels[2]);
|
||||
assertRect(new Rectangle2D.Double(mm(94), 0, mm(30), mm(119.5)), panels[3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void spacingSetsTheSidesApart() {
|
||||
ChassisPanel enclosure = new ChassisPanel(row("1590BB"));
|
||||
enclosure.setSpacing(new Size(2d, SizeUnit.mm));
|
||||
|
||||
Rectangle2D[] panels = enclosure.getSidePanels();
|
||||
|
||||
assertRect(new Rectangle2D.Double(0, -mm(32), mm(94), mm(30)), panels[0]);
|
||||
assertRect(new Rectangle2D.Double(0, mm(121.5), mm(94), mm(30)), panels[1]);
|
||||
assertRect(new Rectangle2D.Double(-mm(32), 0, mm(30), mm(119.5)), panels[2]);
|
||||
assertRect(new Rectangle2D.Double(mm(96), 0, mm(30), mm(119.5)), panels[3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void frontAndBackOnly() {
|
||||
ChassisPanel enclosure = new ChassisPanel(row("1590BB"));
|
||||
enclosure.setSides(Sides.FRONT_AND_BACK);
|
||||
|
||||
Rectangle2D[] panels = enclosure.getSidePanels();
|
||||
|
||||
Assert.assertEquals(2, panels.length);
|
||||
assertRect(new Rectangle2D.Double(0, -mm(30), mm(94), mm(30)), panels[0]);
|
||||
assertRect(new Rectangle2D.Double(0, mm(119.5), mm(94), mm(30)), panels[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noSidesKeepsTheModelButDrawsOnePanel() {
|
||||
ChassisPanel enclosure = new ChassisPanel(row("1590BB"));
|
||||
enclosure.setSides(Sides.NONE);
|
||||
|
||||
Assert.assertEquals(0, enclosure.getSidePanels().length);
|
||||
Assert.assertEquals(new Size(30d, SizeUnit.mm), enclosure.getHeight());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sidesFollowTheTopPanelWhenItIsStretched() {
|
||||
ChassisPanel enclosure = new ChassisPanel(row("1590BB"));
|
||||
enclosure.setControlPoint(new Point2D.Double(mm(200), mm(100)), 1);
|
||||
|
||||
Rectangle2D[] panels = enclosure.getSidePanels();
|
||||
|
||||
assertRect(new Rectangle2D.Double(0, mm(100), mm(200), mm(30)), panels[1]);
|
||||
assertRect(new Rectangle2D.Double(mm(200), 0, mm(30), mm(100)), panels[3]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withoutHeightItIsASinglePanel() {
|
||||
ChassisPanel enclosure = new ChassisPanel();
|
||||
enclosure.setHeight(new Size(0d, SizeUnit.mm));
|
||||
Assert.assertEquals(0, enclosure.getSidePanels().length);
|
||||
|
||||
enclosure.setHeight(null);
|
||||
Assert.assertEquals(0, enclosure.getSidePanels().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void panelFromAnOldFileIsASinglePanel() {
|
||||
// a panel from before the datasheet: no model, a radius of 0 and a free-form size
|
||||
ChassisPanel original = new ChassisPanel();
|
||||
original.setValue("");
|
||||
original.setEdgeRadius(new Size(0d, SizeUnit.mm));
|
||||
original.setControlPoint(new Point2D.Double(20, 30), 1);
|
||||
String xml = ProjectFileManager.xStreamSerializer.toXML(original)
|
||||
.replaceAll("\\s*<height[^>]*/>", "").replaceAll("\\s*<height>.*?</height>", "")
|
||||
.replaceAll("\\s*<sides>[^<]*</sides>", "")
|
||||
.replaceAll("\\s*<spacing[^>]*/>", "").replaceAll("\\s*<spacing>.*?</spacing>", "");
|
||||
Assert.assertFalse(xml, xml.contains("<height"));
|
||||
Assert.assertFalse(xml, xml.contains("<sides>"));
|
||||
Assert.assertFalse(xml, xml.contains("<spacing"));
|
||||
|
||||
ChassisPanel reloaded = (ChassisPanel) ProjectFileManager.xStreamSerializer.fromXML(xml);
|
||||
|
||||
Assert.assertNull(reloaded.getHeight());
|
||||
Assert.assertEquals(Sides.ALL, reloaded.getSides());
|
||||
Assert.assertEquals(new Size(0d, SizeUnit.mm), reloaded.getSpacing());
|
||||
Assert.assertEquals(0, reloaded.getSidePanels().length);
|
||||
Assert.assertEquals("", reloaded.getValueForDisplay());
|
||||
Assert.assertEquals(new Size(0d, SizeUnit.mm), reloaded.getEdgeRadius());
|
||||
Assert.assertEquals(new Point2D.Double(20, 30), reloaded.getControlPoint(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bomListsEnclosuresByModel() {
|
||||
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
|
||||
components.add(new ChassisPanel(row("1590BB")));
|
||||
components.add(new ChassisPanel(row("1590BB")));
|
||||
components.add(new ChassisPanel(row("1590B")));
|
||||
|
||||
List<BomEntry> bom = BomMaker.getInstance().createBom(components);
|
||||
|
||||
Assert.assertEquals(2, bom.size());
|
||||
BomEntry bb = bom.stream().filter(e -> "1590BB".equals(e.getValue())).findFirst().get();
|
||||
Assert.assertEquals("Enclosure", bb.getType());
|
||||
Assert.assertEquals(Integer.valueOf(2), bb.getQuantity());
|
||||
}
|
||||
}
|
||||
+10
-16
@@ -37,11 +37,11 @@ import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.ComponentGroup;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.lang.LangUtil;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
import org.diylc.swing.gui.ComponentPopupMenu;
|
||||
import org.diylc.swing.gui.DragDropList;
|
||||
@@ -257,7 +257,7 @@ public class ExplorerPane extends JPanel {
|
||||
0, false, false)
|
||||
.getPreferredSize().height);
|
||||
componentList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
componentList.setCellRenderer(new ComponentListCellRenderer(plugInPort.getComponentTypes()));
|
||||
componentList.setCellRenderer(new ComponentListCellRenderer());
|
||||
selectionListener = new ListSelectionListener() {
|
||||
|
||||
@Override
|
||||
@@ -586,13 +586,6 @@ public class ExplorerPane extends JPanel {
|
||||
|
||||
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
|
||||
|
||||
private Map<String, ComponentType> componentTypes;
|
||||
|
||||
public ComponentListCellRenderer(Map<String, List<ComponentType>> componentTypeMap) {
|
||||
this.componentTypes = componentTypeMap.values().stream().flatMap(x -> x.stream())
|
||||
.collect(Collectors.toMap(x -> x.getInstanceClass().getCanonicalName(), x -> x));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<? extends ComponentGroupItem> list,
|
||||
ComponentGroupItem value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
@@ -605,14 +598,15 @@ public class ExplorerPane extends JPanel {
|
||||
if (groupItem.getComponentCount() == 1) {
|
||||
// Render as individual component (ungrouped)
|
||||
IDIYComponent<?> component = groupItem.getGroup().iterator().next();
|
||||
ComponentType componentType = componentTypes.get(component.getClass().getCanonicalName());
|
||||
|
||||
if (componentType == null) {
|
||||
double zOrder = ComponentProcessor.getInstance().getZOrder(component);
|
||||
|
||||
// internal types without a descriptor have no layer
|
||||
if (zOrder == Double.MAX_VALUE) {
|
||||
renderer.setText(component.toString());
|
||||
return renderer;
|
||||
}
|
||||
|
||||
int layerId = (int) Math.round(componentType.getZOrder());
|
||||
int layerId = (int) Math.round(zOrder);
|
||||
|
||||
String valueForDisplay = component.getValueForDisplay();
|
||||
if (isSelected) {
|
||||
@@ -637,9 +631,9 @@ public class ExplorerPane extends JPanel {
|
||||
// Calculate maximum layer from components in the group
|
||||
int maxLayerId = 0;
|
||||
for (IDIYComponent<?> component : groupItem.getGroup()) {
|
||||
ComponentType componentType = componentTypes.get(component.getClass().getCanonicalName());
|
||||
if (componentType != null) {
|
||||
int layerId = (int) Math.round(componentType.getZOrder());
|
||||
double zOrder = ComponentProcessor.getInstance().getZOrder(component);
|
||||
if (zOrder != Double.MAX_VALUE) {
|
||||
int layerId = (int) Math.round(zOrder);
|
||||
if (layerId > maxLayerId) {
|
||||
maxLayerId = layerId;
|
||||
}
|
||||
|
||||
@@ -716,3 +716,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names|Pinnamen
|
||||
Pin Labels|Pin-Beschriftungen
|
||||
Names|Namen
|
||||
Hardware|Hardware
|
||||
Sides|Seiten
|
||||
All|Alle
|
||||
Front and Back|Vorne und hinten
|
||||
|
||||
@@ -709,3 +709,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names
|
||||
Pin Labels
|
||||
Names
|
||||
Hardware
|
||||
Sides
|
||||
All
|
||||
Front and Back
|
||||
|
||||
@@ -712,3 +712,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names|Nombres de Pines
|
||||
Pin Labels|Etiquetas de Pines
|
||||
Names|Nombres
|
||||
Hardware|Herrajes
|
||||
Sides|Lados
|
||||
All|Todos
|
||||
Front and Back|Frente y parte trasera
|
||||
|
||||
@@ -711,3 +711,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names|Noms des broches
|
||||
Pin Labels|Étiquettes des broches
|
||||
Names|Noms
|
||||
Hardware|Quincaillerie
|
||||
Sides|Côtés
|
||||
All|Tous
|
||||
Front and Back|Avant et arrière
|
||||
|
||||
@@ -713,3 +713,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names|Nomi dei Pin
|
||||
Pin Labels|Etichette dei Pin
|
||||
Names|Nomi
|
||||
Hardware|Minuteria
|
||||
Sides|Lati
|
||||
All|Tutti
|
||||
Front and Back|Fronte e retro
|
||||
|
||||
@@ -717,3 +717,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names|Pinnamen
|
||||
Pin Labels|Pinlabels
|
||||
Names|Namen
|
||||
Hardware|Hardware
|
||||
Sides|Zijden
|
||||
All|Alle
|
||||
Front and Back|Voor- en achterkant
|
||||
|
||||
@@ -712,3 +712,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names|Nomes dos Pinos
|
||||
Pin Labels|Rótulos dos Pinos
|
||||
Names|Nomes
|
||||
Hardware|Ferragens
|
||||
Sides|Lados
|
||||
All|Todos
|
||||
Front and Back|Frente e traseira
|
||||
|
||||
@@ -708,3 +708,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names|Nazivi Pinova
|
||||
Pin Labels|Oznake Pinova
|
||||
Names|Nazivi
|
||||
Hardware|Mehanički delovi
|
||||
Sides|Strane
|
||||
All|Sve
|
||||
Front and Back|Prednja i zadnja
|
||||
|
||||
@@ -710,3 +710,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names|पिन नाम
|
||||
Pin Labels|पिन लेबल
|
||||
Names|नाम
|
||||
Hardware|हार्डवेयर
|
||||
Sides|भुजाएं
|
||||
All|सभी
|
||||
Front and Back|आगे और पीछे
|
||||
|
||||
@@ -710,3 +710,7 @@ AI Circuit Analyzer requires a DIYLC Cloud account. Would you like to log in now
|
||||
Pin Names|引脚名称
|
||||
Pin Labels|引脚标签
|
||||
Names|名称
|
||||
Hardware|五金件
|
||||
Sides|侧面
|
||||
All|全部
|
||||
Front and Back|前后
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.diylc;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -14,10 +15,13 @@ import org.junit.Test;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.appframework.miscutils.InMemoryConfigurationManager;
|
||||
import org.diylc.clipboard.ComponentTransferable;
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.components.chassis.ChassisPanel;
|
||||
import org.diylc.components.composite.CompositeComponent;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Template;
|
||||
import org.diylc.presenter.Presenter;
|
||||
@@ -45,6 +49,24 @@ public class PresenterTests extends TestBase {
|
||||
Assert.assertEquals(1, presenter.getCurrentProject().getComponents().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChassisCompositeIsPlacedUnderExistingComponents() {
|
||||
instantiateTwoClick("Passive", "Resistor", new Point(1000, 1000), new Point(1200, 1000));
|
||||
|
||||
CompositeComponent chassis = new CompositeComponent();
|
||||
chassis.initBlockName("Chassis");
|
||||
chassis.getChildComponents().add(new ChassisPanel());
|
||||
chassis.getChildComponents().add(new ChassisPanel());
|
||||
List<IDIYComponent<?>> clipboard = new ArrayList<IDIYComponent<?>>();
|
||||
clipboard.add(chassis);
|
||||
presenter.pasteComponents(new ComponentTransferable(clipboard, "Chassis"), false, true);
|
||||
presenter.mouseClicked(new Point(500, 500), MouseEvent.BUTTON1, false, false, false, 1);
|
||||
|
||||
List<IDIYComponent<?>> components = presenter.getCurrentProject().getComponents();
|
||||
Assert.assertEquals(2, components.size());
|
||||
Assert.assertTrue(components.get(0) instanceof CompositeComponent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodeNameHover() {
|
||||
final String[] receivedTooltip = new String[1];
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
# Chassis and Enclosures
|
||||
|
||||
The Hammond die-cast and amplifier chassis lineup as a datasheet on a single `Enclosure`
|
||||
component that draws either one panel or an exploded view of the whole box.
|
||||
|
||||
## 1. Current state
|
||||
|
||||
- `ChassisPanel` (`diylc-library`, `org.diylc.components.chassis`) is shown as **Enclosure** in the
|
||||
new **Hardware** category, with instance prefix `ENC`. The class name is unchanged, so files,
|
||||
favourites, recent components and variants, all keyed by class, are unaffected. The three
|
||||
cutouts, Drill Hole and Dial Scale moved to Hardware with it.
|
||||
- It is a two-point `AbstractTransparentComponent<String>` (no longer an `AbstractShape`) on the
|
||||
`CHASSIS` layer. The control points are the top panel.
|
||||
With `Height` > 0 the sides are unfolded around it (front above, back below, left and right to
|
||||
the sides; never the bottom), per `Sides`: `All`, `Front and Back` or `None`, set `Spacing`
|
||||
(default 0, edge to edge) apart from the top.
|
||||
- A new enclosure is an upright 125B with all sides, square corners and no spacing (`DEFAULT_*`
|
||||
constants; the size matches its datasheet row).
|
||||
Old files are unaffected: XStream runs no constructor or initializer, so their saved size,
|
||||
radius and empty value stay and their missing `height` keeps them a single panel. `Height` null
|
||||
(old files) or 0, or `Sides = None`, draws a single panel, as `ChassisPanel` always did.
|
||||
- A datasheet of 132 Hammond and generic models (§4) sets `Value` (the model), the top panel size
|
||||
and `Height`; it leaves `Radius` alone. One component is one enclosure, so the BOM lists `Enclosure / 1590BB`.
|
||||
- The four old factory variants (`125B`, `A`, `B`, `BB`) are withdrawn as `deletedOn` stubs.
|
||||
- Composites take the lowest layer of their children (`ComponentProcessor.getZOrder`), so a
|
||||
building block made of chassis parts sits on the Chassis layer and hides and locks with it.
|
||||
|
||||
## 2. Design decisions
|
||||
|
||||
| # | Decision | Rationale |
|
||||
|---|---|---|
|
||||
| D1 | One component draws the whole enclosure; no per-side panels and no exploded building blocks | Every datasheet model is an exploded enclosure in one click, the BOM gets one line per box, stretching the top drags the sides along, rotation needs no special code, and the component sits on the Chassis layer natively. Building blocks would have needed import tracking, a flat toolbar of ~10 buttons, and a per-panel BOM workaround. |
|
||||
| D2 | Row format `Group,Model,X,Y,Height`: the top panel's size as placed, then the wall height, every size with its unit (`119.5 mm`, `17 in`), parsed with `Size.parseSize` like `DIL_IC` | Pedal drawings are metric, Hammond chassis are nominal inches; writing each in its native unit keeps the file checkable against the drawings. |
|
||||
| D3 | `ChassisPanel` no longer extends `AbstractShape`; it is an `AbstractTransparentComponent<String>` whose value is the model. It keeps every field name it inherited (`value`, `controlPoints`, `firstPoint`, `secondPoint`, `color`, `borderColor`), and `borderThickness` stays as a `@Deprecated` unused field; `edgeRadius`, `height`, `sides` and `spacing` read `null` from old files and default in their getters | XStream fails on unknown fields, so a name an old file stores must stay. The border is a fixed 1 px line; old panels drawn with a thicker border now draw with 1 px. |
|
||||
| D4 | Die-cast boxes up to 125 mm long (1590, 1550, 125B) are listed upright, with Hammond's length along Y; longer boxes and all 1441/1444 chassis horizontal. A new enclosure is an upright 125B. `applyModel` sets `Value`, `Height` and the top panel size, keeping the first control point and the direction the panel is drawn in | Pedals use the small boxes upright, with the jacks and DC socket on the short ends, which the front and back panels then show; bigger boxes and amp chassis are used lying down. |
|
||||
| D5 | The datasheet carries no corner radius; `Radius` defaults to 0 and only the top panel uses it, the sides are drawn square | Hammond does not publish the die-cast corner radius (§5), so rounded corners are set by hand when wanted. |
|
||||
| D6 | Length/Width are Hammond's outside dimensions; Height is the drillable wall: box height without the lid for die-cast boxes, outside height for 1441/1444 | The lid of a 1590 is the pedal's bottom, which the exploded view leaves out. |
|
||||
| D7 | Die-cast taper is ignored: the top uses the outer size at the lid opening and the sides are rectangles | Hammond does not publish the floor size; the walls slope at most 2 deg, so the floor is 0.7-1.9 mm smaller per side (§5). |
|
||||
| D8 | A composite's z-order is the minimum of its children's, computed per instance | A composite is drawn as a unit, so it should sit under what is placed on it afterwards; a maker board built from a board, pads and silkscreen text belongs on the Board layer, not the Text layer. |
|
||||
| D9 | Die-cast boxes come from the 1590 and 1550 series only, natural finish only, plus generic sizes such as 125B under `Others`. HWCHAS walnut chassis and rack cases are out | Painted and black versions share the natural part's dimensions, and the shaped 1590 STOMP boxes (TRPB, TRPC, STPC) are sold painted only. |
|
||||
|
||||
## 3. Implementation
|
||||
|
||||
### 3.1 Composite z-order (core) - done
|
||||
|
||||
- `ComponentProcessor.getZOrder(IDIYComponent<?>)`: for a `CompositeComponent`, the minimum over
|
||||
its children, recursing into nested composites; a childless composite and any other component
|
||||
use the type's z-order. Not cached: a type lookup is a map hit and composites are few.
|
||||
- Every class-level layer read goes through it: `Presenter` insertion, hidden and locked layers,
|
||||
`selectAll(layer)`, send to back / bring to front; `GroupAndLockIndex.isLocked`;
|
||||
`ComparatorFactory.getComponentZOrderComparator`; the `[L#]` tag in `ExplorerPane`.
|
||||
- Tests: `CompositeComponentTest` and
|
||||
`PresenterTests.testChassisCompositeIsPlacedUnderExistingComponents`.
|
||||
|
||||
### 3.2 Enclosure (library) - done
|
||||
|
||||
- `ChassisPanel` implements `IDatasheetSupport` (two creation steps, model column 1) with a
|
||||
`ChassisPanel(String[] model)` constructor; rows in `datasheets/ChassisPanel.datasheet`.
|
||||
- `getSidePanels()` derives the side rectangles from the top panel's normalized corners and
|
||||
`Spacing` (a new field; `null` from files reads as 0); `draw()`
|
||||
fills them before `stopTracking()` so they take part in hit-testing, and outlines them with the
|
||||
top. `getValueForDisplay()` returns the model.
|
||||
- Category `Hardware` for `ChassisPanel`, the three cutouts, `DrillHole` and `DialScale`. New
|
||||
language keys in every `lang/` file: `Hardware`, `Sides`, `All`, `Front and Back` (`Height`
|
||||
and `None` existed). `catalog_full.json` and `catalog_index.json` regenerated.
|
||||
- Tests: `ChassisPanelDatasheetTest` (every row applies, unique model names, inch rows,
|
||||
radius left alone by a model, side layout for All / Front and Back / None, spacing, sides follow a stretched top, no height, old-file
|
||||
panel, BOM).
|
||||
|
||||
### 3.3 Verify
|
||||
|
||||
`mvn -q test`, then the regression suite: the z-order change alters hide/lock of existing
|
||||
composites, and `ChassisPanel` gained serialized fields and a new category.
|
||||
|
||||
## 4. Datasheet rows
|
||||
|
||||
Sources: Hammond per-part drawings, `https://www.hammfg.com/files/parts/pdf/<PART>.pdf`; series
|
||||
tables on hammfg.com (1590, 1590-STOMP, 1441, 1444). Die-cast sizes are drawing outside dimensions
|
||||
at the lid opening; heights are the box without the 4 mm lid. Chassis sizes are Hammond's nominal
|
||||
outside W x D x H. Rows of die-cast boxes up to 125 mm long have their two top sizes swapped so
|
||||
they place upright (D4). There is no radius column (D5).
|
||||
|
||||
Die-cast boxes are grouped by series only (1590, 1550), in Hammond's catalogue order, and only
|
||||
natural-finish (unpainted) part numbers are rows. Chassis are grouped by family, then height. The
|
||||
1590 group has 37 rows; the toolbox already splits a datasheet submenu longer than
|
||||
`MAX_MENU_ITEMS` (30) into ranged submenus, so it needs no further split.
|
||||
|
||||
The rows are in `diylc-library/src/main/resources/datasheets/ChassisPanel.datasheet`.
|
||||
|
||||
|
||||
Group sizes: 37 (1590), 15 (1550), 1 (Others); 23 / 24 / 25 / 7 chassis (132 rows). `Others`
|
||||
holds generic sizes sold by several makers under one name, currently only 125B (122 x 66 x 40 mm
|
||||
with the backplate, per a maker's listing). The other 1590 rows were read from the per-part
|
||||
drawings, except 1590H, U, V, CE, KK, K, E, F, R1, DE, EE, BX2 and BX, which come from Hammond's
|
||||
series table (whole mm, lid included) like all 1550 rows but 1550B.
|
||||
|
||||
Finish and option suffixes are not rows: `BK3` (black 1441), `BK` (black 1550), colour codes on
|
||||
1590 (`RD`, `CB`, ...), `W` prefix (watertight; IP66/IP67 gaskets on the 1550), `F`/`FL`
|
||||
(flanged), `CWW` (walnut sides on sizes 12/16/22/24/32/33, which shorten the usable front, back and
|
||||
top by about 22 mm).
|
||||
|
||||
## 5. Unsourced or conflicting figures
|
||||
|
||||
| Item | Status |
|
||||
|---|---|
|
||||
| Die-cast corner radius (top view) and top-to-side edge fillet | Not published, so not in the datasheet (D5). Measure from Hammond STEP models or a box if it is ever wanted. |
|
||||
| Die-cast floor size (pedal top face) | Not published; between the outer size and outer minus 2 x (box height x tan 2 deg). |
|
||||
| 1590DD box height | Drawing gives 37.00 both overall and box; 33 assumes the usual 4 mm lid. |
|
||||
| 1590D box height | ~52, same assumption. |
|
||||
| Box heights of the table-only 1590 rows (H, U, V, CE, KK, K, E, F, R1, DE, EE, BX2, BX) | Table height minus the 4 mm lid; length and width are the table's rounded figures. Read the drawings to firm them up. |
|
||||
| 125B box height | 40 mm with the backplate minus an assumed 4 mm backplate (the 1590 lid); makers do not state the plate thickness. |
|
||||
| 1550 box heights (all but 1550B) | Series table height (lid included) minus 4 mm, the overall-to-box difference on the 1550B drawing (30.10 / 26.00). |
|
||||
| 1590BS / 1590B2 height | Web table 38 for both; drawings 42.00 overall / 38.00 box and 37.50 overall. Drawings used. |
|
||||
| 1444-10/-12/-14 height | Drawings say 49.78 mm; catalogue and inner height fit 50.80 (2 in). 2 in used. |
|
||||
| 1441-42 sheet | Drawing 0.057", product page 18 ga. Irrelevant to the outline. |
|
||||
|
||||
## 6. Later
|
||||
|
||||
- HWCHAS walnut-frame chassis (HWCHAS1310 / 1710; aluminium top 298.45 x 222.25 / 400.05 x
|
||||
222.25 mm on a 19.05 mm walnut frame): a different construction from the folded sheet metal.
|
||||
- Hammond rack cases (RM, RMCS) and the 1458 instrument enclosure.
|
||||
- Factory building blocks are still imported once, behind the boolean
|
||||
`DEFAULT_BLOCKS_IMPORTED_KEY`, so a block added to `blocks.xml` later never reaches existing
|
||||
users. Fix by giving factory blocks `createdOn`/`deletedOn` and an import date, as `VariantManager`
|
||||
does, when a new factory block is next needed.
|
||||
- Configs older than class-keyed variants store keys like `Electro-Mechanical.Chassis Panel`;
|
||||
`VariantManager`'s upgrade maps them by the current category and name, so such variants would
|
||||
not carry over. Map the legacy name if it turns out to matter.
|
||||
Reference in New Issue
Block a user