diff --git a/ diy-layout-creator --username bancika@gmail.com/DIYLC/library/main.jar b/ diy-layout-creator --username bancika@gmail.com/DIYLC/library/main.jar
index 1924c119..d58e1a18 100644
Binary files a/ diy-layout-creator --username bancika@gmail.com/DIYLC/library/main.jar and b/ diy-layout-creator --username bancika@gmail.com/DIYLC/library/main.jar differ
diff --git a/ diy-layout-creator --username bancika@gmail.com/DIYLC/src/org/diylc/core/measures/CapacitanceUnit.java b/ diy-layout-creator --username bancika@gmail.com/DIYLC/src/org/diylc/core/measures/CapacitanceUnit.java
index 5b26a057..83071499 100644
--- a/ diy-layout-creator --username bancika@gmail.com/DIYLC/src/org/diylc/core/measures/CapacitanceUnit.java
+++ b/ diy-layout-creator --username bancika@gmail.com/DIYLC/src/org/diylc/core/measures/CapacitanceUnit.java
@@ -2,7 +2,7 @@ package org.diylc.core.measures;
public enum CapacitanceUnit implements Unit {
- pF(1, "pF"), nF(1e3, "nF"), uF(1e6, "\u03bcF"), mF(1e9, "mF"), F(1e12, "F");
+ pF(1, "pF"), nF(1e3, "nF"), uF(1e6, "uF"), mF(1e9, "mF"), F(1e12, "F");
double factor;
String display;
diff --git a/ diy-layout-creator --username bancika@gmail.com/DIYLC/update.xml b/ diy-layout-creator --username bancika@gmail.com/DIYLC/update.xml
index fbd9b235..545e1d7d 100644
--- a/ diy-layout-creator --username bancika@gmail.com/DIYLC/update.xml
+++ b/ diy-layout-creator --username bancika@gmail.com/DIYLC/update.xml
@@ -228,6 +228,10 @@
BUG_FIX
Ruler ticks don't always match with the grid
+
+ BUG_FIX
+ Micro symbol doesn't get exported to PDF
+
IMPROVEMENT
DIL IC now has more pin options
@@ -244,6 +248,10 @@
NEW_FEATURE
Added support for themes
+
+ NEW_FEATURE
+ Added tube socket
+
NEW_FEATURE
Sticky points may be turned off
diff --git a/ diy-layout-creator --username bancika@gmail.com/Library/.classpath b/ diy-layout-creator --username bancika@gmail.com/Library/.classpath
index 0fed21e8..9f8613f1 100644
--- a/ diy-layout-creator --username bancika@gmail.com/Library/.classpath
+++ b/ diy-layout-creator --username bancika@gmail.com/Library/.classpath
@@ -4,6 +4,6 @@
-
+
diff --git a/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/misc/ProjectInformation.java b/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/misc/ProjectInformation.java
deleted file mode 100644
index eed5f6c3..00000000
--- a/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/misc/ProjectInformation.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.diylc.components.misc;
-
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.geom.Rectangle2D;
-
-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.Theme;
-import org.diylc.core.VisibilityPolicy;
-import org.diylc.core.annotations.ComponentDescriptor;
-import org.diylc.core.measures.Size;
-import org.diylc.core.measures.SizeUnit;
-
-@ComponentDescriptor(name = "Project Information", author = "Branislav Stojkovic", category = "Misc", description = "Draws a box with general project information", instanceNamePrefix = "BOM", zOrder = IDIYComponent.TEXT, stretchable = false)
-public class ProjectInformation extends AbstractComponent {
-
- public static Size DEFAULT_SIZE = new Size(10d, SizeUnit.cm);
- public static Color COLOR = Color.black;
- public static String DEFAULT_TEXT = "No components to show in the Bill of Materials";
-
- private static final long serialVersionUID = 1L;
-
- private Point point = new Point(0, 0);
-
- @Override
- public void draw(Graphics2D g2d, ComponentState componentState, Project project,
- IDrawingObserver drawingObserver) {
- g2d.setFont(LABEL_FONT);
- g2d.setColor(componentState == ComponentState.DRAGGING
- || componentState == ComponentState.SELECTED ? SELECTION_COLOR : COLOR);
- // FontMetrics fontMetrics = g2d.getFontMetrics();
- g2d.drawString(project.getTitle(), point.x, point.y);
- }
-
- @Override
- public void drawIcon(Graphics2D g2d, int width, int height) {
- g2d.setColor(Color.white);
- g2d.fillRect(width / 8, 0, 6 * width / 8, height - 1);
- g2d.setColor(Color.black);
- g2d.drawRect(width / 8, 0, 6 * width / 8, height - 1);
- g2d.setFont(LABEL_FONT.deriveFont(1f * 9 * width / 32).deriveFont(Font.PLAIN));
-
- FontMetrics fontMetrics = g2d.getFontMetrics();
- Rectangle2D rect = fontMetrics.getStringBounds("BOM", g2d);
-
- int textHeight = (int) (rect.getHeight());
- int textWidth = (int) (rect.getWidth());
-
- // Center text horizontally and vertically.
- int x = (width - textWidth) / 2 + 1;
- int y = textHeight + 2;
-
- g2d.drawString("BOM", x, y);
-
- g2d.setFont(g2d.getFont().deriveFont(1f * 5 * width / 32));
-
- fontMetrics = g2d.getFontMetrics();
- rect = fontMetrics.getStringBounds("resistors", g2d);
- x = (width - textWidth) / 2 + 1;
- y = height / 2 + 2;
- g2d.drawString("resistors", x, y);
- y += rect.getHeight() - 1;
- g2d.drawString("tubes", x, y);
- y += rect.getHeight() - 1;
- g2d.drawString("diodes", x, y);
- }
-
- @Override
- public int getControlPointCount() {
- return 1;
- }
-
- @Override
- public Point getControlPoint(int index) {
- return point;
- }
-
- @Override
- public boolean isControlPointSticky(int index) {
- return false;
- }
-
- @Override
- public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
- return VisibilityPolicy.NEVER;
- }
-
- @Override
- public void setControlPoint(Point point, int index) {
- this.point.setLocation(point);
- }
-
- @Override
- public Void getValue() {
- return null;
- }
-
- @Override
- public void setValue(Void value) {
- }
-}
diff --git a/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/passive/TrimmerPotentiometer.java b/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/passive/TrimmerPotentiometer.java
index e103a3b0..8b03bc26 100644
--- a/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/passive/TrimmerPotentiometer.java
+++ b/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/passive/TrimmerPotentiometer.java
@@ -19,7 +19,6 @@ import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
-import org.diylc.core.Theme;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
diff --git a/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/semiconductors/DIL_IC.java b/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/semiconductors/DIL_IC.java
index af7f16a4..d2cd4bb9 100644
--- a/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/semiconductors/DIL_IC.java
+++ b/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/semiconductors/DIL_IC.java
@@ -19,7 +19,6 @@ 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;
@@ -57,7 +56,7 @@ public class DIL_IC extends AbstractTransparentComponent {
// pinSpacing.convertToPixels()),
// new Point(3 * pinSpacing.convertToPixels(), 3 *
// pinSpacing.convertToPixels()) };
- transient private Area body[];
+ transient private Area[] body;
public DIL_IC() {
super();
@@ -80,7 +79,8 @@ public class DIL_IC extends AbstractTransparentComponent {
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
- // Reset body shape;
+ updateControlPoints();
+ // Reset body shape.
body = null;
}
diff --git a/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/tube/TubeSocket.java b/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/tube/TubeSocket.java
new file mode 100644
index 00000000..127f1588
--- /dev/null
+++ b/ diy-layout-creator --username bancika@gmail.com/Library/src/org/diylc/components/tube/TubeSocket.java
@@ -0,0 +1,309 @@
+package org.diylc.components.tube;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Shape;
+import java.awt.geom.Area;
+import java.awt.geom.Ellipse2D;
+
+import org.diylc.common.ObjectCache;
+import org.diylc.common.Orientation;
+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.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 = "Tube Socket", author = "Branislav Stojkovic", category = "Tubes", instanceNamePrefix = "V", description = "Various types of tube/valve sockets", stretchable = false, zOrder = IDIYComponent.COMPONENT)
+public class TubeSocket extends AbstractTransparentComponent {
+
+ private static final long serialVersionUID = 1L;
+
+ private static Color BODY_COLOR = Color.decode("#FFFFE0");
+ private static Color BORDER_COLOR = Color.decode("#8E8E38");
+ public static Color PIN_COLOR = Color.decode("#00B2EE");
+ public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
+ public static Size PIN_SIZE = new Size(1d, SizeUnit.mm);
+ public static Size HOLE_SIZE = new Size(5d, SizeUnit.mm);
+ public static Size TICK_SIZE = new Size(2d, SizeUnit.mm);
+
+ private Base base = Base.B9A;
+ private String type = "";
+ private Orientation orientation = Orientation.DEFAULT;
+ // private Mount mount = Mount.CHASSIS;
+
+ private Point[] controlPoints = new Point[] { new Point(0, 0) };
+
+ transient private Shape body;
+
+ public TubeSocket() {
+ super();
+ updateControlPoints();
+ }
+
+ @EditableProperty
+ public Base getBase() {
+ return base;
+ }
+
+ public void setBase(Base base) {
+ this.base = base;
+ updateControlPoints();
+ // Reset body shape
+ body = null;
+ }
+
+ @EditableProperty
+ public Orientation getOrientation() {
+ return orientation;
+ }
+
+ public void setOrientation(Orientation orientation) {
+ this.orientation = orientation;
+ updateControlPoints();
+ // Reset body shape
+ body = null;
+ }
+
+ // @EditableProperty
+ // public Mount getMount() {
+ // return mount;
+ // }
+ //
+ // public void setMount(Mount mount) {
+ // this.mount = mount;
+ // }
+
+ private void updateControlPoints() {
+ Point firstPoint = controlPoints[0];
+ int pinCount;
+ int pinCircleDiameter;
+ boolean hasEmptySpace;
+ switch (base) {
+ case B7G:
+ pinCount = 7;
+ pinCircleDiameter = getClosestOdd(new Size(12d, SizeUnit.mm).convertToPixels());
+ hasEmptySpace = true;
+ break;
+ case OCTAL:
+ pinCount = 8;
+ pinCircleDiameter = getClosestOdd(new Size(17.5d, SizeUnit.mm).convertToPixels());
+ hasEmptySpace = false;
+ break;
+ case B9A:
+ pinCount = 9;
+ pinCircleDiameter = getClosestOdd(new Size(14d, SizeUnit.mm).convertToPixels());
+ hasEmptySpace = true;
+ break;
+ default:
+ throw new RuntimeException("Unexpected base: " + base);
+ }
+ double angleIncrement = Math.PI * 2 / (hasEmptySpace ? (pinCount + 1) : pinCount);
+ double initialAngleOffset = hasEmptySpace ? angleIncrement : (angleIncrement / 2);
+ double initialAngle;
+ switch (orientation) {
+ case DEFAULT:
+ initialAngle = Math.PI / 2 + initialAngleOffset;
+ break;
+ case _90:
+ initialAngle = Math.PI + initialAngleOffset;
+ break;
+ case _180:
+ initialAngle = 3 * Math.PI / 2 + initialAngleOffset;
+ break;
+ case _270:
+ initialAngle = initialAngleOffset;
+ break;
+ default:
+ throw new RuntimeException("Unexpected orientation: " + orientation);
+ }
+ controlPoints = new Point[pinCount + 1];
+ double angle = initialAngle;
+ controlPoints[0] = firstPoint;
+ for (int i = 0; i < pinCount; i++) {
+ controlPoints[i + 1] = new Point((int) (firstPoint.getX() + Math.cos(angle)
+ * pinCircleDiameter / 2), (int) (firstPoint.getY() + Math.sin(angle)
+ * pinCircleDiameter / 2));
+ angle += angleIncrement;
+ }
+ }
+
+ public Shape getBody() {
+ if (body == null) {
+ int bodyDiameter;
+ switch (base) {
+ case B7G:
+ bodyDiameter = getClosestOdd(new Size(17d, SizeUnit.mm).convertToPixels());
+ break;
+ case B9A:
+ bodyDiameter = getClosestOdd(new Size(19d, SizeUnit.mm).convertToPixels());
+ break;
+ case OCTAL:
+ bodyDiameter = getClosestOdd(new Size(24.5d, SizeUnit.mm).convertToPixels());
+ break;
+ default:
+ throw new RuntimeException("Unexpected base: " + base);
+ }
+ body = new Ellipse2D.Double(controlPoints[0].x - bodyDiameter / 2, controlPoints[0].y
+ - bodyDiameter / 2, bodyDiameter, bodyDiameter);
+ Area bodyArea = new Area(body);
+ int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
+ bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].x - holeSize / 2,
+ controlPoints[0].y - holeSize / 2, holeSize, holeSize)));
+ if (base == Base.OCTAL) {
+ int tickSize = getClosestOdd(TICK_SIZE.convertToPixels());
+ double angle = 0;
+ switch (orientation) {
+ case DEFAULT:
+ angle = Math.PI / 2;
+ break;
+ case _90:
+ angle = Math.PI;
+ break;
+ case _180:
+ angle = 3 * Math.PI / 2;
+ break;
+ case _270:
+ angle = 0;
+ break;
+ }
+ int centerX = (int) (controlPoints[0].x + Math.cos(angle) * holeSize / 2);
+ int centerY = (int) (controlPoints[0].y + Math.sin(angle) * holeSize / 2);
+ bodyArea.subtract(new Area(new Ellipse2D.Double(centerX - tickSize / 2, centerY
+ - tickSize / 2, tickSize, tickSize)));
+ }
+ body = bodyArea;
+ }
+ return body;
+ }
+
+ @Override
+ public void draw(Graphics2D g2d, ComponentState componentState, Project project,
+ IDrawingObserver drawingObserver) {
+ // g2d.setColor(Color.black);
+ g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
+ // for (int i = 0; i < controlPoints.length; i++) {
+ // g2d.drawString(Integer.toString(i), controlPoints[i].x,
+ // controlPoints[i].y);
+ // }
+ // Draw body
+ Shape body = getBody();
+ Composite oldComposite = g2d.getComposite();
+ if (alpha < MAX_ALPHA) {
+ g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
+ / MAX_ALPHA));
+ }
+ g2d.setColor(BODY_COLOR);
+ g2d.fill(body);
+ g2d.setComposite(oldComposite);
+ g2d.setColor(componentState == ComponentState.SELECTED
+ || componentState == ComponentState.DRAGGING ? SELECTION_COLOR : BORDER_COLOR);
+ g2d.draw(body);
+ // Draw pins
+ int pinSize = getClosestOdd(PIN_SIZE.convertToPixels());
+ for (int i = 1; i < controlPoints.length; i++) {
+ g2d.setColor(PIN_COLOR);
+ g2d.fillOval(controlPoints[i].x - pinSize / 2, controlPoints[i].y - pinSize / 2,
+ pinSize, pinSize);
+ g2d.setColor(PIN_BORDER_COLOR);
+ g2d.drawOval(controlPoints[i].x - pinSize / 2, controlPoints[i].y - pinSize / 2,
+ pinSize, pinSize);
+ }
+ }
+
+ @Override
+ public void drawIcon(Graphics2D g2d, int width, int height) {
+ Area area = new Area(new Ellipse2D.Double(1, 1, width - 2, width - 2));
+ int center = width / 2;
+ area.subtract(new Area(new Ellipse2D.Double(center - 2, center - 2, 5, 5)));
+ g2d.setColor(BODY_COLOR);
+ g2d.fill(area);
+ g2d.setColor(BORDER_COLOR);
+ g2d.draw(area);
+
+ int radius = width / 2 - 6;
+ for (int i = 0; i < 8; i++) {
+ int x = (int) (center + Math.cos(i * Math.PI / 4) * radius);
+ int y = (int) (center + Math.sin(i * Math.PI / 4) * radius);
+ g2d.setColor(PIN_COLOR);
+ g2d.fillOval(x - 1, y - 1, 3, 3);
+ g2d.setColor(PIN_BORDER_COLOR);
+ g2d.drawOval(x - 1, y - 1, 3, 3);
+ }
+ }
+
+ @Override
+ public Point getControlPoint(int index) {
+ return controlPoints[index];
+ }
+
+ @Override
+ public int getControlPointCount() {
+ return controlPoints.length;
+ }
+
+ @Override
+ public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
+ return VisibilityPolicy.NEVER;
+ }
+
+ @Override
+ @EditableProperty(name = "Type")
+ public String getValue() {
+ return type;
+ }
+
+ @Override
+ public void setValue(String value) {
+ this.type = value;
+ }
+
+ @Override
+ public boolean isControlPointSticky(int index) {
+ return index > 0;
+ }
+
+ @Override
+ public void setControlPoint(Point point, int index) {
+ controlPoints[index].setLocation(point);
+ body = null;
+ }
+
+ static enum Base {
+ B9A("Noval B9A"), OCTAL("Octal"), B7G("Small-button B7G");
+
+ String name;
+
+ private Base(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ static enum Mount {
+ CHASSIS("Chassis"), PCB("PCB");
+
+ String name;
+
+ private Mount(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+}