diff --git a/diylc/catalog_full.json b/diylc/catalog_full.json
index be4731d2..cbd0396c 100644
--- a/diylc/catalog_full.json
+++ b/diylc/catalog_full.json
@@ -11509,7 +11509,7 @@
"type" : "Size",
"format" : "(value)(unit)",
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
- "defaultValue" : "0.2mm"
+ "defaultValue" : "1px"
}, {
"name" : "Color",
"type" : "Color",
@@ -11538,12 +11538,6 @@
"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",
@@ -11602,7 +11596,7 @@
"type" : "Size",
"format" : "(value)(unit)",
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
- "defaultValue" : "0.2mm"
+ "defaultValue" : "1px"
}, {
"name" : "Color",
"type" : "Color",
@@ -11639,7 +11633,7 @@
"type" : "Size",
"format" : "(value)(unit)",
"possibleUnits" : [ "px", "mm", "cm", "m", "in", "ft", "yd" ],
- "defaultValue" : "0.2mm"
+ "defaultValue" : "1px"
}, {
"name" : "Color",
"type" : "Color",
@@ -18741,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",
@@ -18842,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",
@@ -18879,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",
diff --git a/diylc/diylc-core/src/main/resources/update.xml b/diylc/diylc-core/src/main/resources/update.xml
index fec9e759..ef1ddd6c 100644
--- a/diylc/diylc-core/src/main/resources/update.xml
+++ b/diylc/diylc-core/src/main/resources/update.xml
@@ -531,7 +531,7 @@
NEW_FEATURE
- Added a datasheet to 'Enclosure' with Hammond 1590, 1550, 1441 and 1444 enclosures and the 125B size
+ Added a datasheet to 'Enclosure' with Hammond 1590, 1550, 1441 and 1444 enclosures and the 125B size - more than 130 variations
IMPROVEMENT
diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/chassis/ChassisPanel.java b/diylc/diylc-library/src/main/java/org/diylc/components/chassis/ChassisPanel.java
index 690ed75e..9d8d6f33 100644
--- a/diylc/diylc-library/src/main/java/org/diylc/components/chassis/ChassisPanel.java
+++ b/diylc/diylc-library/src/main/java/org/diylc/components/chassis/ChassisPanel.java
@@ -21,19 +21,21 @@
*/
package org.diylc.components.chassis;
+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;
@@ -50,10 +52,13 @@ import org.diylc.core.measures.SizeUnit;
zOrder = IDIYComponent.CHASSIS, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false,
transformer = SimpleComponentTransformer.class, enableDatasheet = true,
datasheetCreationStepCount = 2, datasheetModelColumn = 1)
-public class ChassisPanel extends AbstractShape implements IDatasheetSupport {
+public class ChassisPanel extends AbstractTransparentComponent
+ implements IDatasheetSupport {
private static final long serialVersionUID = 1L;
+ 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);
@@ -62,17 +67,25 @@ public class ChassisPanel extends AbstractShape implements IDatasheetSupport {
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();
- this.value = DEFAULT_MODEL;
- setControlPoint(new Point2D.Double(DEFAULT_TOP_WIDTH.convertToPixels(),
- DEFAULT_TOP_LENGTH.convertToPixels()), 1);
+ updateCorners();
}
public ChassisPanel(String[] model) {
@@ -81,11 +94,12 @@ public class ChassisPanel extends AbstractShape implements IDatasheetSupport {
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
+ // 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) {
- setModel(model[1]);
+ 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];
@@ -96,6 +110,13 @@ public class ChassisPanel extends AbstractShape implements IDatasheetSupport {
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
@@ -121,49 +142,107 @@ public class ChassisPanel extends AbstractShape implements IDatasheetSupport {
}
@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;
}
@@ -171,15 +250,6 @@ public class ChassisPanel extends AbstractShape implements IDatasheetSupport {
this.edgeRadius = edgeRadius;
}
- @EditableProperty(name = "Value")
- public String getModel() {
- return value;
- }
-
- public void setModel(String model) {
- this.value = model;
- }
-
@EditableProperty
public Size getHeight() {
return height;
@@ -213,11 +283,6 @@ public class ChassisPanel extends AbstractShape implements IDatasheetSupport {
this.spacing = spacing;
}
- @Override
- public String getValueForDisplay() {
- return value == null ? "" : value;
- }
-
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
diff --git a/diylc/diylc-library/src/test/java/org/diylc/components/chassis/ChassisPanelDatasheetTest.java b/diylc/diylc-library/src/test/java/org/diylc/components/chassis/ChassisPanelDatasheetTest.java
index c3eeaa25..73852f0c 100644
--- a/diylc/diylc-library/src/test/java/org/diylc/components/chassis/ChassisPanelDatasheetTest.java
+++ b/diylc/diylc-library/src/test/java/org/diylc/components/chassis/ChassisPanelDatasheetTest.java
@@ -65,7 +65,7 @@ public class ChassisPanelDatasheetTest {
for (String[] row : datasheet) {
Assert.assertEquals(String.join(",", row), 5, row.length);
ChassisPanel enclosure = new ChassisPanel(row);
- Assert.assertEquals(row[1], enclosure.getModel());
+ 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);
@@ -81,7 +81,7 @@ public class ChassisPanelDatasheetTest {
ChassisPanel enclosure = new ChassisPanel();
ChassisPanel fromDatasheet = new ChassisPanel(row("125B"));
- Assert.assertEquals(fromDatasheet.getModel(), enclosure.getModel());
+ 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));
@@ -202,7 +202,7 @@ public class ChassisPanelDatasheetTest {
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.setModel("");
+ original.setValue("");
original.setEdgeRadius(new Size(0d, SizeUnit.mm));
original.setControlPoint(new Point2D.Double(20, 30), 1);
String xml = ProjectFileManager.xStreamSerializer.toXML(original)
diff --git a/diylc/docs/plans/chassis-enclosures.md b/diylc/docs/plans/chassis-enclosures.md
index ffc773ed..7bf77c97 100644
--- a/diylc/docs/plans/chassis-enclosures.md
+++ b/diylc/docs/plans/chassis-enclosures.md
@@ -9,7 +9,8 @@ component that draws either one panel or an exploded view of the whole box.
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 `AbstractShape` on the `CHASSIS` layer. The control points are the top panel.
+- It is a two-point `AbstractTransparentComponent` (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.
@@ -30,7 +31,7 @@ component that draws either one panel or an exploded view of the whole box.
|---|---|---|
| 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 | `Value` is backed by `AbstractShape.value` through `getModel()` with `@EditableProperty(name = "Value")`; `height` and `sides` are new fields | `value` is a `String` every shape already serializes and nothing read, and `AbstractShape.getValue()` is typed `Void`. New fields read `null` from old files: `getHeight()` null means no sides, `getSides()` defaults to `All`. |
+| D3 | `ChassisPanel` no longer extends `AbstractShape`; it is an `AbstractTransparentComponent` 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. |