mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 12:24:58 +10:00
Angle editor added
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Angle {
|
||||
|
||||
private int value;
|
||||
|
||||
private Angle(int value) {
|
||||
super();
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + value;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Angle other = (Angle) obj;
|
||||
if (value != other.value)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Integer.toString(value);
|
||||
}
|
||||
|
||||
private static Map<Integer, Angle> valueCache = new HashMap<Integer, Angle>();
|
||||
|
||||
public synchronized static Angle of(int angle) {
|
||||
valueCache.computeIfAbsent(angle, (value) -> new Angle(value));
|
||||
return valueCache.get(angle);
|
||||
}
|
||||
}
|
||||
@@ -3937,5 +3937,33 @@
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>4</major>
|
||||
<minor>28</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2022-09-25 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added '4-pin Jumbo Tube Socket' component for 211, 805 and 845 tubes</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>More convenient way of editing angle of rotation of all tube sockets</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Ability to rotate all tube sockets through the 'Transform Selection' feature or keyboard shortcut</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Tube socket pin designations are not rendered until property editor dialog is opened and closed</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
</a>
|
||||
</java.util.Arrays_-ArrayList>
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2018 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.transform;
|
||||
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import org.diylc.common.IComponentTransformer;
|
||||
import org.diylc.components.tube.TubeSocket;
|
||||
import org.diylc.core.Angle;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
public class TubeSocketTransformer implements IComponentTransformer {
|
||||
|
||||
@Override
|
||||
public boolean canRotate(IDIYComponent<?> component) {
|
||||
return TubeSocket.class.isAssignableFrom(component.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMirror(IDIYComponent<?> component) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mirroringChangesCircuit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(IDIYComponent<?> component, Point2D center, int direction) {
|
||||
AffineTransform rotate = AffineTransform.getRotateInstance(Math.PI / 2 * direction, center.getX(), center.getY());
|
||||
for (int index = 0; index < component.getControlPointCount(); index++) {
|
||||
Point2D p = new Point2D.Double();
|
||||
rotate.transform(component.getControlPoint(index), p);
|
||||
component.setControlPoint(p, index);
|
||||
}
|
||||
|
||||
TubeSocket tube = (TubeSocket) component;
|
||||
Angle angle = tube.getAngle();
|
||||
Angle newAngle = Angle.of(angle.getValue() + direction * 90);
|
||||
tube.setAngle(newAngle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mirror(IDIYComponent<?> component, Point2D center, int direction) {
|
||||
}
|
||||
}
|
||||
@@ -1,86 +1,89 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2018 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/>.
|
||||
|
||||
*/
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2018 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.tube;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.awt.StringUtils;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.common.VerticalAlignment;
|
||||
import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.awt.StringUtils;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.common.VerticalAlignment;
|
||||
import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.components.transform.TubeSocketTransformer;
|
||||
import org.diylc.core.Angle;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "Tube Socket", author = "Branislav Stojkovic", category = "Tubes",
|
||||
instanceNamePrefix = "V", description = "Various types of tube/valve sockets",
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true)
|
||||
zOrder = IDIYComponent.COMPONENT, keywordPolicy = KeywordPolicy.SHOW_VALUE, enableCache = true,
|
||||
transformer = TubeSocketTransformer.class)
|
||||
public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final Size B9A_PIN_SPACING_CHASSIS = new Size(12.5d, SizeUnit.mm);
|
||||
private static final Size B9A_PIN_SPACING_PCB = new Size(21d, SizeUnit.mm);
|
||||
private static final Size OCTAL_PIN_SPACING = new Size(17.5d, SizeUnit.mm);
|
||||
private static final Size B7G_PIN_SPACING = new Size(12d, SizeUnit.mm);
|
||||
private static final Size B7G_CUTOUT_DIAMETER = new Size(4d, SizeUnit.mm);
|
||||
private static final Size B9A_CUTOUT_DIAMETER = new Size(5.5d, SizeUnit.mm);
|
||||
private static final Size B12C_HOLE_SIZE = new Size(10d, SizeUnit.mm);
|
||||
private static final Size B12C_CUTOUT_DIAMETER = new Size(5.5d, SizeUnit.mm);
|
||||
private static final Size B12C_PIN_SPACING_PCB = new Size(25d, SizeUnit.mm);
|
||||
private static final Size B12C_PIN_SPACING_CHASSIS = new Size(22d, SizeUnit.mm);
|
||||
|
||||
private static final Size OCTAL_DIAMETER = new Size(25d, SizeUnit.mm);
|
||||
private static final Size B9A_DIAMETER = new Size(3 / 4d, SizeUnit.in);
|
||||
private static final Size B7G_DIAMETER = new Size(17d, SizeUnit.mm);
|
||||
private static final Size B12C_DIAMETER = new Size(30d, SizeUnit.mm);
|
||||
|
||||
private static final Size B9A_PIN_SPACING_CHASSIS = new Size(12.5d, SizeUnit.mm);
|
||||
private static final Size B9A_PIN_SPACING_PCB = new Size(21d, SizeUnit.mm);
|
||||
private static final Size OCTAL_PIN_SPACING = new Size(17.5d, SizeUnit.mm);
|
||||
private static final Size B7G_PIN_SPACING = new Size(12d, SizeUnit.mm);
|
||||
private static final Size B7G_CUTOUT_DIAMETER = new Size(4d, SizeUnit.mm);
|
||||
private static final Size B9A_CUTOUT_DIAMETER = new Size(5.5d, SizeUnit.mm);
|
||||
private static final Size B12C_HOLE_SIZE = new Size(10d, SizeUnit.mm);
|
||||
private static final Size B12C_CUTOUT_DIAMETER = new Size(5.5d, SizeUnit.mm);
|
||||
private static final Size B12C_PIN_SPACING_PCB = new Size(25d, SizeUnit.mm);
|
||||
private static final Size B12C_PIN_SPACING_CHASSIS = new Size(22d, SizeUnit.mm);
|
||||
|
||||
private static final Size OCTAL_DIAMETER = new Size(25d, SizeUnit.mm);
|
||||
private static final Size B9A_DIAMETER = new Size(3 / 4d, SizeUnit.in);
|
||||
private static final Size B7G_DIAMETER = new Size(17d, SizeUnit.mm);
|
||||
private static final Size B12C_DIAMETER = new Size(30d, SizeUnit.mm);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Color BODY_COLOR = Color.decode("#F7F7EF");
|
||||
private static Color BODY_COLOR = Color.decode("#F7F7EF");
|
||||
private static Color LABEL_COLOR = BODY_COLOR.darker();
|
||||
public static Color PIN_COLOR = Color.decode("#00B2EE");
|
||||
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
|
||||
public static Size PIN_DIAMETER = new Size(1d, SizeUnit.mm);
|
||||
private static Size PIN_WIDTH = new Size(0.08d, SizeUnit.in);
|
||||
public static Size PIN_DIAMETER = new Size(1d, SizeUnit.mm);
|
||||
private static Size PIN_WIDTH = new Size(0.08d, SizeUnit.in);
|
||||
private static Size PIN_THICKNESS = new Size(0.02d, SizeUnit.in);
|
||||
public static Size HOLE_SIZE = new Size(5d, SizeUnit.mm);
|
||||
public static Size OCTAL_TICK_SIZE = new Size(2d, SizeUnit.mm);
|
||||
@@ -91,9 +94,9 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
private Orientation orientation;
|
||||
// private Mount mount = Mount.CHASSIS;
|
||||
private int angle;
|
||||
private Color color = BODY_COLOR;
|
||||
private String electrodeLabels = null;
|
||||
private Mount mount = Mount.CHASSIS;
|
||||
private Color color = BODY_COLOR;
|
||||
private String electrodeLabels = null;
|
||||
private Mount mount = Mount.CHASSIS;
|
||||
private Color labelColor = LABEL_COLOR;
|
||||
|
||||
private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)};
|
||||
@@ -119,7 +122,7 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
|
||||
@EditableProperty
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
public int getAngle() {
|
||||
public Angle getAngle() {
|
||||
if (orientation != null) {
|
||||
switch (orientation) {
|
||||
case _90:
|
||||
@@ -134,11 +137,11 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
}
|
||||
orientation = null;
|
||||
}
|
||||
return angle;
|
||||
return Angle.of(angle);
|
||||
}
|
||||
|
||||
public void setAngle(int angle) {
|
||||
this.angle = angle;
|
||||
public void setAngle(Angle angle) {
|
||||
this.angle = angle.getValue();
|
||||
updateControlPoints();
|
||||
// Reset body shape
|
||||
body = null;
|
||||
@@ -185,11 +188,11 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
pinCount = 9;
|
||||
pinSpacing = getClosestOdd(getMount() == Mount.PCB ? B9A_PIN_SPACING_PCB.convertToPixels() : B9A_PIN_SPACING_CHASSIS.convertToPixels());
|
||||
hasEmptySpace = true;
|
||||
break;
|
||||
case B12C:
|
||||
pinCount = 12;
|
||||
pinSpacing = getClosestOdd(getMount() == Mount.PCB ? B12C_PIN_SPACING_PCB.convertToPixels() : B12C_PIN_SPACING_CHASSIS.convertToPixels());
|
||||
hasEmptySpace = true;
|
||||
break;
|
||||
case B12C:
|
||||
pinCount = 12;
|
||||
pinSpacing = getClosestOdd(getMount() == Mount.PCB ? B12C_PIN_SPACING_PCB.convertToPixels() : B12C_PIN_SPACING_CHASSIS.convertToPixels());
|
||||
hasEmptySpace = true;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected base: " + base);
|
||||
@@ -198,7 +201,7 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
double initialAngleOffset = hasEmptySpace ? angleIncrement : (angleIncrement / 2);
|
||||
|
||||
controlPoints = new Point2D[pinCount + 1];
|
||||
double theta = initialAngleOffset + Math.toRadians(getAngle());
|
||||
double theta = initialAngleOffset + Math.toRadians(getAngle().getValue());
|
||||
controlPoints[0] = firstPoint;
|
||||
for (int i = 0; i < pinCount; i++) {
|
||||
controlPoints[i + 1] =
|
||||
@@ -220,13 +223,13 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
break;
|
||||
case OCTAL:
|
||||
bodyDiameter = getClosestOdd(OCTAL_DIAMETER.convertToPixels());
|
||||
break;
|
||||
case B12C:
|
||||
bodyDiameter = getClosestOdd(B12C_DIAMETER.convertToPixels());
|
||||
break;
|
||||
case B12C:
|
||||
bodyDiameter = getClosestOdd(B12C_DIAMETER.convertToPixels());
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected base: " + base);
|
||||
}
|
||||
}
|
||||
|
||||
body =
|
||||
new Ellipse2D.Double(controlPoints[0].getX() - bodyDiameter / 2, controlPoints[0].getY() - bodyDiameter / 2,
|
||||
@@ -234,28 +237,28 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
Area bodyArea = new Area(body);
|
||||
int holeSize = getClosestOdd(base == Base.B12C ? B12C_HOLE_SIZE.convertToPixels() : HOLE_SIZE.convertToPixels());
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - holeSize / 2, controlPoints[0].getY() - holeSize
|
||||
/ 2, holeSize, holeSize)));
|
||||
/ 2, holeSize, holeSize)));
|
||||
|
||||
if (base == Base.OCTAL) {
|
||||
int tickSize = getClosestOdd(OCTAL_TICK_SIZE.convertToPixels());
|
||||
double theta = Math.toRadians(getAngle());
|
||||
double theta = Math.toRadians(getAngle().getValue());
|
||||
int centerX = (int) (controlPoints[0].getX() + Math.cos(theta) * holeSize / 2);
|
||||
int centerY = (int) (controlPoints[0].getY() + Math.sin(theta) * holeSize / 2);
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(centerX - tickSize / 2, centerY - tickSize / 2, tickSize,
|
||||
tickSize)));
|
||||
} else if (base == Base.B9A && getMount() == Mount.CHASSIS) {
|
||||
double cutoutDiameter = getClosestOdd(B9A_CUTOUT_DIAMETER.convertToPixels());
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() - bodyDiameter / 2 - cutoutDiameter * 3 / 4, cutoutDiameter, cutoutDiameter)));
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() + bodyDiameter / 2 - cutoutDiameter / 4, cutoutDiameter, cutoutDiameter)));
|
||||
} else if (base == Base.B7G && getMount() == Mount.CHASSIS) {
|
||||
double cutoutDiameter = getClosestOdd(B7G_CUTOUT_DIAMETER.convertToPixels());
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() - bodyDiameter / 2 - cutoutDiameter * 3 / 4, cutoutDiameter, cutoutDiameter)));
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() + bodyDiameter / 2 - cutoutDiameter / 4, cutoutDiameter, cutoutDiameter)));
|
||||
} else if (base == Base.B12C && getMount() == Mount.CHASSIS) {
|
||||
double cutoutDiameter = getClosestOdd(B12C_CUTOUT_DIAMETER.convertToPixels());
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() - bodyDiameter / 2 - cutoutDiameter * 3 / 4, cutoutDiameter, cutoutDiameter)));
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() + bodyDiameter / 2 - cutoutDiameter / 4, cutoutDiameter, cutoutDiameter)));
|
||||
}
|
||||
} else if (base == Base.B9A && getMount() == Mount.CHASSIS) {
|
||||
double cutoutDiameter = getClosestOdd(B9A_CUTOUT_DIAMETER.convertToPixels());
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() - bodyDiameter / 2 - cutoutDiameter * 3 / 4, cutoutDiameter, cutoutDiameter)));
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() + bodyDiameter / 2 - cutoutDiameter / 4, cutoutDiameter, cutoutDiameter)));
|
||||
} else if (base == Base.B7G && getMount() == Mount.CHASSIS) {
|
||||
double cutoutDiameter = getClosestOdd(B7G_CUTOUT_DIAMETER.convertToPixels());
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() - bodyDiameter / 2 - cutoutDiameter * 3 / 4, cutoutDiameter, cutoutDiameter)));
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() + bodyDiameter / 2 - cutoutDiameter / 4, cutoutDiameter, cutoutDiameter)));
|
||||
} else if (base == Base.B12C && getMount() == Mount.CHASSIS) {
|
||||
double cutoutDiameter = getClosestOdd(B12C_CUTOUT_DIAMETER.convertToPixels());
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() - bodyDiameter / 2 - cutoutDiameter * 3 / 4, cutoutDiameter, cutoutDiameter)));
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].getX() - cutoutDiameter / 2, controlPoints[0].getY() + bodyDiameter / 2 - cutoutDiameter / 4, cutoutDiameter, cutoutDiameter)));
|
||||
}
|
||||
|
||||
body = bodyArea;
|
||||
}
|
||||
@@ -264,7 +267,7 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
IDrawingObserver drawingObserver) {
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
|
||||
@@ -292,48 +295,48 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
: getColor().darker();
|
||||
}
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body);
|
||||
|
||||
drawingObserver.stopTracking();
|
||||
g2d.draw(body);
|
||||
|
||||
drawingObserver.stopTracking();
|
||||
|
||||
// Draw pins
|
||||
if (!outlineMode) {
|
||||
for (int i = 1; i < controlPoints.length; i++) {
|
||||
Shape pinShape;
|
||||
if (getMount() == Mount.PCB) {
|
||||
int pinSize = getClosestOdd(PIN_DIAMETER.convertToPixels());
|
||||
pinShape = new Ellipse2D.Double(controlPoints[i].getX() - pinSize / 2, controlPoints[i].getY() - pinSize / 2, pinSize, pinSize);
|
||||
} else {
|
||||
int pinWidth = getClosestOdd(PIN_WIDTH.convertToPixels());
|
||||
int pinThickness = getClosestOdd(PIN_THICKNESS.convertToPixels());
|
||||
pinShape = new Rectangle2D.Double(controlPoints[i].getX() - pinWidth / 2, controlPoints[i].getY() - pinThickness / 2, pinWidth, pinThickness);
|
||||
double theta = Math.atan2(controlPoints[i].getY() - controlPoints[0].getY(), controlPoints[i].getX() - controlPoints[0].getX()) + Math.PI / 2;
|
||||
Area rotatedPin = new Area(pinShape);
|
||||
rotatedPin.transform(AffineTransform.getRotateInstance(theta, controlPoints[i].getX(), controlPoints[i].getY()));
|
||||
pinShape = rotatedPin;
|
||||
for (int i = 1; i < controlPoints.length; i++) {
|
||||
Shape pinShape;
|
||||
if (getMount() == Mount.PCB) {
|
||||
int pinSize = getClosestOdd(PIN_DIAMETER.convertToPixels());
|
||||
pinShape = new Ellipse2D.Double(controlPoints[i].getX() - pinSize / 2, controlPoints[i].getY() - pinSize / 2, pinSize, pinSize);
|
||||
} else {
|
||||
int pinWidth = getClosestOdd(PIN_WIDTH.convertToPixels());
|
||||
int pinThickness = getClosestOdd(PIN_THICKNESS.convertToPixels());
|
||||
pinShape = new Rectangle2D.Double(controlPoints[i].getX() - pinWidth / 2, controlPoints[i].getY() - pinThickness / 2, pinWidth, pinThickness);
|
||||
double theta = Math.atan2(controlPoints[i].getY() - controlPoints[0].getY(), controlPoints[i].getX() - controlPoints[0].getX()) + Math.PI / 2;
|
||||
Area rotatedPin = new Area(pinShape);
|
||||
rotatedPin.transform(AffineTransform.getRotateInstance(theta, controlPoints[i].getX(), controlPoints[i].getY()));
|
||||
pinShape = rotatedPin;
|
||||
}
|
||||
g2d.setColor(PIN_COLOR);
|
||||
g2d.fill(pinShape);
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.fill(pinShape);
|
||||
}
|
||||
}
|
||||
|
||||
// draw electrode labels
|
||||
if (electrodeLabels != null) {
|
||||
g2d.setColor(getLabelColor());
|
||||
g2d.setFont(project.getFont().deriveFont((float) (project.getFont().getSize2D() * 0.8)));
|
||||
String[] labels = electrodeLabels.split(",");
|
||||
double electrodeLabelOffset = project.getFont().getSize2D() * (getBase() == Base.B9A && getMount() == Mount.PCB ? 1.5 : 1);
|
||||
for (int i = 0; i < labels.length; i++) {
|
||||
if (i < controlPoints.length - 1) {
|
||||
String label = labels[i];
|
||||
double theta = Math.atan2(controlPoints[i + 1].getY() - controlPoints[0].getY(), controlPoints[i + 1].getX() - controlPoints[0].getX());
|
||||
double x = controlPoints[i + 1].getX() - Math.cos(theta) * electrodeLabelOffset;
|
||||
double y = controlPoints[i + 1].getY() - Math.sin(theta) * electrodeLabelOffset;
|
||||
StringUtils.drawCenteredText(g2d, label, (int)x, (int)y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw electrode labels
|
||||
if (getElectrodeLabels() != null) {
|
||||
g2d.setColor(getLabelColor());
|
||||
g2d.setFont(project.getFont().deriveFont((float) (project.getFont().getSize2D() * 0.8)));
|
||||
String[] labels = getElectrodeLabels().split(",");
|
||||
double electrodeLabelOffset = project.getFont().getSize2D() * (getBase() == Base.B9A && getMount() == Mount.PCB ? 1.5 : 1);
|
||||
for (int i = 0; i < labels.length; i++) {
|
||||
if (i < controlPoints.length - 1) {
|
||||
String label = labels[i];
|
||||
double theta = Math.atan2(controlPoints[i + 1].getY() - controlPoints[0].getY(), controlPoints[i + 1].getX() - controlPoints[0].getX());
|
||||
double x = controlPoints[i + 1].getX() - Math.cos(theta) * electrodeLabelOffset;
|
||||
double y = controlPoints[i + 1].getY() - Math.sin(theta) * electrodeLabelOffset;
|
||||
StringUtils.drawCenteredText(g2d, label, (int)x, (int)y, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +377,7 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
@EditableProperty(name = "Type")
|
||||
@EditableProperty(name = "Designation")
|
||||
public String getValue() {
|
||||
return type;
|
||||
}
|
||||
@@ -391,58 +394,64 @@ public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point2D point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
controlPoints[index].setLocation(point);
|
||||
|
||||
body = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPointMoveFreely(int pointIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Electrode Labels")
|
||||
public String getElectrodeLabels() {
|
||||
if (electrodeLabels == null)
|
||||
electrodeLabels = "1,2,3,4,5,6,7,8,9,10,11,12";
|
||||
return electrodeLabels;
|
||||
}
|
||||
|
||||
public void setElectrodeLabels(String electrodeLabels) {
|
||||
this.electrodeLabels = electrodeLabels;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Label")
|
||||
public Color getLabelColor() {
|
||||
if (labelColor == null)
|
||||
labelColor = LABEL_COLOR;
|
||||
return labelColor;
|
||||
}
|
||||
|
||||
public void setLabelColor(Color labelColor) {
|
||||
this.labelColor = labelColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Mount")
|
||||
public Mount getMount() {
|
||||
if (mount == null)
|
||||
mount = Mount.CHASSIS;
|
||||
return mount;
|
||||
}
|
||||
|
||||
public void setMount(Mount mount) {
|
||||
this.mount = mount;
|
||||
|
||||
updateControlPoints();
|
||||
// Reset body shape
|
||||
body = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
Rectangle2D rect = getBody().getBounds2D();
|
||||
int margin = 40; // to catch the pins that are outside the body, if needed
|
||||
return new Rectangle2D.Double(rect.getX() - margin, rect.getY() - margin, rect.getWidth() + 2 * margin, rect.getHeight() + 2 * margin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPointMoveFreely(int pointIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Electrode Labels")
|
||||
public String getElectrodeLabels() {
|
||||
if (electrodeLabels == null)
|
||||
electrodeLabels = "1,2,3,4,5,6,7,8,9,10,11,12";
|
||||
return electrodeLabels;
|
||||
}
|
||||
|
||||
public void setElectrodeLabels(String electrodeLabels) {
|
||||
this.electrodeLabels = electrodeLabels;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Label")
|
||||
public Color getLabelColor() {
|
||||
if (labelColor == null)
|
||||
labelColor = LABEL_COLOR;
|
||||
return labelColor;
|
||||
}
|
||||
|
||||
public void setLabelColor(Color labelColor) {
|
||||
this.labelColor = labelColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Mount")
|
||||
public Mount getMount() {
|
||||
if (mount == null)
|
||||
mount = Mount.CHASSIS;
|
||||
return mount;
|
||||
}
|
||||
|
||||
public void setMount(Mount mount) {
|
||||
this.mount = mount;
|
||||
|
||||
updateControlPoints();
|
||||
// Reset body shape
|
||||
body = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
String[] labels = getElectrodeLabels().split(",");
|
||||
return index > 0 && index <= labels.length ? labels[index - 1] : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
Rectangle2D rect = getBody().getBounds2D();
|
||||
int margin = 40; // to catch the pins that are outside the body, if needed
|
||||
return new Rectangle2D.Double(rect.getX() - margin, rect.getY() - margin, rect.getWidth() + 2 * margin, rect.getHeight() + 2 * margin);
|
||||
}
|
||||
|
||||
public static enum Base {
|
||||
|
||||
@@ -69,6 +69,7 @@ import org.diylc.components.tube.PentodeSymbol;
|
||||
import org.diylc.components.tube.TriodeSymbol;
|
||||
import org.diylc.components.tube.TubeSocket;
|
||||
import org.diylc.components.tube.TubeSocket.Base;
|
||||
import org.diylc.core.Angle;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.measures.Capacitance;
|
||||
import org.diylc.core.measures.CapacitanceUnit;
|
||||
@@ -926,7 +927,7 @@ public class V2FileParser implements IOldFileParser {
|
||||
ts.setAlpha((byte) transparency);
|
||||
if (value_s != "")
|
||||
ts.setValue(value_s);
|
||||
ts.setAngle((int) angle);
|
||||
ts.setAngle(Angle.of((int) angle));
|
||||
ts.setControlPoint(tacke.get(0), 0);
|
||||
ts.setBase(Base.B9A);
|
||||
project.getComponents().add(ts);
|
||||
@@ -962,7 +963,7 @@ public class V2FileParser implements IOldFileParser {
|
||||
ts.setAlpha((byte) transparency);
|
||||
if (value_s != "")
|
||||
ts.setValue(value_s);
|
||||
ts.setAngle((int) angle);
|
||||
ts.setAngle(Angle.of((int) angle));
|
||||
ts.setControlPoint(tacke.get(0), 0);
|
||||
ts.setBase(Base.OCTAL);
|
||||
project.getComponents().add(ts);
|
||||
@@ -975,7 +976,7 @@ public class V2FileParser implements IOldFileParser {
|
||||
ts.setAlpha((byte) transparency);
|
||||
if (value_s != "")
|
||||
ts.setValue(value_s);
|
||||
ts.setAngle((int) angle);
|
||||
ts.setAngle(Angle.of((int)angle));
|
||||
|
||||
ts.setControlPoint(tacke.get(0), 0);
|
||||
ts.setBase(Base.B7G);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
*
|
||||
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 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.swing.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JList;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.Angle;
|
||||
import org.diylc.lang.LangUtil;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
public class AngleEditor extends JComboBox<Integer> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg = getBackground();
|
||||
|
||||
private final PropertyWrapper property;
|
||||
|
||||
public AngleEditor(final PropertyWrapper property) {
|
||||
this.property = property;
|
||||
if (property.isReadOnly())
|
||||
setEnabled(false);
|
||||
|
||||
setEditable(true);
|
||||
|
||||
setModel(new DefaultComboBoxModel<Integer>(new Integer[] {30, 45, 90, 135, 180, 270}));
|
||||
setRenderer(new DefaultListCellRenderer() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
// TODO Auto-generated method stub
|
||||
return super.getListCellRendererComponent(list,
|
||||
value == null ? null : LangUtil.translate(value.toString()), index, isSelected,
|
||||
cellHasFocus);
|
||||
}
|
||||
|
||||
});
|
||||
setSelectedItem(((Angle) (property.getValue())).getValue());
|
||||
addItemListener(new ItemListener() {
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
property.setChanged(true);
|
||||
setBackground(oldBg);
|
||||
AngleEditor.this.property.setValue(Angle.of((Integer) e.getItem()));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!property.isUnique()) {
|
||||
setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import javax.swing.JLabel;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.components.misc.LoadlineEntity;
|
||||
import org.diylc.core.Angle;
|
||||
import org.diylc.core.annotations.ByteArrayProperty;
|
||||
import org.diylc.core.annotations.DynamicList;
|
||||
import org.diylc.core.annotations.MultiLineText;
|
||||
@@ -112,6 +113,10 @@ public class FieldEditorFactory {
|
||||
if (LoadlineEntity.class.isAssignableFrom(property.getType())) {
|
||||
LoadlineEditor editor = new LoadlineEditor(property);
|
||||
return editor;
|
||||
}
|
||||
if (Angle.class.isAssignableFrom(property.getType())) {
|
||||
AngleEditor editor = new AngleEditor(property);
|
||||
return editor;
|
||||
}
|
||||
LOG.error("Unrecognized parameter type: " + property.getType().getName());
|
||||
return new JLabel("Unrecognized");
|
||||
|
||||
Reference in New Issue
Block a user