mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 01:02:08 +10:00
Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d5bd4a949 | |||
| a23342f682 | |||
| 93a4978e68 | |||
| 0d845677c4 | |||
| ab10103e41 | |||
| 0d17046170 | |||
| 880e618e30 | |||
| 176abc2428 | |||
| 061bc520c6 | |||
| 9c9d6ecd70 | |||
| d9f5e2e42b | |||
| 0c1659cde0 | |||
| 53feb60b63 | |||
| 8c2700b92c | |||
| 298d575696 | |||
| 931138083f | |||
| f2a814e41c | |||
| d07965a3c0 | |||
| 9e1f5c3ac8 | |||
| 569a50e97a | |||
| 80e7e3a487 | |||
| 5d73617af3 | |||
| 8169e3a6ba | |||
| a7b48f4f52 | |||
| 89bf22bcf8 | |||
| ae99ce2702 | |||
| 61937d6d42 | |||
| e618a1e1ad | |||
| 513a229e64 | |||
| f834aa6d0b | |||
| 35d8b13d41 | |||
| 989e0a03e4 | |||
| c6cb77f4ef | |||
| af1a11e848 | |||
| 4bcff4a574 | |||
| 36f65423e0 | |||
| ef11c931a7 | |||
| 732a9954b7 | |||
| 2b5b904d8d | |||
| 6ca16d07e6 | |||
| 4f113f032d | |||
| e572412f1e | |||
| dd9e9f054c |
Binary file not shown.
@@ -3,6 +3,7 @@ package org.diylc.common;
|
||||
import java.awt.Point;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.core.ExpansionMode;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
public interface ISelectionProcessor {
|
||||
@@ -32,6 +33,14 @@ public interface ISelectionProcessor {
|
||||
*/
|
||||
List<IDIYComponent<?>> findComponentsAt(Point point);
|
||||
|
||||
/**
|
||||
* Expands the current selection to include surrounding components.
|
||||
* Options are controlled with <code>expansionMode</code> flag.
|
||||
*
|
||||
* @param expansionMode
|
||||
*/
|
||||
void expandSelection(ExpansionMode expansionMode);
|
||||
|
||||
/**
|
||||
* Selects all components in the project.
|
||||
*/
|
||||
|
||||
@@ -32,6 +32,7 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
|
||||
public static Color LABEL_COLOR = Color.black;
|
||||
public static Color LABEL_COLOR_SELECTED = Color.red;
|
||||
public static Font LABEL_FONT = new Font("Tahoma", Font.PLAIN, 14);
|
||||
public static Color METAL_COLOR = Color.decode("#236B8E");
|
||||
|
||||
@EditableProperty(defaultable = false)
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.diylc.core;
|
||||
|
||||
public enum ExpansionMode {
|
||||
|
||||
ALL,
|
||||
SAME_TYPE,
|
||||
IMMEDIATE,
|
||||
}
|
||||
@@ -32,36 +32,56 @@ public class Resistance extends AbstractMeasure<ResistanceUnit> {
|
||||
|
||||
public Color[] getColorCode(ResistorColorCode resistorColorCode) {
|
||||
Color[] bands;
|
||||
double base = getValue() * getUnit().getFactor();
|
||||
int multiplier = 0;
|
||||
while (base > (resistorColorCode == ResistorColorCode._4_BAND ? 99 : 999)) {
|
||||
multiplier += 1;
|
||||
base /= 10;
|
||||
}
|
||||
while (base < (resistorColorCode == ResistorColorCode._4_BAND ? 10 : 100)) {
|
||||
multiplier -= 1;
|
||||
base *= 10;
|
||||
}
|
||||
if (multiplier > 6 || multiplier < -2) {
|
||||
// Out of range.
|
||||
return new Color[] {};
|
||||
}
|
||||
switch (resistorColorCode) {
|
||||
case _4_BAND:
|
||||
bands = new Color[3];
|
||||
bands[0] = COLOR_DIGITS[(int) (base / 10)];
|
||||
bands[1] = COLOR_DIGITS[(int) (base % 10)];
|
||||
bands[2] = COLOR_MULTIPLIER[multiplier + 2];
|
||||
break;
|
||||
case _5_BAND:
|
||||
bands = new Color[4];
|
||||
bands[0] = COLOR_DIGITS[(int) (base / 100)];
|
||||
bands[1] = COLOR_DIGITS[(int) (base / 10 % 10)];
|
||||
bands[2] = COLOR_DIGITS[(int) (base % 10)];
|
||||
bands[3] = COLOR_MULTIPLIER[multiplier + 2];
|
||||
break;
|
||||
default:
|
||||
bands = new Color[] {};
|
||||
if (getValue() == 0) {
|
||||
switch (resistorColorCode) {
|
||||
case _4_BAND:
|
||||
bands = new Color[3];
|
||||
bands[0] = COLOR_DIGITS[0];
|
||||
bands[1] = COLOR_DIGITS[0];
|
||||
bands[2] = COLOR_MULTIPLIER[2];
|
||||
break;
|
||||
case _5_BAND:
|
||||
bands = new Color[4];
|
||||
bands[0] = COLOR_DIGITS[0];
|
||||
bands[1] = COLOR_DIGITS[0];
|
||||
bands[2] = COLOR_DIGITS[0];
|
||||
bands[3] = COLOR_MULTIPLIER[2];
|
||||
break;
|
||||
default:
|
||||
bands = new Color[] {};
|
||||
}
|
||||
} else {
|
||||
double base = getValue() * getUnit().getFactor();
|
||||
int multiplier = 0;
|
||||
while (base > (resistorColorCode == ResistorColorCode._4_BAND ? 99 : 999)) {
|
||||
multiplier += 1;
|
||||
base /= 10;
|
||||
}
|
||||
while (base < (resistorColorCode == ResistorColorCode._4_BAND ? 10 : 100)) {
|
||||
multiplier -= 1;
|
||||
base *= 10;
|
||||
}
|
||||
if (multiplier > 6 || multiplier < -2) {
|
||||
// Out of range.
|
||||
return new Color[] {};
|
||||
}
|
||||
switch (resistorColorCode) {
|
||||
case _4_BAND:
|
||||
bands = new Color[3];
|
||||
bands[0] = COLOR_DIGITS[(int) (base / 10)];
|
||||
bands[1] = COLOR_DIGITS[(int) (base % 10)];
|
||||
bands[2] = COLOR_MULTIPLIER[multiplier + 2];
|
||||
break;
|
||||
case _5_BAND:
|
||||
bands = new Color[4];
|
||||
bands[0] = COLOR_DIGITS[(int) (base / 100)];
|
||||
bands[1] = COLOR_DIGITS[(int) (base / 10 % 10)];
|
||||
bands[2] = COLOR_DIGITS[(int) (base % 10)];
|
||||
bands[3] = COLOR_MULTIPLIER[multiplier + 2];
|
||||
break;
|
||||
default:
|
||||
bands = new Color[] {};
|
||||
}
|
||||
}
|
||||
return bands;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.components.connectivity.SolderPad;
|
||||
import org.diylc.core.ExpansionMode;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IView;
|
||||
import org.diylc.core.Project;
|
||||
@@ -55,7 +56,7 @@ public class Presenter implements IPlugInPort {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(Presenter.class);
|
||||
|
||||
public static final VersionNumber CURRENT_VERSION = new VersionNumber(3, 2, 0);
|
||||
public static final VersionNumber CURRENT_VERSION = new VersionNumber(3, 6, 0);
|
||||
public static final String DEFAULTS_KEY_PREFIX = "default.";
|
||||
|
||||
public static final List<IDIYComponent<?>> EMPTY_SELECTION = Collections.emptyList();
|
||||
@@ -1078,6 +1079,7 @@ public class Presenter implements IPlugInPort {
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
LOG.info("refresh()");
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
}
|
||||
|
||||
@@ -1093,6 +1095,7 @@ public class Presenter implements IPlugInPort {
|
||||
|
||||
@Override
|
||||
public void renumberSelectedComponents(final boolean xAxisFirst) {
|
||||
LOG.info("renumberSelectedComponents(" + xAxisFirst + ")");
|
||||
if (getSelectedComponents().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -1183,6 +1186,67 @@ public class Presenter implements IPlugInPort {
|
||||
controlPointMap.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expandSelection(ExpansionMode expansionMode) {
|
||||
List<IDIYComponent<?>> newSelection = new ArrayList<IDIYComponent<?>>(
|
||||
this.selectedComponents);
|
||||
// Find control points of all selected components and all types
|
||||
Set<String> selectedNamePrefixes = new HashSet<String>();
|
||||
if (expansionMode == ExpansionMode.SAME_TYPE) {
|
||||
for (IDIYComponent<?> component : getSelectedComponents()) {
|
||||
selectedNamePrefixes.add(ComponentProcessor.getInstance().extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass()).getNamePrefix());
|
||||
}
|
||||
}
|
||||
// Now try to find components that intersect with at least one component
|
||||
// in the pool.
|
||||
for (IDIYComponent<?> component : getCurrentProject().getComponents()) {
|
||||
// Skip already selected components or ones that cannot be stuck to
|
||||
// other components.
|
||||
Area area = drawingManager.getComponentArea(component);
|
||||
if (newSelection.contains(component) || !component.isControlPointSticky(0)
|
||||
|| area == null)
|
||||
continue;
|
||||
boolean matches = false;
|
||||
for (IDIYComponent<?> selectedComponent : this.selectedComponents) {
|
||||
Area selectedArea = drawingManager.getComponentArea(selectedComponent);
|
||||
if (selectedArea == null)
|
||||
continue;
|
||||
Area intersection = new Area(area);
|
||||
intersection.intersect(selectedArea);
|
||||
if (!intersection.isEmpty()) {
|
||||
matches = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches) {
|
||||
switch (expansionMode) {
|
||||
case ALL:
|
||||
case IMMEDIATE:
|
||||
newSelection.add(component);
|
||||
break;
|
||||
case SAME_TYPE:
|
||||
if (selectedNamePrefixes.contains(ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) component.getClass())
|
||||
.getNamePrefix())) {
|
||||
newSelection.add(component);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int oldSize = this.getSelectedComponents().size();
|
||||
updateSelection(newSelection);
|
||||
// Go deeper if possible.
|
||||
if (newSelection.size() > oldSize && expansionMode != ExpansionMode.IMMEDIATE) {
|
||||
expandSelection(expansionMode);
|
||||
}
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the groups that contain at least one of the specified
|
||||
* components.
|
||||
|
||||
@@ -6,6 +6,11 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -21,7 +26,6 @@ import org.diylc.appframework.simplemq.MessageDispatcher;
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.components.AbstractComponent;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.components.boards.AbstractBoard;
|
||||
@@ -53,6 +57,7 @@ import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
@@ -86,7 +91,7 @@ public class ProjectFileManager {
|
||||
|
||||
public ProjectFileManager(MessageDispatcher<EventType> messageDispatcher) {
|
||||
super();
|
||||
this.xStream = new XStream(new DomDriver());
|
||||
this.xStream = new XStream(new DomDriver("UTF-8"));
|
||||
xStream.autodetectAnnotations(true);
|
||||
xStream.registerConverter(new PointConverter());
|
||||
this.xStreamOld = new XStream(new DomDriver());
|
||||
@@ -107,7 +112,9 @@ public class ProjectFileManager {
|
||||
}
|
||||
FileOutputStream fos;
|
||||
fos = new FileOutputStream(fileName);
|
||||
xStream.toXML(project, fos);
|
||||
Writer writer = new OutputStreamWriter(fos, "UTF-8");
|
||||
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
|
||||
xStream.toXML(project, writer);
|
||||
fos.close();
|
||||
if (!isBackup) {
|
||||
this.currentFileName = fileName;
|
||||
@@ -123,7 +130,7 @@ public class ProjectFileManager {
|
||||
File file = new File(fileName);
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
Document doc = db.parse(file);
|
||||
Document doc = db.parse(new InputSource(new InputStreamReader(new FileInputStream(file))));
|
||||
doc.getDocumentElement().normalize();
|
||||
if (doc.getDocumentElement().getNodeName().equalsIgnoreCase(Project.class.getName())) {
|
||||
project = parseV3File(fileName);
|
||||
@@ -536,7 +543,8 @@ public class ProjectFileManager {
|
||||
Project project;
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
try {
|
||||
project = (Project) xStream.fromXML(fis);
|
||||
Reader reader = new InputStreamReader(fis, "UTF-8");
|
||||
project = (Project) xStream.fromXML(reader);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Could not open with the new xStream, trying the old one");
|
||||
fis.close();
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,105 @@
|
||||
package org.diylc.components.connectivity;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
|
||||
@ComponentDescriptor(name = "Line", author = "Branislav Stojkovic", category = "Connectivity", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "LN", description = "", zOrder = IDIYComponent.COMPONENT)
|
||||
public class Line extends AbstractLeadedComponent<Void> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color COLOR = Color.black;
|
||||
|
||||
private Color color = COLOR;
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.setColor(COLOR);
|
||||
g2d.drawLine(1, height - 2, width - 2, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.setColor(color);
|
||||
g2d.drawLine(getControlPoint(0).x, getControlPoint(0).y, getControlPoint(1).x,
|
||||
getControlPoint(1).y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getLeadColor(ComponentState componentState) {
|
||||
return componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : color;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public Color getBodyColor() {
|
||||
return super.getBodyColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBorderColor() {
|
||||
return super.getBorderColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte getAlpha() {
|
||||
return super.getAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Size getLength() {
|
||||
return super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Size getWidth() {
|
||||
return super.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Void value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shape getBodyShape() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Size getDefaultWidth() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Size getDefaultLength() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
package org.diylc.components.electromechanical;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
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.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "Cliff 1/4\" Jack", category = "Electromechanical", author = "Branislav Stojkovic", description = "Cliff-style closed panel mount 1/4\" phono jack", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J")
|
||||
public class CliffJack1_4 extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Size SPACING = new Size(0.3d, SizeUnit.in);
|
||||
private static Size PIN_WIDTH = new Size(0.1d, SizeUnit.in);
|
||||
private static Size PIN_THICKNESS = new Size(0.02d, SizeUnit.in);
|
||||
private static Color BODY_COLOR = Color.decode("#666666");
|
||||
private static Color NUT_COLOR = Color.decode("#999999");
|
||||
private static Color BORDER_COLOR = Color.black;
|
||||
private static Color LABEL_COLOR = Color.white;
|
||||
private static Size BODY_WIDTH = new Size(3/4d, SizeUnit.in);
|
||||
private static Size BODY_LENGTH = new Size(0.9d, SizeUnit.in);
|
||||
private static Size TAIL_LENGTH = new Size(0.1d, SizeUnit.in);
|
||||
|
||||
private Point[] controlPoints = new Point[] { new Point(0, 0) };
|
||||
private JackType type = JackType.MONO;
|
||||
private Orientation orientation = Orientation.DEFAULT;
|
||||
transient private Shape[] body;
|
||||
private String value = "";
|
||||
|
||||
public CliffJack1_4() {
|
||||
super();
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
private void updateControlPoints() {
|
||||
// invalidate body shape
|
||||
body = null;
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
int spacing = (int) SPACING.convertToPixels();
|
||||
controlPoints = new Point[type == JackType.STEREO ? 6 : 4];
|
||||
|
||||
controlPoints[0] = new Point(x, y);
|
||||
controlPoints[1] = new Point(x, y + 2 * spacing);
|
||||
controlPoints[2] = new Point(x + 2 * spacing, y);
|
||||
controlPoints[3] = new Point(x + 2 * spacing, y + 2 * spacing);
|
||||
if (type == JackType.STEREO) {
|
||||
controlPoints[4] = new Point(x + spacing, y);
|
||||
controlPoints[5] = new Point(x + spacing, y + 2 * spacing);
|
||||
}
|
||||
|
||||
// Apply rotation if necessary
|
||||
double angle = getAngle();
|
||||
if (angle != 0) {
|
||||
AffineTransform rotation = AffineTransform.getRotateInstance(angle, x, y);
|
||||
for (int i = 1; i < controlPoints.length; i++) {
|
||||
rotation.transform(controlPoints[i], controlPoints[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double getAngle() {
|
||||
// Apply rotation if necessary
|
||||
double angle;
|
||||
switch (orientation) {
|
||||
case _90:
|
||||
angle = Math.PI / 2;
|
||||
break;
|
||||
case _180:
|
||||
angle = Math.PI;
|
||||
break;
|
||||
case _270:
|
||||
angle = Math.PI * 3 / 2;
|
||||
break;
|
||||
default:
|
||||
angle = 0;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Shape[5];
|
||||
|
||||
// Create body.
|
||||
int bodyLength = (int) BODY_LENGTH.convertToPixels();
|
||||
int bodyWidth = (int) BODY_WIDTH.convertToPixels();
|
||||
int centerX = (controlPoints[0].x + controlPoints[3].x) / 2;
|
||||
int centerY = (controlPoints[0].y + controlPoints[3].y) / 2;
|
||||
body[0] = new Rectangle(centerX - bodyLength / 2, centerY - bodyWidth / 2, bodyLength,
|
||||
bodyWidth);
|
||||
|
||||
int tailLength = (int) TAIL_LENGTH.convertToPixels();
|
||||
body[1] = new RoundRectangle2D.Double(centerX - bodyLength / 2 - tailLength, centerY
|
||||
- bodyWidth / 4, tailLength * 2, bodyWidth / 2, tailLength, tailLength);
|
||||
Area tailArea = new Area(body[1]);
|
||||
tailArea.subtract(new Area(body[0]));
|
||||
body[1] = tailArea;
|
||||
|
||||
body[2] = new Rectangle(centerX + bodyLength / 2, centerY - bodyWidth / 4, tailLength,
|
||||
bodyWidth / 2);
|
||||
|
||||
body[3] = new Rectangle(centerX + bodyLength / 2 + tailLength, centerY - bodyWidth / 4,
|
||||
tailLength, bodyWidth / 2);
|
||||
tailArea = new Area(body[3]);
|
||||
int radius = bodyLength / 2 + tailLength * 2;
|
||||
tailArea.intersect(new Area(new Ellipse2D.Double(centerX - radius, centerY - radius,
|
||||
radius * 2, radius * 2)));
|
||||
body[3] = tailArea;
|
||||
|
||||
// Apply rotation if necessary
|
||||
double angle = getAngle();
|
||||
if (angle != 0) {
|
||||
AffineTransform rotation = AffineTransform.getRotateInstance(angle, centerX,
|
||||
centerY);
|
||||
for (int i = 0; i < body.length; i++) {
|
||||
if (body[i] != null) {
|
||||
Area area = new Area(body[i]);
|
||||
area.transform(rotation);
|
||||
body[i] = area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create pins.
|
||||
Area pins = new Area();
|
||||
|
||||
int pinWidth = (int) PIN_WIDTH.convertToPixels();
|
||||
int pinThickness = (int) PIN_THICKNESS.convertToPixels();
|
||||
for (int i = 0; i < getControlPointCount(); i++) {
|
||||
Point point = getControlPoint(i);
|
||||
Rectangle pin;
|
||||
if (orientation == Orientation.DEFAULT || orientation == Orientation._180) {
|
||||
pin = new Rectangle(point.x - pinWidth / 2, point.y - pinThickness / 2,
|
||||
pinWidth, pinThickness);
|
||||
} else {
|
||||
pin = new Rectangle(point.x - pinThickness / 2, point.y - pinWidth / 2,
|
||||
pinThickness, pinWidth);
|
||||
}
|
||||
pins.add(new Area(pin));
|
||||
}
|
||||
|
||||
body[4] = pins;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
Shape[] body = getBody();
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BODY_COLOR);
|
||||
for (int i = 0; i < body.length - 1; i++) {
|
||||
// Nut is brighter colored.
|
||||
if (i == body.length - 2)
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : NUT_COLOR);
|
||||
g2d.fill(body[i]);
|
||||
}
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||
: BORDER_COLOR;
|
||||
}
|
||||
|
||||
g2d.setColor(finalBorderColor);
|
||||
for (int i = 0; i < body.length - 1; i++) {
|
||||
g2d.draw(body[i]);
|
||||
}
|
||||
|
||||
// Pins are the last piece.
|
||||
Shape pins = body[body.length - 1];
|
||||
g2d.setColor(METAL_COLOR);
|
||||
g2d.fill(pins);
|
||||
g2d.setColor(METAL_COLOR.darker());
|
||||
g2d.draw(pins);
|
||||
|
||||
Color finalLabelColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
|
||||
: LABEL_COLOR;
|
||||
}
|
||||
g2d.setColor(finalLabelColor);
|
||||
g2d.setFont(LABEL_FONT);
|
||||
int centerX = (controlPoints[0].x + controlPoints[3].x) / 2;
|
||||
int centerY = (controlPoints[0].y + controlPoints[3].y) / 2;
|
||||
drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER,
|
||||
VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int bodyWidth = getClosestOdd(width * 3 / 5);
|
||||
int tailWidth = getClosestOdd(width * 3 / 9);
|
||||
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRoundRect((width - tailWidth) / 2, height / 2, tailWidth, height / 2 - 2 * 32
|
||||
/ height, 4 * 32 / width, 4 * 32 / width);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRoundRect((width - tailWidth) / 2, height / 2, tailWidth, height / 2 - 2 * 32
|
||||
/ height, 4 * 32 / width, 4 * 32 / width);
|
||||
|
||||
g2d.setColor(NUT_COLOR);
|
||||
g2d.fillRoundRect((width - tailWidth) / 2, 2 * 32 / height, tailWidth, height / 2,
|
||||
4 * 32 / width, 4 * 32 / width);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRoundRect((width - tailWidth) / 2, 2 * 32 / height, tailWidth, height / 2,
|
||||
4 * 32 / width, 4 * 32 / width);
|
||||
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRect((width - bodyWidth) / 2, height / 7 + 1, bodyWidth, height * 5 / 7);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRect((width - bodyWidth) / 2, height / 7 + 1, bodyWidth, height * 5 / 7);
|
||||
|
||||
g2d.setColor(METAL_COLOR);
|
||||
int pinX1 = getClosestOdd((width - bodyWidth * 3 / 4) / 2);
|
||||
int pinX2 = getClosestOdd((width + bodyWidth * 3 / 4) / 2) - 1;
|
||||
g2d.drawLine(pinX1, width * 2 / 8, pinX1, width * 3 / 8);
|
||||
g2d.drawLine(pinX1, width * 5 / 8, pinX1, width * 6 / 8);
|
||||
g2d.drawLine(pinX2, width * 2 / 8, pinX2, width * 3 / 8);
|
||||
g2d.drawLine(pinX2, width * 5 / 8, pinX2, width * 6 / 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
body = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.NEVER;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public JackType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(JackType type) {
|
||||
this.type = type;
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Orientation getOrientation() {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
public void setOrientation(Orientation orientation) {
|
||||
this.orientation = orientation;
|
||||
updateControlPoints();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
package org.diylc.components.electromechanical;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.GeneralPath;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
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.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "Closed 1/4\" Jack", category = "Electromechanical", author = "Branislav Stojkovic", description = "Enclosed panel mount 1/4\" phono jack", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J")
|
||||
public class ClosedJack1_4 extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Size SPACING = new Size(0.1d, SizeUnit.in);
|
||||
private static Size LUG_WIDTH = new Size(0.1d, SizeUnit.in);
|
||||
private static Size LUG_LENGTH = new Size(0.12d, SizeUnit.in);
|
||||
private static Size LUG_HOLE_SIZE = new Size(1d, SizeUnit.mm);
|
||||
private static Color BODY_COLOR = Color.decode("#666666");
|
||||
private static Color SHAFT_COLOR = Color.decode("#AAAAAA");
|
||||
private static Size SHAFT_LENGTH = new Size(0.25d, SizeUnit.in);
|
||||
private static Size SHAFT_WIDTH = new Size(3d / 8, SizeUnit.in);
|
||||
private static Color BORDER_COLOR = Color.black;
|
||||
private static Color LABEL_COLOR = Color.white;
|
||||
private static Size BODY_WIDTH = new Size(0.65d, SizeUnit.in);
|
||||
private static Size BODY_LENGTH = new Size(0.8d, SizeUnit.in);
|
||||
|
||||
private Point[] controlPoints = new Point[] { new Point(0, 0) };
|
||||
private JackType type = JackType.MONO;
|
||||
private Orientation orientation = Orientation.DEFAULT;
|
||||
transient private Shape[] body;
|
||||
private String value = "";
|
||||
|
||||
public ClosedJack1_4() {
|
||||
super();
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
private void updateControlPoints() {
|
||||
// invalidate body shape
|
||||
body = null;
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
int spacing = (int) SPACING.convertToPixels();
|
||||
int bodyLength = (int) BODY_LENGTH.convertToPixels();
|
||||
controlPoints = new Point[type == JackType.STEREO ? 3 : 2];
|
||||
|
||||
controlPoints[0] = new Point(x, y);
|
||||
controlPoints[1] = new Point(x + bodyLength, y);
|
||||
if (type == JackType.STEREO) {
|
||||
controlPoints[2] = new Point(x, y + 2 * spacing);
|
||||
}
|
||||
|
||||
// Apply rotation if necessary
|
||||
double angle = getAngle();
|
||||
if (angle != 0) {
|
||||
AffineTransform rotation = AffineTransform.getRotateInstance(angle, x, y);
|
||||
for (int i = 1; i < controlPoints.length; i++) {
|
||||
rotation.transform(controlPoints[i], controlPoints[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double getAngle() {
|
||||
// Apply rotation if necessary
|
||||
double angle;
|
||||
switch (orientation) {
|
||||
case _90:
|
||||
angle = Math.PI / 2;
|
||||
break;
|
||||
case _180:
|
||||
angle = Math.PI;
|
||||
break;
|
||||
case _270:
|
||||
angle = Math.PI * 3 / 2;
|
||||
break;
|
||||
default:
|
||||
angle = 0;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Shape[5];
|
||||
|
||||
// Create body.
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
int lugWidth = (int) LUG_WIDTH.convertToPixels();
|
||||
int lugLength = (int) LUG_LENGTH.convertToPixels();
|
||||
int lugHoleSize = (int) LUG_HOLE_SIZE.convertToPixels();
|
||||
int bodyLength = (int) BODY_LENGTH.convertToPixels();
|
||||
int bodyWidth = (int) BODY_WIDTH.convertToPixels();
|
||||
body[0] = new Area(new Rectangle(x + lugLength, y - bodyWidth / 2, bodyLength,
|
||||
bodyWidth));
|
||||
|
||||
int shaftLength = (int) SHAFT_LENGTH.convertToPixels();
|
||||
int shaftWidth = (int) SHAFT_WIDTH.convertToPixels();
|
||||
Area shaft = new Area(new Rectangle(x + lugLength + bodyLength, y - shaftWidth / 2,
|
||||
shaftLength, shaftWidth));
|
||||
body[1] = shaft;
|
||||
|
||||
double angle = getAngle();
|
||||
AffineTransform rotation = null;
|
||||
if (angle != 0) {
|
||||
rotation = AffineTransform.getRotateInstance(angle, x, y);
|
||||
}
|
||||
|
||||
GeneralPath path = new GeneralPath();
|
||||
int step = 4;
|
||||
for (int i = x + lugLength + bodyLength + step; i <= x + lugLength + bodyLength
|
||||
+ shaftLength; i += step) {
|
||||
Point p = new Point(i, y - shaftWidth / 2 + 1);
|
||||
if (rotation != null) {
|
||||
rotation.transform(p, p);
|
||||
}
|
||||
path.moveTo(p.x, p.y);
|
||||
p = new Point(i - step, y + shaftWidth / 2 - 1);
|
||||
if (rotation != null) {
|
||||
rotation.transform(p, p);
|
||||
}
|
||||
path.lineTo(p.x, p.y);
|
||||
}
|
||||
Area pathArea = new Area(path);
|
||||
pathArea.intersect(shaft);
|
||||
body[2] = path;
|
||||
|
||||
// Create lugs.
|
||||
Area lugs = new Area();
|
||||
|
||||
int spacing = (int) SPACING.convertToPixels();
|
||||
Point[] untransformedControlPoints = new Point[type == JackType.STEREO ? 3 : 2];
|
||||
|
||||
untransformedControlPoints[0] = new Point(x, y);
|
||||
untransformedControlPoints[1] = new Point(x + bodyLength, y);
|
||||
if (type == JackType.STEREO) {
|
||||
untransformedControlPoints[2] = new Point(x, y + 2 * spacing);
|
||||
}
|
||||
|
||||
for (int i = 0; i < untransformedControlPoints.length; i++) {
|
||||
Point point = untransformedControlPoints[i];
|
||||
Area lug = new Area(new Ellipse2D.Double(point.x - lugWidth / 2, point.y - lugWidth
|
||||
/ 2, lugWidth, lugWidth));
|
||||
lug.add(new Area(
|
||||
new Rectangle(point.x, point.y - lugWidth / 2, lugLength, lugWidth)));
|
||||
lug.subtract(new Area(new Ellipse2D.Double(point.x - lugHoleSize / 2, point.y
|
||||
- lugHoleSize / 2, lugHoleSize, lugHoleSize)));
|
||||
lugs.add(lug);
|
||||
}
|
||||
|
||||
body[3] = lugs;
|
||||
|
||||
// Rotate everything that's of Area type, e.g. everything but lines.
|
||||
if (rotation != null) {
|
||||
for (Shape shape : body) {
|
||||
if (shape instanceof Area) {
|
||||
Area area = (Area) shape;
|
||||
area.transform(rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
Shape[] body = getBody();
|
||||
|
||||
// Rectangle bounds = body.getBounds();
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BODY_COLOR);
|
||||
g2d.fill(body[0]);
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : SHAFT_COLOR);
|
||||
g2d.fill(body[1]);
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : METAL_COLOR);
|
||||
g2d.fill(body[3]);
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : BORDER_COLOR;
|
||||
}
|
||||
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body[0]);
|
||||
g2d.draw(body[1]);
|
||||
if (!outlineMode) {
|
||||
g2d.setColor(SHAFT_COLOR.darker());
|
||||
g2d.fill(body[2]);
|
||||
g2d.draw(body[2]);
|
||||
}
|
||||
|
||||
// Pins are the last piece.
|
||||
g2d.setColor(outlineMode ? finalBorderColor : METAL_COLOR.darker());
|
||||
g2d.draw(body[3]);
|
||||
|
||||
Color finalLabelColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
|
||||
: LABEL_COLOR;
|
||||
}
|
||||
g2d.setColor(finalLabelColor);
|
||||
g2d.setFont(LABEL_FONT);
|
||||
Rectangle bounds = body[0].getBounds();
|
||||
int centerX = bounds.x + bounds.width / 2;
|
||||
int centerY = bounds.y + bounds.height / 2;
|
||||
drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER,
|
||||
VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int bodyWidth = getClosestOdd(width * 3 / 5);
|
||||
int tailWidth = getClosestOdd(width * 3 / 10);
|
||||
|
||||
g2d.setColor(SHAFT_COLOR);
|
||||
g2d.fillRect((width - tailWidth) / 2, 1, tailWidth, height / 2);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRect((width - tailWidth) / 2, 1, tailWidth, height / 2);
|
||||
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRect((width - bodyWidth) / 2, height / 7 + 1, bodyWidth, height * 5 / 7);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRect((width - bodyWidth) / 2, height / 7 + 1, bodyWidth, height * 5 / 7);
|
||||
|
||||
g2d.setColor(METAL_COLOR);
|
||||
|
||||
g2d.fillRect(width * 7 / 16, height * 6 / 7 + 1, width / 8, height / 7 - 1);
|
||||
g2d.fillRect(width * 7 / 16, height / 7 + 2, width / 8, height / 7 - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
body = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.NEVER;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public JackType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(JackType type) {
|
||||
this.type = type;
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Orientation getOrientation() {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
public void setOrientation(Orientation orientation) {
|
||||
this.orientation = orientation;
|
||||
updateControlPoints();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.diylc.components.electromechanical;
|
||||
|
||||
public enum DCPolarity {
|
||||
|
||||
NONE("None"), CENTER_POSITIVE("Center Positive"), CENTER_NEGATIVE("Center Negative");
|
||||
|
||||
private String title;
|
||||
|
||||
private DCPolarity(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.diylc.components.electromechanical;
|
||||
|
||||
public enum JackType {
|
||||
|
||||
MONO, STEREO;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -33,12 +33,11 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
|
||||
private static Size MARGIN = new Size(0.08d, SizeUnit.in);
|
||||
private static Size CIRCLE_SIZE = new Size(0.09d, SizeUnit.in);
|
||||
private static Size LUG_WIDTH = new Size(0.060d, SizeUnit.in);
|
||||
private static Size LUG_HEIGHT = new Size(0.03d, SizeUnit.in);
|
||||
private static Size LUG_THICKNESS = new Size(0.02d, SizeUnit.in);
|
||||
|
||||
private static Color BODY_COLOR = Color.decode("#3299CC");
|
||||
private static Color BORDER_COLOR = BODY_COLOR.darker();
|
||||
private static Color CIRCLE_COLOR = Color.red;
|
||||
private static Color LUG_COLOR = Color.decode("#00B2EE");
|
||||
private static Color CIRCLE_COLOR = Color.decode("#FFFFAA");
|
||||
|
||||
protected Point[] controlPoints = new Point[] { new Point(0, 0) };
|
||||
transient protected RoundRectangle2D body;
|
||||
@@ -205,17 +204,17 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
|
||||
// so far.
|
||||
drawingObserver.stopTracking();
|
||||
// Draw lugs.
|
||||
if (!outlineMode) {
|
||||
int circleDiameter = getClosestOdd((int) CIRCLE_SIZE.convertToPixels());
|
||||
int lugWidth = getClosestOdd((int) LUG_WIDTH.convertToPixels());
|
||||
int lugHeight = getClosestOdd((int) LUG_HEIGHT.convertToPixels());
|
||||
for (Point p : controlPoints) {
|
||||
int circleDiameter = getClosestOdd((int) CIRCLE_SIZE.convertToPixels());
|
||||
int lugWidth = getClosestOdd((int) LUG_WIDTH.convertToPixels());
|
||||
int lugHeight = getClosestOdd((int) LUG_THICKNESS.convertToPixels());
|
||||
for (Point p : controlPoints) {
|
||||
if (!outlineMode) {
|
||||
g2d.setColor(CIRCLE_COLOR);
|
||||
g2d.fillOval(p.x - circleDiameter / 2, p.y - circleDiameter / 2, circleDiameter,
|
||||
circleDiameter);
|
||||
g2d.setColor(LUG_COLOR);
|
||||
g2d.fillRect(p.x - lugWidth / 2, p.y - lugHeight / 2, lugWidth, lugHeight);
|
||||
}
|
||||
g2d.setColor(METAL_COLOR);
|
||||
g2d.fillRect(p.x - lugWidth / 2, p.y - lugHeight / 2, lugWidth, lugHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,9 +260,12 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
|
||||
g2d.fillRoundRect(width / 4, 1, width / 2, height - 2, circleSize, circleSize);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRoundRect(width / 4, 1, width / 2, height - 2, circleSize, circleSize);
|
||||
g2d.setColor(CIRCLE_COLOR);
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
g2d.setColor(CIRCLE_COLOR);
|
||||
g2d.fillOval(width / 2 - circleSize / 2, i * height / 4 - 3, circleSize, circleSize);
|
||||
g2d.setColor(METAL_COLOR);
|
||||
g2d.drawLine(width / 2 - circleSize / 2 + 1, i * height / 4 - 1, width / 2 + circleSize
|
||||
/ 2 - 1, i * height / 4 - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
package org.diylc.components.electromechanical;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
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.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "Plastic DC Jack", category = "Electromechanical", author = "Branislav Stojkovic", description = "Panel mount plastic DC jack", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J")
|
||||
public class PlasticDCJack extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Size LUG_WIDTH = new Size(0.08d, SizeUnit.in);
|
||||
private static Size LUG_THICKNESS = new Size(0.02d, SizeUnit.in);
|
||||
private static Size SPACING = new Size(0.1d, SizeUnit.in);
|
||||
private static Size DIAMETER = new Size(0.5d, SizeUnit.in);
|
||||
private static Color BODY_COLOR = Color.decode("#666666");
|
||||
private static Color PHENOLIC_COLOR = Color.decode("#CD8500");
|
||||
private static Color BORDER_COLOR = Color.black;
|
||||
private static Color MARKING_COLOR = Color.lightGray;
|
||||
|
||||
private Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0), new Point(0, 0) };
|
||||
private String value = "";
|
||||
private DCPolarity polarity = DCPolarity.CENTER_NEGATIVE;
|
||||
transient private Shape[] body;
|
||||
|
||||
public PlasticDCJack() {
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
private void updateControlPoints() {
|
||||
// invalidate body shape
|
||||
body = null;
|
||||
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
|
||||
int spacing = (int) SPACING.convertToPixels();
|
||||
controlPoints[1] = new Point(x + spacing, y + spacing);
|
||||
controlPoints[2] = new Point(x - spacing, y + spacing * 2);
|
||||
}
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Shape[4];
|
||||
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
int spacing = (int) SPACING.convertToPixels();
|
||||
int diameter = getClosestOdd(DIAMETER.convertToPixels());
|
||||
body[0] = new Ellipse2D.Double(x - diameter / 2, y + spacing - diameter / 2, diameter,
|
||||
diameter);
|
||||
|
||||
int rectWidth = (int) (diameter / Math.sqrt(2)) - 2;
|
||||
body[1] = new Rectangle(x - rectWidth / 2, y + spacing - rectWidth / 2, rectWidth,
|
||||
rectWidth);
|
||||
|
||||
int lugWidth = getClosestOdd(LUG_WIDTH.convertToPixels());
|
||||
int lugThickness = getClosestOdd(LUG_THICKNESS.convertToPixels());
|
||||
|
||||
Point groundPoint = controlPoints[controlPoints.length - 1];
|
||||
Area groundLug = new Area(new Ellipse2D.Double(groundPoint.x + spacing - lugWidth / 2,
|
||||
groundPoint.y - lugWidth / 2, lugWidth, lugWidth));
|
||||
groundLug.add(new Area(new Rectangle(groundPoint.x, groundPoint.y - lugWidth / 2,
|
||||
spacing, lugWidth)));
|
||||
groundLug.subtract(new Area(new Ellipse2D.Double(
|
||||
groundPoint.x + spacing - lugWidth / 6, groundPoint.y - lugWidth / 6,
|
||||
lugWidth / 3, lugWidth / 3)));
|
||||
body[2] = groundLug;
|
||||
|
||||
Area lugArea = new Area();
|
||||
for (int i = 0; i < controlPoints.length; i++) {
|
||||
Point point = controlPoints[i];
|
||||
if (i == getControlPointCount() - 1) {
|
||||
lugArea.add(new Area(new Rectangle(point.x - lugThickness / 2, point.y
|
||||
- lugWidth / 2, lugThickness, lugWidth)));
|
||||
} else {
|
||||
lugArea.add(new Area(new Rectangle(point.x - lugWidth / 2, point.y
|
||||
- lugThickness / 2, lugWidth, lugThickness)));
|
||||
}
|
||||
}
|
||||
body[3] = lugArea;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
Shape[] body = getBody();
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BODY_COLOR);
|
||||
g2d.fill(body[0]);
|
||||
if (!outlineMode) {
|
||||
g2d.setColor(PHENOLIC_COLOR);
|
||||
g2d.fill(body[1]);
|
||||
}
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : BORDER_COLOR;
|
||||
}
|
||||
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body[0]);
|
||||
if (!outlineMode) {
|
||||
g2d.setColor(PHENOLIC_COLOR.darker());
|
||||
g2d.draw(body[1]);
|
||||
|
||||
g2d.setColor(METAL_COLOR);
|
||||
g2d.fill(body[2]);
|
||||
g2d.setColor(METAL_COLOR.darker());
|
||||
g2d.draw(body[2]);
|
||||
}
|
||||
|
||||
g2d.setColor(METAL_COLOR);
|
||||
g2d.fill(body[3]);
|
||||
g2d.setColor(METAL_COLOR.darker());
|
||||
g2d.draw(body[3]);
|
||||
|
||||
if (!outlineMode && getPolarity() != DCPolarity.NONE) {
|
||||
int spacing = (int) SPACING.convertToPixels();
|
||||
g2d.setColor(MARKING_COLOR);
|
||||
g2d.setFont(LABEL_FONT.deriveFont(12f));
|
||||
drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "+" : "-",
|
||||
controlPoints[0].x, controlPoints[0].y - spacing * 7 / 16,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "_" : "+",
|
||||
controlPoints[2].x, controlPoints[2].y - spacing * 3 / 4,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int margin = 2 * 32 / width;
|
||||
int diameter = getClosestOdd(width - margin);
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillOval((width - diameter) / 2, (height - diameter) / 2, diameter, diameter);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawOval((width - diameter) / 2, (height - diameter) / 2, diameter, diameter);
|
||||
int rectWidth = getClosestOdd(((width - 2 * margin) / Math.sqrt(2)) - margin / 2);
|
||||
g2d.setColor(PHENOLIC_COLOR);
|
||||
g2d.fillRect((width - rectWidth) / 2, (height - rectWidth) / 2, rectWidth, rectWidth);
|
||||
g2d.setColor(PHENOLIC_COLOR.darker());
|
||||
g2d.drawRect((width - rectWidth) / 2, (height - rectWidth) / 2, rectWidth, rectWidth);
|
||||
int lugWidth = 4 * 32 / width;
|
||||
g2d.setColor(METAL_COLOR);
|
||||
g2d.drawLine((width - lugWidth) / 2, height / 3, (width + lugWidth) / 2, height / 3);
|
||||
g2d
|
||||
.drawLine(width * 2 / 3, (height - lugWidth) / 2, width * 2 / 3,
|
||||
(height + lugWidth) / 2);
|
||||
g2d.fillOval((width - lugWidth) / 2, height * 2 / 3 - lugWidth / 2, lugWidth, lugWidth);
|
||||
g2d.fillRect(width / 2 - lugWidth * 3 / 2, height * 2 / 3 - lugWidth / 2, lugWidth * 3 / 2,
|
||||
lugWidth);
|
||||
g2d.setColor(PHENOLIC_COLOR);
|
||||
g2d.fillOval((width - margin) / 2, height * 2 / 3 - margin / 2, margin, margin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
this.body = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.NEVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public DCPolarity getPolarity() {
|
||||
if (polarity == null) {
|
||||
polarity = DCPolarity.CENTER_NEGATIVE;
|
||||
}
|
||||
return polarity;
|
||||
}
|
||||
|
||||
public void setPolarity(DCPolarity polarity) {
|
||||
this.polarity = polarity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
package org.diylc.components.guitar;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
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.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "Humbucker Pickup", category = "Guitar", author = "Branislav Stojkovic", description = "PAF-style humbucker guitar pickup", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "PKP")
|
||||
public class HumbuckerPickup extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Color BODY_COLOR = Color.lightGray;
|
||||
private static Color POINT_COLOR = Color.darkGray;
|
||||
private static Size WIDTH = new Size(36.5d, SizeUnit.mm);
|
||||
private static Size LENGTH = new Size(68.58d, SizeUnit.mm);
|
||||
private static Size LIP_WIDTH = new Size(12.7d, SizeUnit.mm);
|
||||
private static Size LIP_LENGTH = new Size(7.9d, SizeUnit.mm);
|
||||
private static Size EDGE_RADIUS = new Size(4d, SizeUnit.mm);
|
||||
private static Size POINT_MARGIN = new Size(5d, SizeUnit.mm);
|
||||
private static Size POINT_SIZE = new Size(3d, SizeUnit.mm);
|
||||
private static Size LIP_HOLE_SIZE = new Size(1.5d, SizeUnit.mm);
|
||||
private static Size POLE_SIZE = new Size(3d, SizeUnit.mm);
|
||||
private static Size POLE_SPACING = new Size(10.1d, SizeUnit.mm);
|
||||
private static Size COIL_SPACING = new Size(18d, SizeUnit.mm);
|
||||
|
||||
private String value = "";
|
||||
private Point controlPoint = new Point(0, 0);
|
||||
transient Shape[] body;
|
||||
private Orientation orientation = Orientation.DEFAULT;
|
||||
private Color color = BODY_COLOR;
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
Shape[] body = getBody();
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : color);
|
||||
g2d.fill(body[0]);
|
||||
g2d.fill(body[1]);
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : POINT_COLOR);
|
||||
g2d.fill(body[2]);
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : color.darker();
|
||||
}
|
||||
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body[0]);
|
||||
g2d.draw(body[1]);
|
||||
if (!outlineMode) {
|
||||
g2d.setColor(color.darker());
|
||||
g2d.draw(body[3]);
|
||||
}
|
||||
|
||||
Color finalLabelColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
|
||||
: LABEL_COLOR;
|
||||
}
|
||||
g2d.setColor(finalLabelColor);
|
||||
g2d.setFont(LABEL_FONT);
|
||||
Rectangle bounds = body[0].getBounds();
|
||||
drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Shape[4];
|
||||
|
||||
int x = controlPoint.x;
|
||||
int y = controlPoint.y;
|
||||
int width = (int) WIDTH.convertToPixels();
|
||||
int length = (int) LENGTH.convertToPixels();
|
||||
int lipWidth = (int) LIP_WIDTH.convertToPixels();
|
||||
int lipLength = (int) LIP_LENGTH.convertToPixels();
|
||||
int edgeRadius = (int) EDGE_RADIUS.convertToPixels();
|
||||
int pointMargin = (int) POINT_MARGIN.convertToPixels();
|
||||
int pointSize = getClosestOdd(POINT_SIZE.convertToPixels());
|
||||
int lipHoleSize = getClosestOdd(LIP_HOLE_SIZE.convertToPixels());
|
||||
|
||||
body[0] = new Area(new RoundRectangle2D.Double(x + pointMargin - length, y
|
||||
- pointMargin, length, width, edgeRadius, edgeRadius));
|
||||
body[1] = new Area(new RoundRectangle2D.Double(x + pointMargin - length - lipLength, y
|
||||
- pointMargin + width / 2 - lipWidth / 2, length + 2 * lipLength, lipWidth,
|
||||
edgeRadius / 2, edgeRadius / 2));
|
||||
Area lipArea = new Area(body[1]);
|
||||
lipArea.subtract(new Area(body[0]));
|
||||
lipArea.subtract(new Area(new Ellipse2D.Double(
|
||||
x + pointMargin - length - lipLength / 2, y - pointMargin + width / 2
|
||||
- lipHoleSize / 2, lipHoleSize, lipHoleSize)));
|
||||
lipArea.subtract(new Area(new Ellipse2D.Double(x + pointMargin + lipLength / 2, y
|
||||
- pointMargin + width / 2 - lipHoleSize / 2, lipHoleSize, lipHoleSize)));
|
||||
body[1] = lipArea;
|
||||
body[2] = new Area(new Ellipse2D.Double(x - pointSize / 2, y - pointSize / 2,
|
||||
pointSize, pointSize));
|
||||
|
||||
int poleSize = (int) POLE_SIZE.convertToPixels();
|
||||
int poleSpacing = (int) POLE_SPACING.convertToPixels();
|
||||
int coilSpacing = (int) COIL_SPACING.convertToPixels();
|
||||
int coilMargin = (width - coilSpacing) / 2;
|
||||
int poleMargin = (length - poleSpacing * 5) / 2;
|
||||
Area poleArea = new Area();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Ellipse2D pole = new Ellipse2D.Double(x + pointMargin - length + poleMargin + i
|
||||
* poleSpacing - poleSize / 2, y - pointMargin + coilMargin - poleSize / 2,
|
||||
poleSize, poleSize);
|
||||
poleArea.add(new Area(pole));
|
||||
pole = new Ellipse2D.Double(x + pointMargin - length + poleMargin + i * poleSpacing
|
||||
- poleSize / 2, y - pointMargin + width - coilMargin - poleSize / 2,
|
||||
poleSize, poleSize);
|
||||
poleArea.add(new Area(pole));
|
||||
}
|
||||
body[3] = poleArea;
|
||||
|
||||
// Rotate if needed
|
||||
if (orientation != Orientation.DEFAULT) {
|
||||
double theta = 0;
|
||||
switch (orientation) {
|
||||
case _90:
|
||||
theta = Math.PI / 2;
|
||||
break;
|
||||
case _180:
|
||||
theta = Math.PI;
|
||||
break;
|
||||
case _270:
|
||||
theta = Math.PI * 3 / 2;
|
||||
break;
|
||||
}
|
||||
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
|
||||
for (Shape shape : body) {
|
||||
Area area = (Area) shape;
|
||||
area.transform(rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int baseWidth = 16 * width / 32;
|
||||
int baseLength = 27 * width / 32;
|
||||
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRoundRect((width - baseWidth / 4) / 2, 0, baseWidth / 4, height - 1,
|
||||
2 * width / 32, 2 * width / 32);
|
||||
g2d.setColor(BODY_COLOR.darker());
|
||||
g2d.drawRoundRect((width - baseWidth / 4) / 2, 0, baseWidth / 4, height - 1,
|
||||
2 * width / 32, 2 * width / 32);
|
||||
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRoundRect((width - baseWidth) / 2, (height - baseLength) / 2, baseWidth,
|
||||
baseLength, 4 * width / 32, 4 * width / 32);
|
||||
g2d.setColor(BODY_COLOR.darker());
|
||||
g2d.drawRoundRect((width - baseWidth) / 2, (height - baseLength) / 2, baseWidth,
|
||||
baseLength, 4 * width / 32, 4 * width / 32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return controlPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
this.controlPoint.setLocation(point);
|
||||
// Invalidate the body
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Model")
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Orientation getOrientation() {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
public void setOrientation(Orientation orientation) {
|
||||
this.orientation = orientation;
|
||||
// Invalidate the body
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
package org.diylc.components.guitar;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
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.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "Strat Single Coil Pickup", category = "Guitar", author = "Branislav Stojkovic", description = "Strat-style single coil guitar pickup", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "PKP")
|
||||
public class SingleCoilPickup extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Color BODY_COLOR = Color.darkGray;
|
||||
private static Color POINT_COLOR = Color.lightGray;
|
||||
private static Size WIDTH = new Size(15.5d, SizeUnit.mm);
|
||||
private static Size LENGTH = new Size(83.82d, SizeUnit.mm);
|
||||
private static Size LIP_WIDTH = new Size(5d, SizeUnit.mm);
|
||||
private static Size LIP_LENGTH = new Size(20d, SizeUnit.mm);
|
||||
private static Size POINT_SIZE = new Size(3d, SizeUnit.mm);
|
||||
private static Size HOLE_SIZE = new Size(2d, SizeUnit.mm);
|
||||
private static Size HOLE_MARGIN = new Size(4d, SizeUnit.mm);
|
||||
private static Size POLE_SIZE = new Size(3d, SizeUnit.mm);
|
||||
private static Size POLE_SPACING = new Size(11.68d, SizeUnit.mm);
|
||||
|
||||
private String value = "";
|
||||
private Point controlPoint = new Point(0, 0);
|
||||
transient Shape[] body;
|
||||
private Orientation orientation = Orientation.DEFAULT;
|
||||
private Color color = BODY_COLOR;
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
Shape[] body = getBody();
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : color);
|
||||
g2d.fill(body[0]);
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : POINT_COLOR);
|
||||
g2d.fill(body[1]);
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : color
|
||||
.brighter();
|
||||
}
|
||||
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body[0]);
|
||||
if (!outlineMode) {
|
||||
g2d.draw(body[2]);
|
||||
}
|
||||
|
||||
Color finalLabelColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
|
||||
: LABEL_COLOR;
|
||||
}
|
||||
g2d.setColor(finalLabelColor);
|
||||
g2d.setFont(LABEL_FONT);
|
||||
Rectangle bounds = body[0].getBounds();
|
||||
drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Shape[3];
|
||||
|
||||
int x = controlPoint.x;
|
||||
int y = controlPoint.y;
|
||||
int width = (int) WIDTH.convertToPixels();
|
||||
int length = (int) LENGTH.convertToPixels();
|
||||
int lipWidth = (int) LIP_WIDTH.convertToPixels();
|
||||
int lipLength = (int) LIP_LENGTH.convertToPixels();
|
||||
int pointSize = getClosestOdd(POINT_SIZE.convertToPixels());
|
||||
int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
|
||||
int holeMargin = getClosestOdd(HOLE_MARGIN.convertToPixels());
|
||||
|
||||
Area mainArea = new Area(new RoundRectangle2D.Double(x - length / 2, y - lipWidth / 2
|
||||
- width, length, width, width, width));
|
||||
mainArea.add(new Area(new Polygon(new int[] { x - length / 2 + width / 2,
|
||||
x + length / 2 - width / 2, x + lipLength / 2, x - lipLength / 2 }, new int[] {
|
||||
y - lipWidth / 2, y - lipWidth / 2, y + lipWidth / 2, y + lipWidth / 2 }, 4)));
|
||||
// Cutout holes
|
||||
mainArea.subtract(new Area(new Ellipse2D.Double(x - length / 2 + holeMargin - holeSize
|
||||
/ 2, y - lipWidth / 2 - width / 2 - holeSize / 2, holeSize, holeSize)));
|
||||
mainArea.subtract(new Area(new Ellipse2D.Double(x + length / 2 - holeMargin - holeSize
|
||||
/ 2, y - lipWidth / 2 - width / 2 - holeSize / 2, holeSize, holeSize)));
|
||||
|
||||
body[0] = mainArea;
|
||||
|
||||
body[1] = new Area(new Ellipse2D.Double(x - pointSize / 2, y - pointSize / 2,
|
||||
pointSize, pointSize));
|
||||
|
||||
int poleSize = (int) POLE_SIZE.convertToPixels();
|
||||
int poleSpacing = (int) POLE_SPACING.convertToPixels();
|
||||
int poleMargin = (length - poleSpacing * 5) / 2;
|
||||
Area poleArea = new Area();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Ellipse2D pole = new Ellipse2D.Double(
|
||||
x - length / 2 + poleMargin + i * poleSpacing, y - lipWidth / 2 - width / 2
|
||||
- poleSize / 2, poleSize, poleSize);
|
||||
poleArea.add(new Area(pole));
|
||||
}
|
||||
body[2] = poleArea;
|
||||
|
||||
// Rotate if needed
|
||||
if (orientation != Orientation.DEFAULT) {
|
||||
double theta = 0;
|
||||
switch (orientation) {
|
||||
case _90:
|
||||
theta = Math.PI / 2;
|
||||
break;
|
||||
case _180:
|
||||
theta = Math.PI;
|
||||
break;
|
||||
case _270:
|
||||
theta = Math.PI * 3 / 2;
|
||||
break;
|
||||
}
|
||||
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
|
||||
for (Shape shape : body) {
|
||||
Area area = (Area) shape;
|
||||
area.transform(rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int bodyWidth = 8 * width / 32;
|
||||
int bodyLength = 30 * width / 32;
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRoundRect((width - bodyWidth) / 2, (height - bodyLength) / 2, bodyWidth,
|
||||
bodyLength, bodyWidth, bodyWidth);
|
||||
g2d.fillPolygon(new int[] { width * 9 / 16, width * 9 / 16, width * 11 / 16, width * 11 / 16 },
|
||||
new int[] { (height - bodyLength) / 2, (height + bodyLength) / 2, height * 5 / 8,
|
||||
height * 3 / 8 }, 4);
|
||||
|
||||
g2d.setColor(Color.lightGray);
|
||||
g2d.drawLine(width / 2, 4 * width / 32, width / 2, 4 * width / 32);
|
||||
g2d.drawLine(width / 2, height - 4 * width / 32, width / 2, height - 4 * width / 32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return controlPoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
this.controlPoint.setLocation(point);
|
||||
// Invalidate the body
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Model")
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Orientation getOrientation() {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
public void setOrientation(Orientation orientation) {
|
||||
this.orientation = orientation;
|
||||
// Invalidate the body
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package org.diylc.components.misc;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Polygon;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.components.AbstractComponent;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Ground Symbol", author = "Branislav Stojkovic", category = "Misc", instanceNamePrefix = "GND", description = "Ground schematic symbol", stretchable = false, zOrder = IDIYComponent.COMPONENT)
|
||||
public class GroundSymbol extends AbstractComponent<Void> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color COLOR = Color.black;
|
||||
public static Size SIZE = new Size(0.15d, SizeUnit.in);
|
||||
|
||||
private Point point = new Point(0, 0);
|
||||
private Color color = COLOR;
|
||||
private Size size = SIZE;
|
||||
private GroundSymbolType type = GroundSymbolType.DEFAULT;
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
int sizePx = (int) size.convertToPixels();
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.setColor(color);
|
||||
int x = point.x;
|
||||
int y = point.y;
|
||||
g2d.drawLine(x, y, x, y + sizePx / 6);
|
||||
if (type == GroundSymbolType.DEFAULT) {
|
||||
int delta = sizePx / 7;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
g2d.drawLine(x - sizePx / 2 + delta * i, y + sizePx / 6 * (i + 1), x + sizePx / 2
|
||||
- delta * i, y + sizePx / 6 * (i + 1));
|
||||
}
|
||||
} else {
|
||||
Polygon poly = new Polygon(new int[] { x - sizePx / 2, x + sizePx / 2, x }, new int[] {
|
||||
y + sizePx / 6, y + sizePx / 6, y + sizePx }, 3);
|
||||
g2d.draw(poly);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int margin = 3 * width / 32;
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.setColor(COLOR);
|
||||
g2d.drawLine(width / 2, margin * 2, width / 2, margin * 3 + height / 5);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
g2d.drawLine(margin * (i + 1), margin * (3 + i) + height / 5, width - margin * (i + 1),
|
||||
margin * (3 + i) + height / 5);
|
||||
}
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Style")
|
||||
public GroundSymbolType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(GroundSymbolType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return point;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Size getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Size size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public Void getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setValue(Void value) {
|
||||
}
|
||||
|
||||
public static enum GroundSymbolType {
|
||||
DEFAULT("Default"), TRIANGLE("Triangle");
|
||||
|
||||
private String title;
|
||||
|
||||
private GroundSymbolType(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import org.diylc.core.measures.ResistanceUnit;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Resistor (schematic symbol)", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "R", description = "", zOrder = IDIYComponent.COMPONENT)
|
||||
@ComponentDescriptor(name = "Resistor (schematic symbol)", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "R", description = "Resistor schematic symbol", zOrder = IDIYComponent.COMPONENT)
|
||||
public class ResistorSymbol extends AbstractSchematicLeadedSymbol<Resistance> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
import java.awt.Shape;
|
||||
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
|
||||
public abstract class AbstractDiodeSymbol extends AbstractLeadedComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected boolean shouldShadeLeads() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shape getBodyShape() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Shape;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.VerticalAlignment;
|
||||
import org.diylc.components.AbstractComponent;
|
||||
import org.diylc.core.ComponentState;
|
||||
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.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
public abstract class AbstractTransistorSymbol extends AbstractComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
public static Color COLOR = Color.black;
|
||||
|
||||
protected String value = "";
|
||||
protected Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0),
|
||||
new Point(0, 0) };
|
||||
protected Color color = COLOR;
|
||||
protected Display display = Display.NAME;
|
||||
transient protected Shape[] body;
|
||||
|
||||
public AbstractTransistorSymbol() {
|
||||
super();
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
if (checkPointsClipped(g2d.getClip())) {
|
||||
return;
|
||||
}
|
||||
int pinSpacing = (int) PIN_SPACING.convertToPixels();
|
||||
Color finalColor;
|
||||
if (componentState == ComponentState.SELECTED) {
|
||||
finalColor = SELECTION_COLOR;
|
||||
} else if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalColor = theme.getOutlineColor();
|
||||
} else {
|
||||
finalColor = color;
|
||||
}
|
||||
g2d.setColor(finalColor);
|
||||
|
||||
// Draw transistor
|
||||
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
|
||||
Shape[] body = getBody();
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
||||
g2d.draw(body[0]);
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.draw(body[1]);
|
||||
|
||||
g2d.fill(body[2]);
|
||||
|
||||
// Draw label
|
||||
g2d.setFont(LABEL_FONT);
|
||||
Color finalLabelColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
|
||||
: LABEL_COLOR;
|
||||
}
|
||||
g2d.setColor(finalLabelColor);
|
||||
drawCenteredText(g2d, display == Display.VALUE ? getValue() : getName(),
|
||||
x + pinSpacing * 2, y, HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
private void updateControlPoints() {
|
||||
int pinSpacing = (int) PIN_SPACING.convertToPixels();
|
||||
// Update control points.
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
|
||||
controlPoints[1].x = x + pinSpacing * 2;
|
||||
controlPoints[1].y = y - pinSpacing * 2;
|
||||
|
||||
controlPoints[2].x = x + pinSpacing * 2;
|
||||
controlPoints[2].y = y + pinSpacing * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@Override
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
// Invalidate body
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Display getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public void setDisplay(Display display) {
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns transistor shape consisting of 3 parts, in this order: main body,
|
||||
* connectors, polarity arrow.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract Shape[] getBody();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
public enum BJTPolarity {
|
||||
|
||||
NPN, PNP;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.GeneralPath;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
@ComponentDescriptor(name = "BJT Symbol", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "Bipolar junction transistor schematic symbol", stretchable = false, zOrder = IDIYComponent.COMPONENT)
|
||||
public class BJTSymbol extends AbstractTransistorSymbol {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected BJTPolarity polarity = BJTPolarity.NPN;
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Shape[3];
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
int pinSpacing = (int) PIN_SPACING.convertToPixels();
|
||||
|
||||
GeneralPath polyline = new GeneralPath();
|
||||
|
||||
polyline.moveTo(x + pinSpacing / 2, y - pinSpacing);
|
||||
polyline.lineTo(x + pinSpacing / 2, y + pinSpacing);
|
||||
|
||||
body[0] = polyline;
|
||||
|
||||
polyline = new GeneralPath();
|
||||
|
||||
polyline.moveTo(x, y);
|
||||
polyline.lineTo(x + pinSpacing / 2, y);
|
||||
polyline.moveTo(x + pinSpacing / 2, y - pinSpacing / 2);
|
||||
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing);
|
||||
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing * 2);
|
||||
polyline.moveTo(x + pinSpacing / 2, y + pinSpacing / 2);
|
||||
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing);
|
||||
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing * 2);
|
||||
body[1] = polyline;
|
||||
|
||||
Area arrow;
|
||||
double theta;
|
||||
if (polarity == BJTPolarity.NPN) {
|
||||
theta = Math.atan(1.0 / 3);
|
||||
arrow = new Area(new Polygon(new int[] { x + pinSpacing, x + pinSpacing,
|
||||
x + pinSpacing * 10 / 6 }, new int[] { y - pinSpacing / 5 + pinSpacing / 2,
|
||||
y + pinSpacing / 5 + pinSpacing / 2, y + pinSpacing / 2 }, 3));
|
||||
arrow.transform(AffineTransform.getRotateInstance(theta, x + pinSpacing / 2, y
|
||||
+ pinSpacing / 2));
|
||||
} else {
|
||||
theta = -Math.atan(1.0 / 3);
|
||||
arrow = new Area(new Polygon(new int[] { x + pinSpacing, x + pinSpacing * 10 / 6,
|
||||
x + pinSpacing * 10 / 6 }, new int[] { y - pinSpacing / 2,
|
||||
y - pinSpacing / 5 - pinSpacing / 2, y + pinSpacing / 5 - pinSpacing / 2 },
|
||||
3));
|
||||
arrow.transform(AffineTransform.getRotateInstance(theta, x + pinSpacing / 2, y
|
||||
- pinSpacing / 2));
|
||||
}
|
||||
body[2] = arrow;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setColor(COLOR);
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
||||
g2d.drawLine(width / 3, height / 5, width / 3, height * 4 / 5);
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.drawLine(width / 8, height / 2, width / 3, height / 2);
|
||||
|
||||
g2d.drawLine(width * 3 / 4, 1, width * 3 / 4, height / 4);
|
||||
g2d.drawLine(width / 3, height / 3 + 1, width * 3 / 4, height / 4);
|
||||
|
||||
g2d.drawLine(width * 3 / 4, height - 1, width * 3 / 4, height * 3 / 4);
|
||||
g2d.drawLine(width / 3, height * 2 / 3 - 1, width * 3 / 4, height * 3 / 4);
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Polarity")
|
||||
public BJTPolarity getPolarity() {
|
||||
return polarity;
|
||||
}
|
||||
|
||||
public void setPolarity(BJTPolarity polarity) {
|
||||
this.polarity = polarity;
|
||||
// Invalidate body
|
||||
body = null;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.Orientation;
|
||||
@@ -50,6 +51,7 @@ public class DIL_IC extends AbstractTransparentComponent<String> {
|
||||
private Size pinSpacing = new Size(0.1d, SizeUnit.in);
|
||||
private Size rowSpacing = new Size(0.3d, SizeUnit.in);
|
||||
private Point[] controlPoints = new Point[] { new Point(0, 0) };
|
||||
protected Display display = Display.NAME;
|
||||
// new Point(0, pinSpacing.convertToPixels()),
|
||||
// new Point(0, 2 * pinSpacing.convertToPixels()),
|
||||
// new Point(0, 3 * pinSpacing.convertToPixels()),
|
||||
@@ -120,6 +122,18 @@ public class DIL_IC extends AbstractTransparentComponent<String> {
|
||||
// Reset body shape;
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Display getDisplay() {
|
||||
if (display == null) {
|
||||
display = Display.VALUE;
|
||||
}
|
||||
return display;
|
||||
}
|
||||
|
||||
public void setDisplay(Display display) {
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
@@ -316,14 +330,15 @@ public class DIL_IC extends AbstractTransparentComponent<String> {
|
||||
}
|
||||
g2d.setColor(finalLabelColor);
|
||||
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
|
||||
Rectangle2D rect = fontMetrics.getStringBounds(getName(), g2d);
|
||||
String label = display == Display.NAME ? getName() : getValue();
|
||||
Rectangle2D rect = fontMetrics.getStringBounds(label, g2d);
|
||||
int textHeight = (int) (rect.getHeight());
|
||||
int textWidth = (int) (rect.getWidth());
|
||||
// Center text horizontally and vertically
|
||||
Rectangle bounds = mainArea.getBounds();
|
||||
int x = bounds.x + (bounds.width - textWidth) / 2;
|
||||
int y = bounds.y + (bounds.height - textHeight) / 2 + fontMetrics.getAscent();
|
||||
g2d.drawString(getName(), x, y);
|
||||
g2d.drawString(label, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
public enum FETPolarity {
|
||||
|
||||
NEGATIVE, POSITIVE;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
public enum ICPointCount {
|
||||
_3("3", 3), _5("5", 5);
|
||||
|
||||
private String title;
|
||||
private int value;
|
||||
|
||||
private ICPointCount(String title, int value) {
|
||||
this.title = title;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.common.Display;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
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.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "IC Symbol", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "IC", description = "IC symbol with 3 or 5 contacts", stretchable = false, zOrder = IDIYComponent.COMPONENT)
|
||||
public class ICSymbol extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
public static Color BODY_COLOR = Color.white;
|
||||
public static Color BORDER_COLOR = Color.black;
|
||||
|
||||
protected ICPointCount icPointCount = ICPointCount._5;
|
||||
protected String value = "";
|
||||
protected Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0),
|
||||
new Point(0, 0), new Point(0, 0), new Point(0, 0) };
|
||||
protected Color bodyColor = BODY_COLOR;
|
||||
protected Color borderColor = BORDER_COLOR;
|
||||
protected Display display = Display.NAME;
|
||||
transient private Shape[] body;
|
||||
|
||||
public ICSymbol() {
|
||||
super();
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
if (checkPointsClipped(g2d.getClip())) {
|
||||
return;
|
||||
}
|
||||
int pinSpacing = (int) PIN_SPACING.convertToPixels();
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
|
||||
Shape[] body = getBody();
|
||||
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
|
||||
g2d.fill(body[0]);
|
||||
g2d.setComposite(oldComposite);
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalBorderColor = theme.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = borderColor;
|
||||
}
|
||||
g2d.setColor(finalBorderColor);
|
||||
// Draw contacts
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.draw(body[1]);
|
||||
// Draw triangle
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
||||
g2d.draw(body[0]);
|
||||
// Draw label
|
||||
g2d.setFont(LABEL_FONT);
|
||||
Color finalLabelColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalLabelColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
|
||||
: LABEL_COLOR;
|
||||
}
|
||||
g2d.setColor(finalLabelColor);
|
||||
int x = (controlPoints[0].x + controlPoints[2].x) / 2;
|
||||
drawCenteredText(g2d, display == Display.VALUE ? getValue() : getName(), x,
|
||||
controlPoints[0].y + pinSpacing, HorizontalAlignment.CENTER,
|
||||
VerticalAlignment.CENTER);
|
||||
// Draw +/- markers
|
||||
drawCenteredText(g2d, "-", controlPoints[0].x + pinSpacing, controlPoints[0].y,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
drawCenteredText(g2d, "+", controlPoints[1].x + pinSpacing, controlPoints[1].y,
|
||||
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
int margin = 3 * width / 32;
|
||||
Area area = new Area(new Polygon(new int[] { margin, margin, width - margin }, new int[] {
|
||||
margin, height - margin, height / 2 }, 3));
|
||||
// area.subtract(new Area(new Rectangle2D.Double(0, 0, 2 * margin,
|
||||
// height)));
|
||||
area.intersect(new Area(new Rectangle2D.Double(2 * margin, 0, width, height)));
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fill(area);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.setFont(LABEL_FONT.deriveFont(8f));
|
||||
drawCenteredText(g2d, "-", 3 * margin, height / 3, HorizontalAlignment.CENTER,
|
||||
VerticalAlignment.CENTER);
|
||||
drawCenteredText(g2d, "+", 3 * margin + 1, height * 2 / 3, HorizontalAlignment.CENTER,
|
||||
VerticalAlignment.CENTER);
|
||||
// g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_ROUND,
|
||||
// BasicStroke.JOIN_ROUND));
|
||||
g2d.draw(area);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return icPointCount.getValue();
|
||||
}
|
||||
|
||||
private void updateControlPoints() {
|
||||
int pinSpacing = (int) PIN_SPACING.convertToPixels();
|
||||
// Update control points.
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
|
||||
controlPoints[1].x = x;
|
||||
controlPoints[1].y = y + pinSpacing * 2;
|
||||
|
||||
controlPoints[2].x = x + pinSpacing * 6;
|
||||
controlPoints[2].y = y + pinSpacing;
|
||||
|
||||
controlPoints[3].x = x + pinSpacing * 3;
|
||||
controlPoints[3].y = y - pinSpacing;
|
||||
|
||||
controlPoints[4].x = x + pinSpacing * 3;
|
||||
controlPoints[4].y = y + pinSpacing * 3;
|
||||
}
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Shape[2];
|
||||
int pinSpacing = (int) PIN_SPACING.convertToPixels();
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
Shape triangle = new Polygon(new int[] { x + pinSpacing / 2, x + pinSpacing * 11 / 2,
|
||||
x + pinSpacing / 2 }, new int[] { y - pinSpacing * 3 / 2, y + pinSpacing,
|
||||
y + pinSpacing * 7 / 2 }, 3);
|
||||
body[0] = triangle;
|
||||
|
||||
GeneralPath polyline = new GeneralPath();
|
||||
polyline.moveTo(controlPoints[0].x, controlPoints[0].y);
|
||||
polyline.lineTo(controlPoints[0].x + pinSpacing / 2, controlPoints[0].y);
|
||||
polyline.moveTo(controlPoints[1].x, controlPoints[1].y);
|
||||
polyline.lineTo(controlPoints[1].x + pinSpacing / 2, controlPoints[1].y);
|
||||
polyline.moveTo(controlPoints[2].x, controlPoints[2].y);
|
||||
polyline.lineTo(controlPoints[2].x - pinSpacing / 2, controlPoints[2].y);
|
||||
if (icPointCount == ICPointCount._5) {
|
||||
polyline.moveTo(controlPoints[3].x, controlPoints[3].y);
|
||||
polyline.lineTo(controlPoints[3].x, controlPoints[3].y + pinSpacing * 3 / 4);
|
||||
polyline.moveTo(controlPoints[4].x, controlPoints[4].y);
|
||||
polyline.lineTo(controlPoints[4].x, controlPoints[4].y - pinSpacing * 3 / 4);
|
||||
}
|
||||
body[1] = polyline;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@Override
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Contacts")
|
||||
public ICPointCount getIcPointCount() {
|
||||
return icPointCount;
|
||||
}
|
||||
|
||||
public void setIcPointCount(ICPointCount icPointCount) {
|
||||
this.icPointCount = icPointCount;
|
||||
updateControlPoints();
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Body")
|
||||
public Color getBodyColor() {
|
||||
return bodyColor;
|
||||
}
|
||||
|
||||
public void setBodyColor(Color bodyColor) {
|
||||
this.bodyColor = bodyColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Border")
|
||||
public Color getBorderColor() {
|
||||
return borderColor;
|
||||
}
|
||||
|
||||
public void setBorderColor(Color borderColor) {
|
||||
this.borderColor = borderColor;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Display getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public void setDisplay(Display display) {
|
||||
this.display = display;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.GeneralPath;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
@ComponentDescriptor(name = "JFET Symbol", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "JFET transistor schematic symbol", stretchable = false, zOrder = IDIYComponent.COMPONENT)
|
||||
public class JFETSymbol extends AbstractTransistorSymbol {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected FETPolarity polarity = FETPolarity.NEGATIVE;
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Shape[3];
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
int pinSpacing = (int) PIN_SPACING.convertToPixels();
|
||||
|
||||
GeneralPath polyline = new GeneralPath();
|
||||
|
||||
polyline.moveTo(x + pinSpacing, y - pinSpacing);
|
||||
polyline.lineTo(x + pinSpacing, y + pinSpacing);
|
||||
|
||||
body[0] = polyline;
|
||||
|
||||
polyline = new GeneralPath();
|
||||
|
||||
polyline.moveTo(x, y);
|
||||
polyline.lineTo(x + pinSpacing, y);
|
||||
polyline.moveTo(x + pinSpacing, y - pinSpacing * 7 / 8);
|
||||
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing * 7 / 8);
|
||||
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing * 2);
|
||||
polyline.moveTo(x + pinSpacing, y + pinSpacing * 7 / 8);
|
||||
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing * 7 / 8);
|
||||
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing * 2);
|
||||
body[1] = polyline;
|
||||
|
||||
Polygon arrow;
|
||||
if (polarity == FETPolarity.NEGATIVE) {
|
||||
arrow = new Polygon(new int[] { x + pinSpacing * 2 / 6, x + pinSpacing * 2 / 6,
|
||||
x + pinSpacing * 6 / 6 }, new int[] { y - pinSpacing / 5,
|
||||
y + pinSpacing / 5, y }, 3);
|
||||
} else {
|
||||
arrow = new Polygon(new int[] { x + pinSpacing / 6, x + pinSpacing * 5 / 6,
|
||||
x + pinSpacing * 5 / 6 }, new int[] { y, y + pinSpacing / 5,
|
||||
y - pinSpacing / 5 }, 3);
|
||||
}
|
||||
body[2] = arrow;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setColor(COLOR);
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
||||
g2d.drawLine(width / 2, height / 5, width / 2, height * 4 / 5);
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.drawLine(width / 5, height / 2, width / 2, height / 2);
|
||||
|
||||
g2d.drawLine(width * 3 / 4, 1, width * 3 / 4, height / 4);
|
||||
g2d.drawLine(width / 2, height / 4, width * 3 / 4, height / 4);
|
||||
|
||||
g2d.drawLine(width * 3 / 4, height - 1, width * 3 / 4, height * 3 / 4);
|
||||
g2d.drawLine(width / 2, height * 3 / 4, width * 3 / 4, height * 3 / 4);
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Channel")
|
||||
public FETPolarity getPolarity() {
|
||||
return polarity;
|
||||
}
|
||||
|
||||
public void setPolarity(FETPolarity polarity) {
|
||||
this.polarity = polarity;
|
||||
// Invalidate body
|
||||
body = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package org.diylc.components.semiconductors;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.GeneralPath;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
@ComponentDescriptor(name = "MOSFET Symbol", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "MOSFET transistor schematic symbol", stretchable = false, zOrder = IDIYComponent.COMPONENT)
|
||||
public class MOSFETSymbol extends AbstractTransistorSymbol {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected FETPolarity polarity = FETPolarity.NEGATIVE;
|
||||
|
||||
public Shape[] getBody() {
|
||||
if (body == null) {
|
||||
body = new Shape[3];
|
||||
int x = controlPoints[0].x;
|
||||
int y = controlPoints[0].y;
|
||||
int pinSpacing = (int) PIN_SPACING.convertToPixels();
|
||||
|
||||
GeneralPath polyline = new GeneralPath();
|
||||
|
||||
polyline.moveTo(x + pinSpacing / 2, y - pinSpacing + 1);
|
||||
polyline.lineTo(x + pinSpacing / 2, y + pinSpacing - 1);
|
||||
polyline.moveTo(x + pinSpacing, y - pinSpacing + 1);
|
||||
polyline.lineTo(x + pinSpacing, y + pinSpacing - 1);
|
||||
body[0] = polyline;
|
||||
|
||||
polyline = new GeneralPath();
|
||||
|
||||
polyline.moveTo(x + pinSpacing, y - pinSpacing);
|
||||
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing);
|
||||
polyline.moveTo(x + pinSpacing, y + pinSpacing);
|
||||
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing);
|
||||
polyline.moveTo(x, y);
|
||||
polyline.lineTo(x + pinSpacing / 2, y);
|
||||
polyline.moveTo(x + pinSpacing * 2, y - pinSpacing * 2);
|
||||
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing);
|
||||
polyline.moveTo(x + pinSpacing * 2, y + pinSpacing * 2);
|
||||
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing);
|
||||
body[1] = polyline;
|
||||
|
||||
Polygon arrow;
|
||||
if (polarity == FETPolarity.NEGATIVE) {
|
||||
arrow = new Polygon(new int[] { x + pinSpacing * 8 / 6, x + pinSpacing * 8 / 6,
|
||||
x + pinSpacing * 12 / 6 }, new int[] { y + pinSpacing * 6 / 5,
|
||||
y + pinSpacing * 4 / 5, y + pinSpacing }, 3);
|
||||
} else {
|
||||
arrow = new Polygon(new int[] { x + pinSpacing * 7 / 6, x + pinSpacing * 11 / 6,
|
||||
x + pinSpacing * 11 / 6 }, new int[] { y - pinSpacing,
|
||||
y - pinSpacing * 6 / 5, y - pinSpacing * 4 / 5 }, 3);
|
||||
}
|
||||
body[2] = arrow;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setColor(COLOR);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
||||
g2d.drawLine(width * 2 / 5, height / 4 + 1, width * 2 / 5, height * 3 / 4 - 1);
|
||||
g2d.drawLine(width * 3 / 5, height / 4 + 1, width * 3 / 5, height * 3 / 4 - 1);
|
||||
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.drawLine(width / 5, height / 2, width * 2 / 5, height / 2);
|
||||
|
||||
g2d.drawLine(width * 4 / 5, 1, width * 4 / 5, height / 4);
|
||||
g2d.drawLine(width * 4 / 5, height / 4, width * 3 / 5, height / 4);
|
||||
|
||||
g2d.drawLine(width * 4 / 5, height - 1, width * 4 / 5, height * 3 / 4);
|
||||
g2d.drawLine(width * 4 / 5, height * 3 / 4, width * 3 / 5, height * 3 / 4);
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Channel")
|
||||
public FETPolarity getPolarity() {
|
||||
return polarity;
|
||||
}
|
||||
|
||||
public void setPolarity(FETPolarity polarity) {
|
||||
this.polarity = polarity;
|
||||
// Invalidate body
|
||||
body = null;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -24,7 +24,7 @@ import org.diylc.swing.gui.TemplateDialog;
|
||||
*/
|
||||
public class DIYLCStarter {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(Presenter.class);
|
||||
private static final Logger LOG = Logger.getLogger(DIYLCStarter.class);
|
||||
|
||||
/**
|
||||
* @param args
|
||||
@@ -38,8 +38,10 @@ public class DIYLCStarter {
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not initialize log4j configuration", e);
|
||||
}
|
||||
|
||||
LOG.debug("Java version: " + System.getProperty("java.runtime.version") + " by " + System.getProperty("java.vm.vendor"));
|
||||
|
||||
LOG.debug("Java version: " + System.getProperty("java.runtime.version") + " by "
|
||||
+ System.getProperty("java.vm.vendor"));
|
||||
LOG.debug("OS: " + System.getProperty("os.name") + " " + System.getProperty("os.version"));
|
||||
|
||||
LOG.info("Starting DIYLC with working directory " + System.getProperty("user.dir"));
|
||||
|
||||
|
||||
@@ -31,7 +31,8 @@ public enum IconLoader {
|
||||
"donate.png"), Bug("bug.png"), IconLarge("icon_large.png"), IconMedium(
|
||||
"icon_medium.png"), IconSmall("icon_small.png"), DocumentEdit("document_edit.png"), EditComponent(
|
||||
"edit_component.png"), Size("size.png"), Front("front.png"), Back("back.png"), Pens(
|
||||
"pens.png"), Sort("sort.png"), ElementsSelection("elements_selection.png");
|
||||
"pens.png"), Sort("sort.png"), ElementsSelection("elements_selection.png"), BranchAdd(
|
||||
"branch_add.png");
|
||||
|
||||
protected String name;
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 867 B |
@@ -16,6 +16,7 @@ import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ITask;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.ExpansionMode;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IView;
|
||||
import org.diylc.core.Theme;
|
||||
@@ -128,6 +129,11 @@ public class ActionFactory {
|
||||
return new DeleteSelectionAction(plugInPort);
|
||||
}
|
||||
|
||||
public ExpandSelectionAction createExpandSelectionAction(IPlugInPort plugInPort,
|
||||
ExpansionMode expansionMode) {
|
||||
return new ExpandSelectionAction(plugInPort, expansionMode);
|
||||
}
|
||||
|
||||
public SendToBackAction createSendToBackAction(IPlugInPort plugInPort) {
|
||||
return new SendToBackAction(plugInPort);
|
||||
}
|
||||
@@ -142,11 +148,11 @@ public class ActionFactory {
|
||||
boolean defaultValue) {
|
||||
return new ConfigAction(plugInPort, title, configKey, defaultValue);
|
||||
}
|
||||
|
||||
|
||||
public ThemeAction createThemeAction(IPlugInPort plugInPort, Theme theme) {
|
||||
return new ThemeAction(plugInPort, theme);
|
||||
}
|
||||
|
||||
|
||||
public RenumberAction createRenumberAction(IPlugInPort plugInPort, boolean xAxisFirst) {
|
||||
return new RenumberAction(plugInPort, xAxisFirst);
|
||||
}
|
||||
@@ -756,6 +762,40 @@ public class ActionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExpandSelectionAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private ExpansionMode expansionMode;
|
||||
|
||||
public ExpandSelectionAction(IPlugInPort plugInPort, ExpansionMode expansionMode) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.expansionMode = expansionMode;
|
||||
switch (expansionMode) {
|
||||
case ALL:
|
||||
putValue(AbstractAction.NAME, "All Connected");
|
||||
break;
|
||||
case IMMEDIATE:
|
||||
putValue(AbstractAction.NAME, "Immediate Only");
|
||||
break;
|
||||
case SAME_TYPE:
|
||||
putValue(AbstractAction.NAME, "Same Type Only");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LOG.info("Expand Selection triggered: " + expansionMode);
|
||||
plugInPort.expandSelection(expansionMode);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SendToBackAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -846,7 +886,7 @@ public class ActionFactory {
|
||||
plugInPort.setSelectedTheme(theme);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class RenumberAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.diylc.common.BadPositionException;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.ExpansionMode;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
@@ -49,6 +50,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
||||
private CanvasPanel canvasPanel;
|
||||
private JPopupMenu popupMenu;
|
||||
private JMenu selectionMenu;
|
||||
private JMenu expandMenu;
|
||||
|
||||
private ActionFactory.CutAction cutAction;
|
||||
private ActionFactory.CopyAction copyAction;
|
||||
@@ -59,6 +61,9 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
||||
private ActionFactory.UngroupAction ungroupAction;
|
||||
private ActionFactory.SendToBackAction sendToBackAction;
|
||||
private ActionFactory.BringToFrontAction bringToFrontAction;
|
||||
private ActionFactory.ExpandSelectionAction expandSelectionAllAction;
|
||||
private ActionFactory.ExpandSelectionAction expandSelectionImmediateAction;
|
||||
private ActionFactory.ExpandSelectionAction expandSelectionSameTypeAction;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private ISwingUI swingUI;
|
||||
@@ -104,6 +109,9 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
||||
}
|
||||
getEditSelectionAction().setEnabled(enabled);
|
||||
getDeleteSelectionAction().setEnabled(enabled);
|
||||
getExpandSelectionAllAction().setEnabled(enabled);
|
||||
getExpandSelectionImmediateAction().setEnabled(enabled);
|
||||
getExpandSelectionSameTypeAction().setEnabled(enabled);
|
||||
getGroupAction().setEnabled(enabled);
|
||||
getUngroupAction().setEnabled(enabled);
|
||||
getSendToBackAction().setEnabled(enabled);
|
||||
@@ -193,6 +201,7 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
||||
popupMenu.add(getUngroupAction());
|
||||
popupMenu.add(getSendToBackAction());
|
||||
popupMenu.add(getBringToFrontAction());
|
||||
popupMenu.add(getExpandMenu());
|
||||
popupMenu.addSeparator();
|
||||
popupMenu.add(ActionFactory.getInstance().createEditProjectAction(plugInPort));
|
||||
}
|
||||
@@ -207,6 +216,17 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
||||
return selectionMenu;
|
||||
}
|
||||
|
||||
public JMenu getExpandMenu() {
|
||||
if (expandMenu == null) {
|
||||
expandMenu = new JMenu("Expand Selection");
|
||||
expandMenu.setIcon(IconLoader.BranchAdd.getIcon());
|
||||
expandMenu.add(getExpandSelectionAllAction());
|
||||
expandMenu.add(getExpandSelectionImmediateAction());
|
||||
expandMenu.add(getExpandSelectionSameTypeAction());
|
||||
}
|
||||
return expandMenu;
|
||||
}
|
||||
|
||||
private void updateSelectionMenu(int x, int y) {
|
||||
getSelectionMenu().removeAll();
|
||||
for (IDIYComponent<?> component : plugInPort.findComponentsAt(new Point(x, y))) {
|
||||
@@ -290,6 +310,30 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
|
||||
return bringToFrontAction;
|
||||
}
|
||||
|
||||
public ActionFactory.ExpandSelectionAction getExpandSelectionAllAction() {
|
||||
if (expandSelectionAllAction == null) {
|
||||
expandSelectionAllAction = ActionFactory.getInstance().createExpandSelectionAction(
|
||||
plugInPort, ExpansionMode.ALL);
|
||||
}
|
||||
return expandSelectionAllAction;
|
||||
}
|
||||
|
||||
public ActionFactory.ExpandSelectionAction getExpandSelectionImmediateAction() {
|
||||
if (expandSelectionImmediateAction == null) {
|
||||
expandSelectionImmediateAction = ActionFactory.getInstance()
|
||||
.createExpandSelectionAction(plugInPort, ExpansionMode.IMMEDIATE);
|
||||
}
|
||||
return expandSelectionImmediateAction;
|
||||
}
|
||||
|
||||
public ActionFactory.ExpandSelectionAction getExpandSelectionSameTypeAction() {
|
||||
if (expandSelectionSameTypeAction == null) {
|
||||
expandSelectionSameTypeAction = ActionFactory.getInstance()
|
||||
.createExpandSelectionAction(plugInPort, ExpansionMode.SAME_TYPE);
|
||||
}
|
||||
return expandSelectionSameTypeAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return EnumSet.of(EventType.PROJECT_LOADED, EventType.ZOOM_CHANGED, EventType.REPAINT);
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.diylc.appframework.undo.UndoHandler;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.ExpansionMode;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.swing.ActionFactory;
|
||||
@@ -22,6 +23,7 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
||||
|
||||
private static final String EDIT_TITLE = "Edit";
|
||||
private static final String RENUMBER_TITLE = "Renumber Selection";
|
||||
private static final String EXPAND_TITLE = "Expand Selection";
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private ISwingUI swingUI;
|
||||
@@ -39,6 +41,9 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
||||
private ActionFactory.BringToFrontAction bringToFrontAction;
|
||||
private ActionFactory.RenumberAction renumberXAxisAction;
|
||||
private ActionFactory.RenumberAction renumberYAxisAction;
|
||||
private ActionFactory.ExpandSelectionAction expandSelectionAllAction;
|
||||
private ActionFactory.ExpandSelectionAction expandSelectionImmediateAction;
|
||||
private ActionFactory.ExpandSelectionAction expandSelectionSameTypeAction;
|
||||
|
||||
private UndoHandler<Project> undoHandler;
|
||||
|
||||
@@ -149,6 +154,30 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
||||
return renumberYAxisAction;
|
||||
}
|
||||
|
||||
public ActionFactory.ExpandSelectionAction getExpandSelectionAllAction() {
|
||||
if (expandSelectionAllAction == null) {
|
||||
expandSelectionAllAction = ActionFactory.getInstance().createExpandSelectionAction(
|
||||
plugInPort, ExpansionMode.ALL);
|
||||
}
|
||||
return expandSelectionAllAction;
|
||||
}
|
||||
|
||||
public ActionFactory.ExpandSelectionAction getExpandSelectionImmediateAction() {
|
||||
if (expandSelectionImmediateAction == null) {
|
||||
expandSelectionImmediateAction = ActionFactory.getInstance().createExpandSelectionAction(
|
||||
plugInPort, ExpansionMode.IMMEDIATE);
|
||||
}
|
||||
return expandSelectionImmediateAction;
|
||||
}
|
||||
|
||||
public ActionFactory.ExpandSelectionAction getExpandSelectionSameTypeAction() {
|
||||
if (expandSelectionSameTypeAction == null) {
|
||||
expandSelectionSameTypeAction = ActionFactory.getInstance().createExpandSelectionAction(
|
||||
plugInPort, ExpansionMode.SAME_TYPE);
|
||||
}
|
||||
return expandSelectionSameTypeAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
@@ -173,6 +202,10 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
||||
swingUI.injectSubmenu(RENUMBER_TITLE, IconLoader.Sort.getIcon(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getRenumberXAxisAction(), RENUMBER_TITLE);
|
||||
swingUI.injectMenuAction(getRenumberYAxisAction(), RENUMBER_TITLE);
|
||||
swingUI.injectSubmenu(EXPAND_TITLE, IconLoader.BranchAdd.getIcon(), EDIT_TITLE);
|
||||
swingUI.injectMenuAction(getExpandSelectionAllAction(), EXPAND_TITLE);
|
||||
swingUI.injectMenuAction(getExpandSelectionImmediateAction(), EXPAND_TITLE);
|
||||
swingUI.injectMenuAction(getExpandSelectionSameTypeAction(), EXPAND_TITLE);
|
||||
swingUI.injectMenuAction(null, EDIT_TITLE);
|
||||
swingUI.injectMenuAction(actionFactory.createEditProjectAction(plugInPort), EDIT_TITLE);
|
||||
|
||||
@@ -209,6 +242,9 @@ public class EditMenuPlugin implements IPlugIn, ClipboardOwner {
|
||||
getEditSelectionAction().setEnabled(enabled);
|
||||
getDeleteSelectionAction().setEnabled(enabled);
|
||||
getGroupAction().setEnabled(enabled);
|
||||
getExpandSelectionAllAction().setEnabled(enabled);
|
||||
getExpandSelectionImmediateAction().setEnabled(enabled);
|
||||
getExpandSelectionSameTypeAction().setEnabled(enabled);
|
||||
getUngroupAction().setEnabled(enabled);
|
||||
getSendToBackAction().setEnabled(enabled);
|
||||
getBringToFrontAction().setEnabled(enabled);
|
||||
|
||||
@@ -261,10 +261,18 @@ public class StatusBar extends JPanel implements IPlugIn {
|
||||
statusText = "<html>Drag control point(s) of " + formattedNames + "</html>";
|
||||
} else if (selectedComponentNames != null && !selectedComponentNames.isEmpty()) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(Utils.toCommaString(selectedComponentNames));
|
||||
builder.append(Utils.toCommaString(selectedComponentNames.subList(0, Math.min(20,
|
||||
selectedComponentNames.size()))));
|
||||
if (selectedComponentNames.size() > 20) {
|
||||
builder.append(" and " + (selectedComponentNames.size() - 20) + " more");
|
||||
}
|
||||
if (!stuckComponentNames.isEmpty()) {
|
||||
builder.append(" (hold <b>Ctrl</b> and drag to unstuck from ");
|
||||
builder.append(Utils.toCommaString(stuckComponentNames));
|
||||
builder.append(Utils.toCommaString(stuckComponentNames.subList(0, Math.min(5,
|
||||
stuckComponentNames.size()))));
|
||||
if (stuckComponentNames.size() > 5) {
|
||||
builder.append(" and " + (stuckComponentNames.size() - 5) + " more");
|
||||
}
|
||||
builder.append(")");
|
||||
}
|
||||
statusText = "<html>Selection: " + builder.toString() + "</html>";
|
||||
|
||||
+315
-195
@@ -1,6 +1,6 @@
|
||||
<java.util.Arrays_-ArrayList>
|
||||
<a class="com.diyfever.gui.update.Version-array">
|
||||
<com.diyfever.gui.update.Version>
|
||||
<a class="org.diylc.appframework.update.Version-array">
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
@@ -9,71 +9,71 @@
|
||||
<releaseDate>2011-01-27 21:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Copy/paste between two instances of the application</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Parsing numerical values in countries that use comma as decimal separator</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Dragging sticky points affects selectability of objects</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Click is sometimes not registered while adding a new component</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Fixed NPE when using default values</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Allow shape control points of curves to overlap</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Added DIL IC first pin indentation</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Added transparency to the potentiometer</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Reduced number of layers</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Import from v1 files can now read label and electrolytic capacitor components and trace/pad colors</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Added worker thread for longer file operation, so GUI doesn't freeze</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added right click menu on the canvas</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added "send to back" and "bring to front" options</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added label component</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added image component</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list
|
||||
</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
@@ -82,62 +82,62 @@
|
||||
<releaseDate>2011-01-30 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Curved trace does not show control points</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Potentiometer draws wrong at 180 degrees</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Reset component selection when tab is changed</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Resistor can show color bands</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Electrolytic capacitor has a new icon and new looks</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Solder pad can be square</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Added keyboard shortcuts to some menu options</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>V1 file importer can recognize hookup wire and transistors</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added support for creating and loading templates</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added TO-92 transistor</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added TO-220 transistor</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added LED</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added axial electrolytic capacitor</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
@@ -146,62 +146,62 @@
|
||||
<releaseDate>2011-02-07 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Copy/paste doesn't work for some components (potentiometer, transistor, etc)</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Resistor color codes are sometimes wrong</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Resistors can specify power handling</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Capacitors can specify voltage handling</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Fixed lead alignment issue</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Better scaling, grid lines are more precise</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved performance</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added resistor schematic symbol</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added capacitor schematic symbol</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added eyelet/turret component</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added Marshall/Trainwreck style boards</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added few types of trimmers</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Configurable rendering quality to improve speed</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
@@ -210,70 +210,70 @@
|
||||
<releaseDate>2011-02-27 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Resistor and capacitor symbols are not clickable</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Boards sometimes render holes/pads on the edge</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Download link doesn't work on Mac</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Ruler ticks don't always match with the grid</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Micro symbol doesn't get exported to PDF</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>DIL IC now has more pin options</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Send to Back/Bring to Front are more flexible and renamed to match what they do</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Auto-save project and restore if app crashes</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added support for themes</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added tube socket</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Sticky points may be turned off</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Snap to Grid may be turned off</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Auto-create solder pads</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Auto-edit mode</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Continuous component creation</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
@@ -282,34 +282,34 @@
|
||||
<releaseDate>2011-03-03 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Sometimes it's not possible to click on a component, especially when layout is large</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Curved traces and wires can have 2, 3 and 4 control points</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Switchable wheel zoom</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Automatic standing resistors, capacitors and diodes</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Vertical vero board</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Label has editable font</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
@@ -318,58 +318,58 @@
|
||||
<releaseDate>2011-08-28 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Auto-created solder pads aren't assigned with default settings and name</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Component edit dialog allows changing property values even when they are not the same. Boxes are marked yellow to designate multi-valued state.</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Component edit dialog should show mutual properties when components of different types are selected (e.g. curved trace and straight trace width)</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Ctrl+click should not clear selection when clicked on the canvas</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Increased PNG export resolution</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Auto-increment component names when copy-pasting</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Do not attempt to write auto-save files if user does not have permissions to create files</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Allow zero ohm resistors</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Outline mode that resembles PCB silkscreen</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Double click on a component button in the toolbar selects all components of that type</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Renumber selected components by X or Y axis</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Recently used components in the toolbar for easy navigation</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>1</minor>
|
||||
@@ -378,38 +378,38 @@
|
||||
<releaseDate>2012-02-01 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Selection sometimes highlights wrong component(s)</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Renumber function sometimes doesn't work as expected</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Increased PNG export resolution to 300dpi</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Select All should not include locked components</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Better lead and label rendering when lead spacing is smaller than component body</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Allow more than 32 pins for IC</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Adjustable solder pad hole size</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>2</minor>
|
||||
@@ -418,40 +418,160 @@
|
||||
<releaseDate>2012-02-19 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Select components from context menu even when they are under other components</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Ctrl+Shift toggles "Snap to Grid" option</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Perfboards can show hole coordinates</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Smarter resistor labels; try not to overlap label with color code bands</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved import from v1 file format</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Imperial ruler is divided to .1" instead of 1/4"</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Allow finer grid spacing up to 0.5mm (0.02")</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Do not hard-code voltage and power ratings</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>3</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2012-02-25 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Expand selection feature, useful for debugging</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Limit length of text in the status bar using "and X more" suffix</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>4</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2012-03-09 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>IC Symbol</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>BJT Symbol</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>MOSFET Symbol</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>JFET Symbol</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Line connector</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>IC component can display name or value</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>"Index out of bounds" exception logs when selecting components</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Loading files fails because encoding is not recognized</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Application breaks when resistance is set to 0 ohms</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>5</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2012-03-15 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Generic closed 1/4" jack</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Cliff-style closed 1/4" jack</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Ground Symbol</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>6</minor>
|
||||
<build>0</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2012-03-21 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Fonts are exported to PDF</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Plastic DC jack</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Humbucker pickup</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Single coil pickup</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
</a>
|
||||
</java.util.Arrays_-ArrayList>
|
||||
Reference in New Issue
Block a user