move folders

This commit is contained in:
Branislav Stojkovic
2016-10-23 17:29:23 +02:00
parent 5ec0616a1e
commit 0610229157
487 changed files with 0 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="lib/app-framework.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/diylc-core"/>
<classpathentry kind="lib" path="lib/xstream-1.4.3.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.6.0_45"/>
<classpathentry kind="output" path="bin"/>
</classpath>
+3
View File
@@ -0,0 +1,3 @@
/bin/
/build/
/lib/diylc-core.jar
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>diylc-library</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
+67
View File
@@ -0,0 +1,67 @@
<project name="main" basedir="." default="jar">
<property name="src.dir" value="src" />
<property name="lib.dir" value="${basedir}/lib" />
<property name="build.dir" value="${basedir}/build" />
<property name="jar.dir" value="${build.dir}/jar" />
<property name="report.dir" value="${build.dir}/junitreport" />
<property name="classes.dir" value="${build.dir}/temp/${ant.project.name}/classes" />
<property name="test.classes.dir" value="${build.dir}/temp/${ant.project.name}/test.classes" />
<target name="clean">
<delete dir="${build.dir}" />
</target>
<target name="compile">
<ant antfile="../diylc-core/build.xml" target="jar" inheritAll="false"/>
<mkdir dir="${classes.dir}" />
<echo>Compile with JDK ${java.runtime.version}</echo>
<javac encoding="8859_1" srcdir="${basedir}/${src.dir}" destdir="${classes.dir}" classpathref="class.path" debug="true" />
</target>
<target name="resource.copy">
<copy todir="${classes.dir}">
<fileset dir="${src.dir}">
<exclude name="**/*.java" />
</fileset>
</copy>
</target>
<target name="lib.copy">
<copy todir="${jar.dir}/lib" overwrite="true">
<fileset dir="${basedir}/lib">
<exclude name="**/*dll" />
</fileset>
</copy>
<copy todir="${jar.dir}" overwrite="true">
<fileset dir="${basedir}/lib/" includes="**/*.dll" />
</copy>
</target>
<path id="class.path">
<fileset dir="${basedir}">
<include name="lib/**/*.jar" />
</fileset>
</path>
<target name="jar" depends="clean, lib.copy, resource.copy, compile">
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}" />
<copy todir="../diylc-swing/library" overwrite="true">
<fileset dir="${jar.dir}" includes="${ant.project.name}.jar" />
</copy>
<copy todir="../diylc-core/library" overwrite="true">
<fileset dir="${jar.dir}" includes="${ant.project.name}.jar" />
</copy>
</target>
<target name="javadoc">
<javadoc access="public" author="true" classpathref="class.path" destdir="doc" nodeprecated="false" nodeprecatedlist="false" noindex="false" nonavbar="false" notree="false" source="1.6" splitindex="true" use="true" version="true">
<fileset dir="${src.dir}">
<exclude name="**\.svn\**" />
<include name="**/*.java" />
</fileset>
</javadoc>
</target>
</project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,179 @@
package org.diylc.components.boards;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
public abstract class AbstractBoard extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
public static Color BOARD_COLOR = Color.decode("#F8EBB3");
public static Color BORDER_COLOR = BOARD_COLOR.darker();
public static Color COORDINATE_COLOR = Color.gray.brighter();
public static float COORDINATE_FONT_SIZE = 9f;
public static Size DEFAULT_WIDTH = new Size(1.5d, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(1.2d, SizeUnit.in);
protected String value = "";
protected Point[] controlPoints = new Point[] {new Point(0, 0),
new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels())};
protected Point firstPoint = new Point();
protected Point secondPoint = new Point();
protected Color boardColor = BOARD_COLOR;
protected Color borderColor = BORDER_COLOR;
protected Color coordinateColor = COORDINATE_COLOR;
protected Boolean drawCoordinates = true;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
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(boardColor);
g2d.fillRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);
g2d.setComposite(oldComposite);
}
// Do not track any changes that follow because the whole board has been
// tracked so far.
drawingObserver.stopTracking();
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor);
g2d.drawRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);
}
protected void drawCoordinates(Graphics2D g2d, int spacing) {
if (!getDrawCoordinates())
return;
Point p = new Point(firstPoint);
g2d.setColor(coordinateColor);
g2d.setFont(LABEL_FONT.deriveFont(COORDINATE_FONT_SIZE));
int t = 1;
while (p.y < secondPoint.y - spacing) {
p.y += spacing;
super.drawCenteredText(g2d, getCoordinateLabel(t++), p.x + 2, p.y, HorizontalAlignment.LEFT,
VerticalAlignment.CENTER);
}
p = new Point(firstPoint);
t = 1;
while (p.x < secondPoint.x - spacing) {
p.x += spacing;
super.drawCenteredText(g2d, getCoordinateLabel(t++), p.x, p.y - 2, HorizontalAlignment.CENTER,
VerticalAlignment.TOP);
}
}
private String getCoordinateLabel(int coordinate) {
String result = "";
while (coordinate > 0) {
int digit = coordinate % 26;
coordinate /= 26;
if (digit == 0) {
result = 'Z' + result;
coordinate--;
} else {
result = (char) ((int) 'A' + digit - 1) + result;
}
}
return result;
}
@EditableProperty(name = "Color")
public Color getBoardColor() {
return boardColor;
}
public void setBoardColor(Color boardColor) {
this.boardColor = boardColor;
}
@EditableProperty(name = "Coordinate Color")
public Color getCoordinateColor() {
// Null protection for older files
return coordinateColor == null ? COORDINATE_COLOR : coordinateColor;
}
public void setCoordinateColor(Color coordinateColor) {
this.coordinateColor = coordinateColor;
}
@EditableProperty(name = "Border")
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@EditableProperty(name = "Draw Coordinates")
public boolean getDrawCoordinates() {
// Null protection for older files
return drawCoordinates == null || drawCoordinates;
}
public void setDrawCoordinates(boolean drawCoordinates) {
this.drawCoordinates = drawCoordinates;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return false;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
firstPoint.setLocation(Math.min(controlPoints[0].x, controlPoints[1].x),
Math.min(controlPoints[0].y, controlPoints[1].y));
secondPoint.setLocation(Math.max(controlPoints[0].x, controlPoints[1].x),
Math.max(controlPoints[0].y, controlPoints[1].y));
}
@EditableProperty
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
}
@@ -0,0 +1,45 @@
package org.diylc.components.boards;
import java.awt.Graphics2D;
import java.awt.Shape;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
@ComponentDescriptor(name = "Blank Board", category = "Boards", author = "Branislav Stojkovic",
zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Blank circuit board",
bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false)
public class BlankBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
g2d.setColor(BOARD_COLOR);
g2d.fillRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
Shape clip = g2d.getClip();
if (checkPointsClipped(clip) && !clip.contains(firstPoint.x, secondPoint.y)
&& !clip.contains(secondPoint.x, firstPoint.y)) {
return;
}
super.draw(g2d, componentState, outlineMode, project, drawingObserver);
}
@Override
public boolean getDrawCoordinates() {
// Override to prevent editing.
return super.getDrawCoordinates();
}
}
@@ -0,0 +1,216 @@
package org.diylc.components.boards;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
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.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Breadboard", category = "Boards", author = "Branislav Stojkovic",
description = "Prototyping solderless breadboard", instanceNamePrefix = "BB", stretchable = false,
zOrder = IDIYComponent.BOARD, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false)
public class Breadboard extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L;
public static Color FILL_COLOR = Color.white;
public static Color BORDER_COLOR = Color.black;
public static Size BODY_ARC = new Size(3d, SizeUnit.mm);
public static Color SELECTION_COLOR = Color.red;
public static Color HOLE_COLOR = Color.decode("#EEEEEE");
public static Color PLUS_COLOR = Color.red;
public static Color MINUS_COLOR = Color.blue;
public static float COORDINATE_FONT_SIZE = 9f;
public static Color COORDINATE_COLOR = Color.gray.brighter();
public static Size HOLE_SIZE = new Size(1.5, SizeUnit.mm);
public static Size HOLE_ARC = new Size(1d, SizeUnit.mm);
protected Point point = new Point(0, 0);
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int bodyArc = (int) BODY_ARC.convertToPixels();
double spacing = project.getGridSpacing().convertToPixels();
// draw body
g2d.setColor(FILL_COLOR);
int width = (int) (23 * project.getGridSpacing().convertToPixels());
int height = (int) (31 * project.getGridSpacing().convertToPixels());
g2d.fillRoundRect(point.x, point.y, width, height, bodyArc, bodyArc);
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: BORDER_COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawRoundRect(point.x, point.y, width, height, bodyArc, bodyArc);
drawingObserver.stopTracking();
// draw lines
g2d.setColor(PLUS_COLOR);
g2d.drawLine((int) (point.x + spacing), (int) (point.y + spacing), (int) (point.x + spacing),
(int) (point.y + 30 * spacing));
g2d.drawLine((int) (point.x + 19 * spacing), (int) (point.y + spacing), (int) (point.x + 19 * spacing),
(int) (point.y + 30 * spacing));
g2d.setColor(MINUS_COLOR);
g2d.drawLine((int) (point.x + 4 * spacing), (int) (point.y + spacing), (int) (point.x + 4 * spacing),
(int) (point.y + 30 * spacing));
g2d.drawLine((int) (point.x + 22 * spacing), (int) (point.y + spacing), (int) (point.x + 22 * spacing),
(int) (point.y + 30 * spacing));
int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
int holeArc = (int) HOLE_ARC.convertToPixels();
g2d.setFont(LABEL_FONT.deriveFont(COORDINATE_FONT_SIZE));
byte a = "a".getBytes()[0];
// draw main holes
for (int section = 0; section <= 1; section++) {
double offset = section * 7 * spacing;
for (int y = 0; y < 30; y++) {
g2d.setColor(COORDINATE_COLOR);
int coordinateX;
if (section == 0) {
coordinateX = (int) (point.x + offset + 5.5 * spacing);
} else {
coordinateX = (int) (point.x + offset + 10.5 * spacing);
}
drawCenteredText(g2d, new Integer(y + 1).toString(), coordinateX, (int) (point.y + (y + 1) * spacing),
section == 0 ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
for (int x = 0; x < 5; x++) {
int holeX = (int) (point.x + offset + (x + 6) * spacing);
int holeY = (int) (point.y + (y + 1) * spacing);
g2d.setColor(HOLE_COLOR);
g2d.fillRoundRect(holeX - holeSize / 2, holeY - holeSize / 2, holeSize, holeSize, holeArc, holeArc);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(holeX - holeSize / 2, holeY - holeSize / 2, holeSize, holeSize, holeArc, holeArc);
// Draw horizontal labels
if (y == 0) {
g2d.setColor(COORDINATE_COLOR);
drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y),
HorizontalAlignment.CENTER, VerticalAlignment.TOP);
drawCenteredText(g2d, new String(new byte[] {(byte) (a + x + 5 * section)}), holeX, (int) (point.y
+ spacing * 30 + COORDINATE_FONT_SIZE / 2), HorizontalAlignment.CENTER, VerticalAlignment.TOP);
}
}
}
}
// draw side holes
for (int section = 0; section <= 1; section++) {
double offset = section * 18 * spacing;
for (int y = 0; y < 30; y++) {
for (int x = 0; x < 2; x++) {
if ((y + 1) % 5 == 0)
continue;
int holeX = (int) (point.x + offset + (x + 2) * spacing);
int holeY = (int) (point.y + (y + 1 + 0.5) * spacing);
g2d.setColor(HOLE_COLOR);
g2d.fillRoundRect(holeX - holeSize / 2, holeY - holeSize / 2, holeSize, holeSize, holeArc, holeArc);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(holeX - holeSize / 2, holeY - holeSize / 2, holeSize, holeSize, holeArc, holeArc);
}
}
}
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
int arc = 4 / factor;
g2d.setColor(FILL_COLOR);
g2d.fillRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(HOLE_COLOR);
g2d.fillRoundRect(width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor), arc, arc);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor), arc, arc);
g2d.setColor(HOLE_COLOR);
g2d.fillRoundRect(2 * width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor), arc, arc);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(2 * width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor), arc, arc);
g2d.setColor(HOLE_COLOR);
g2d.fillRoundRect(width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor), arc, arc);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor), arc, arc);
g2d.setColor(HOLE_COLOR);
g2d.fillRoundRect(2 * width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor), arc, arc);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(2 * width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor), arc, arc);
g2d.setColor(MINUS_COLOR);
g2d.drawLine(width / 2, 2 / factor, width / 2, height - 4 / factor);
}
@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) {}
@Deprecated
@Override
public String getName() {
return super.getName();
}
}
@@ -0,0 +1,118 @@
package org.diylc.components.boards;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
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 = "Eyelet Board", category = "Boards", author = "Branislav Stojkovic",
zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated board with eyelets",
bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false)
public class EyeletBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
public static Color BOARD_COLOR = Color.decode("#CCFFCC");
public static Color BORDER_COLOR = BOARD_COLOR.darker();
public static Color EYELET_COLOR = Color.decode("#C3E4ED");
public static Size SPACING = new Size(0.5d, SizeUnit.in);
public static Size EYELET_SIZE = new Size(0.2d, SizeUnit.in);
public static Size HOLE_SIZE = new Size(0.1d, SizeUnit.in);
// private Area copperArea;
protected Size spacing = SPACING;
protected Color eyeletColor = EYELET_COLOR;
public EyeletBoard() {
super();
this.boardColor = BOARD_COLOR;
this.borderColor = BORDER_COLOR;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
Shape clip = g2d.getClip();
if (checkPointsClipped(clip) && !clip.contains(firstPoint.x, secondPoint.y)
&& !clip.contains(secondPoint.x, firstPoint.y)) {
return;
}
super.draw(g2d, componentState, outlineMode, project, drawingObserver);
if (componentState != ComponentState.DRAGGING) {
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
Point p = new Point(firstPoint);
int diameter = getClosestOdd((int) EYELET_SIZE.convertToPixels());
int holeDiameter = getClosestOdd((int) HOLE_SIZE.convertToPixels());
int spacing = (int) this.spacing.convertToPixels();
while (p.y < secondPoint.y - spacing) {
p.x = firstPoint.x;
p.y += spacing;
while (p.x < secondPoint.x - spacing - diameter) {
p.x += spacing;
g2d.setColor(eyeletColor);
g2d.fillOval(p.x - diameter / 2, p.y - diameter / 2, diameter, diameter);
g2d.setColor(eyeletColor.darker());
g2d.drawOval(p.x - diameter / 2, p.y - diameter / 2, diameter, diameter);
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(p.x - holeDiameter / 2, p.y - holeDiameter / 2, holeDiameter, holeDiameter);
g2d.setColor(eyeletColor.darker());
g2d.drawOval(p.x - holeDiameter / 2, p.y - holeDiameter / 2, holeDiameter, holeDiameter);
}
}
super.drawCoordinates(g2d, spacing);
}
}
@EditableProperty(name = "Eyelet color")
public Color getEyeletColor() {
return eyeletColor;
}
public void setEyeletColor(Color padColor) {
this.eyeletColor = padColor;
}
@EditableProperty
public Size getSpacing() {
return spacing;
}
public void setSpacing(Size spacing) {
this.spacing = spacing;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
g2d.setColor(BOARD_COLOR);
g2d.fillRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(EYELET_COLOR);
g2d.fillOval(width / 4, width / 4, width / 2, width / 2);
g2d.setColor(EYELET_COLOR.darker());
g2d.drawOval(width / 4, width / 4, width / 2, width / 2);
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(width / 2 - 2 / factor, width / 2 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(EYELET_COLOR.darker());
g2d.drawOval(width / 2 - 2 / factor, width / 2 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
}
}
@@ -0,0 +1,119 @@
package org.diylc.components.boards;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
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 = "Marshall Style Perf Board", category = "Boards", author = "Branislav Stojkovic",
zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board",
description = "Perforated board as found on some Marshall and Trainwreck amps",
bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false)
public class MarshallPerfBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
public static Color BOARD_COLOR = Color.decode("#CD8500");
public static Color BORDER_COLOR = BOARD_COLOR.darker();
public static Size SPACING = new Size(3 / 8d, SizeUnit.in);
public static Size HOLE_SIZE = new Size(1 / 8d, SizeUnit.in);
// private Area copperArea;
protected Size spacing = SPACING;
public MarshallPerfBoard() {
super();
this.boardColor = BOARD_COLOR;
this.borderColor = BORDER_COLOR;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
Shape clip = g2d.getClip();
if (checkPointsClipped(clip) && !clip.contains(firstPoint.x, secondPoint.y)
&& !clip.contains(secondPoint.x, firstPoint.y)) {
return;
}
super.draw(g2d, componentState, outlineMode, project, drawingObserver);
if (componentState != ComponentState.DRAGGING) {
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
Point p = new Point(firstPoint);
int holeDiameter = getClosestOdd((int) HOLE_SIZE.convertToPixels());
int spacing = (int) this.spacing.convertToPixels();
while (p.y < secondPoint.y - spacing) {
p.x = firstPoint.x;
p.y += spacing;
while (p.x < secondPoint.x - spacing - holeDiameter) {
p.x += spacing;
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(p.x - holeDiameter / 2, p.y - holeDiameter / 2, holeDiameter, holeDiameter);
g2d.setColor(borderColor);
g2d.drawOval(p.x - holeDiameter / 2, p.y - holeDiameter / 2, holeDiameter, holeDiameter);
}
}
super.drawCoordinates(g2d, spacing);
}
}
@EditableProperty
public Size getSpacing() {
return spacing;
}
public void setSpacing(Size spacing) {
this.spacing = spacing;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
g2d.setColor(BOARD_COLOR);
g2d.fillRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(BORDER_COLOR);
g2d.drawOval(width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(2 * width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(BORDER_COLOR);
g2d.drawOval(2 * width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(BORDER_COLOR);
g2d.drawOval(width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(2 * width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(BORDER_COLOR);
g2d.drawOval(2 * width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
}
}
@@ -0,0 +1,110 @@
package org.diylc.components.boards;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
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 = "Perf Board w/ Pads", category = "Boards", author = "Branislav Stojkovic",
zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated board with solder pads",
bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false)
public class PerfBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
public static Color COPPER_COLOR = Color.decode("#DA8A67");
public static Size SPACING = new Size(0.1d, SizeUnit.in);
public static Size PAD_SIZE = new Size(0.08d, SizeUnit.in);
public static Size HOLE_SIZE = new Size(0.7d, SizeUnit.mm);
// private Area copperArea;
protected Size spacing = SPACING;
protected Color padColor = COPPER_COLOR;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
Shape clip = g2d.getClip();
if (checkPointsClipped(clip) && !clip.contains(firstPoint.x, secondPoint.y)
&& !clip.contains(secondPoint.x, firstPoint.y)) {
return;
}
super.draw(g2d, componentState, outlineMode, project, drawingObserver);
if (componentState != ComponentState.DRAGGING) {
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
Point p = new Point(firstPoint);
int diameter = getClosestOdd((int) PAD_SIZE.convertToPixels());
int holeDiameter = getClosestOdd((int) HOLE_SIZE.convertToPixels());
int spacing = (int) this.spacing.convertToPixels();
while (p.y < secondPoint.y - spacing) {
p.x = firstPoint.x;
p.y += spacing;
while (p.x < secondPoint.x - spacing - diameter) {
p.x += spacing;
g2d.setColor(padColor);
g2d.fillOval(p.x - diameter / 2, p.y - diameter / 2, diameter, diameter);
g2d.setColor(padColor.darker());
g2d.drawOval(p.x - diameter / 2, p.y - diameter / 2, diameter, diameter);
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(p.x - holeDiameter / 2, p.y - holeDiameter / 2, holeDiameter, holeDiameter);
g2d.setColor(padColor.darker());
g2d.drawOval(p.x - holeDiameter / 2, p.y - holeDiameter / 2, holeDiameter, holeDiameter);
}
}
super.drawCoordinates(g2d, spacing);
}
}
@EditableProperty(name = "Pad color")
public Color getPadColor() {
return padColor;
}
public void setPadColor(Color padColor) {
this.padColor = padColor;
}
@EditableProperty
public Size getSpacing() {
return spacing;
}
public void setSpacing(Size spacing) {
this.spacing = spacing;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
g2d.setColor(BOARD_COLOR);
g2d.fillRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(COPPER_COLOR);
g2d.fillOval(width / 4, width / 4, width / 2, width / 2);
g2d.setColor(COPPER_COLOR.darker());
g2d.drawOval(width / 4, width / 4, width / 2, width / 2);
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(width / 2 - 2 / factor, width / 2 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(COPPER_COLOR.darker());
g2d.drawOval(width / 2 - 2 / factor, width / 2 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
}
}
@@ -0,0 +1,210 @@
package org.diylc.components.boards;
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 org.diylc.common.OrientationHV;
import org.diylc.core.ComponentState;
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;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "TriPad Board", category = "Boards", author = "Hauke Juhls", zOrder = IDIYComponent.BOARD,
instanceNamePrefix = "Board",
description = "Perforated FR4 board with copper strips connecting 3 holes in a row (aka TriPad Board)")
public class TriPadBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
public static Color STRIP_COLOR = Color.decode("#DA8A67");
public static Color BORDER_COLOR = BOARD_COLOR.darker();
public static Size SPACING = new Size(0.1d, SizeUnit.in);
public static Size STRIP_SIZE = new Size(0.07d, SizeUnit.in);
public static Size HOLE_SIZE = new Size(0.7d, SizeUnit.mm);
protected int stripSpan = 3; // determines how many holes are covered by a
// strip
protected Size spacing = SPACING;
protected Color stripColor = STRIP_COLOR;
protected OrientationHV orientation = OrientationHV.HORIZONTAL;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
Shape clip = g2d.getClip();
if (checkPointsClipped(clip) && !clip.contains(firstPoint.x, secondPoint.y)
&& !clip.contains(secondPoint.x, firstPoint.y)) {
return;
}
super.draw(g2d, componentState, outlineMode, project, drawingObserver);
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
Point p = new Point(firstPoint);
int stripSize = getClosestOdd((int) STRIP_SIZE.convertToPixels());
int holeSize = getClosestOdd((int) HOLE_SIZE.convertToPixels());
int spacing = (int) this.spacing.convertToPixels();
if (orientation == OrientationHV.HORIZONTAL) {
while (p.y < secondPoint.y - spacing) {
p.x = firstPoint.x;
p.y += spacing;
while (p.x + spacing < secondPoint.x) {
int remainingSpace = secondPoint.x - p.x;
int spacesToDraw = stripSpan;
if (remainingSpace < (stripSize + (stripSpan * spacing))) {
spacesToDraw = (remainingSpace - stripSize) / spacing;
}
g2d.setColor(stripColor);
g2d.fillRect(p.x + spacing - stripSize / 2, p.y - stripSize / 2, spacing * (spacesToDraw - 1) + stripSize,
stripSize);
g2d.setColor(stripColor.darker());
g2d.drawRect(p.x + spacing - stripSize / 2, p.y - stripSize / 2, spacing * (spacesToDraw - 1) + stripSize,
stripSize);
p.x += spacing * spacesToDraw;
}
// draw holes
p.x = firstPoint.x;
while (p.x < secondPoint.x - spacing - holeSize) {
p.x += spacing;
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(p.x - holeSize / 2, p.y - holeSize / 2, holeSize, holeSize);
g2d.setColor(stripColor.darker());
g2d.drawOval(p.x - holeSize / 2, p.y - holeSize / 2, holeSize, holeSize);
}
}
} else {
while (p.x < secondPoint.x - spacing) {
p.x += spacing;
p.y = firstPoint.y;
while (p.y + spacing < secondPoint.y) {
int remainingSpace = secondPoint.y - p.y;
int spacesToDraw = stripSpan;
if (remainingSpace < (stripSize + (stripSpan * spacing))) {
spacesToDraw = (remainingSpace - stripSize) / spacing;
}
g2d.setColor(stripColor);
g2d.fillRect(p.x - stripSize / 2, p.y + spacing - stripSize / 2, stripSize, spacing * (spacesToDraw - 1)
+ stripSize);
g2d.setColor(stripColor.darker());
g2d.drawRect(p.x - stripSize / 2, p.y + spacing - stripSize / 2, stripSize, spacing * (spacesToDraw - 1)
+ stripSize);
p.y += spacing * spacesToDraw;
}
// draw holes
p.y = firstPoint.y;
while (p.y < secondPoint.y - spacing - holeSize) {
p.y += spacing;
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(p.x - holeSize / 2, p.y - holeSize / 2, holeSize, holeSize);
g2d.setColor(stripColor.darker());
g2d.drawOval(p.x - holeSize / 2, p.y - holeSize / 2, holeSize, holeSize);
}
}
}
g2d.setComposite(oldComposite);
}
}
@EditableProperty(name = "Strip color")
public Color getStripColor() {
return stripColor;
}
public void setStripColor(Color padColor) {
this.stripColor = padColor;
}
@EditableProperty
public Size getSpacing() {
return spacing;
}
public void setSpacing(Size spacing) {
this.spacing = spacing;
}
@EditableProperty
public OrientationHV getOrientation() {
return orientation;
}
public void setOrientation(OrientationHV orientation) {
this.orientation = orientation;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(BOARD_COLOR);
g2d.fillRect(0, 0, width, height);
final int horizontalSpacing = width / 5;
final int horizontalIndent = horizontalSpacing / 2;
final int verticalSpacing = height / 5;
final int verticalIndent = verticalSpacing / 2;
for (int row = 0; row < 5; row++) {
g2d.setColor(STRIP_COLOR);
g2d.fillRect(0, row * verticalSpacing + 2, horizontalIndent / 2 + horizontalSpacing, verticalSpacing - 1);
g2d.setColor(STRIP_COLOR);
g2d.fillRect(horizontalSpacing + 2, row * verticalSpacing + 2, horizontalSpacing * 3 - 1, verticalSpacing - 1);
g2d.fillRect(horizontalSpacing * 4 + 2, row * verticalSpacing + 2, horizontalIndent / 2 + horizontalSpacing,
verticalSpacing - 1);
}
// draw dots
for (int row = 0; row < 5; row++) {
int y = (verticalSpacing * row) + verticalIndent;
for (int col = 0; col < 5; col++) {
int x = (horizontalSpacing * col) + horizontalIndent;
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(x, y, 2, 2);
g2d.setColor(STRIP_COLOR.darker());
g2d.drawOval(x, y, 2, 2);
}
}
}
@EditableProperty(name = "Holes per strip")
public int getStripSpan() {
return stripSpan;
}
public void setStripSpan(int stripSpan) {
if (stripSpan < 1) {
this.stripSpan = 1;
} else {
this.stripSpan = stripSpan;
}
}
}
@@ -0,0 +1,147 @@
package org.diylc.components.boards;
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 org.diylc.common.OrientationHV;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
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 = "Vero Board", category = "Boards", author = "Branislav Stojkovic",
zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board",
description = "Perforated FR4 board with copper strips connecting all holes in a row",
bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false)
public class VeroBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
public static Color STRIP_COLOR = Color.decode("#DA8A67");
public static Color BORDER_COLOR = BOARD_COLOR.darker();
public static Size SPACING = new Size(0.1d, SizeUnit.in);
public static Size STRIP_SIZE = new Size(0.07d, SizeUnit.in);
public static Size HOLE_SIZE = new Size(0.7d, SizeUnit.mm);
protected Size spacing = SPACING;
protected Color stripColor = STRIP_COLOR;
protected OrientationHV orientation = OrientationHV.HORIZONTAL;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
Shape clip = g2d.getClip();
if (checkPointsClipped(clip) && !clip.contains(firstPoint.x, secondPoint.y)
&& !clip.contains(secondPoint.x, firstPoint.y)) {
return;
}
super.draw(g2d, componentState, outlineMode, project, drawingObserver);
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
Point p = new Point(firstPoint);
int stripSize = getClosestOdd((int) STRIP_SIZE.convertToPixels());
int holeSize = getClosestOdd((int) HOLE_SIZE.convertToPixels());
int spacing = (int) this.spacing.convertToPixels();
if (orientation == OrientationHV.HORIZONTAL) {
while (p.y < secondPoint.y - spacing) {
p.x = firstPoint.x;
p.y += spacing;
g2d.setColor(stripColor);
g2d.fillRect(p.x + spacing / 2, p.y - stripSize / 2, secondPoint.x - spacing - p.x, stripSize);
g2d.setColor(stripColor.darker());
g2d.drawRect(p.x + spacing / 2, p.y - stripSize / 2, secondPoint.x - spacing - p.x, stripSize);
while (p.x < secondPoint.x - spacing - holeSize) {
p.x += spacing;
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(p.x - holeSize / 2, p.y - holeSize / 2, holeSize, holeSize);
g2d.setColor(stripColor.darker());
g2d.drawOval(p.x - holeSize / 2, p.y - holeSize / 2, holeSize, holeSize);
}
}
} else {
while (p.x < secondPoint.x - spacing) {
p.x += spacing;
p.y = firstPoint.y;
g2d.setColor(stripColor);
g2d.fillRect(p.x - stripSize / 2, p.y + spacing / 2, stripSize, secondPoint.y - spacing - p.y);
g2d.setColor(stripColor.darker());
g2d.drawRect(p.x - stripSize / 2, p.y + spacing / 2, stripSize, secondPoint.y - spacing - p.y);
while (p.y < secondPoint.y - spacing - holeSize) {
p.y += spacing;
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(p.x - holeSize / 2, p.y - holeSize / 2, holeSize, holeSize);
g2d.setColor(stripColor.darker());
g2d.drawOval(p.x - holeSize / 2, p.y - holeSize / 2, holeSize, holeSize);
}
}
}
g2d.setComposite(oldComposite);
super.drawCoordinates(g2d, spacing);
}
}
@EditableProperty(name = "Strip color")
public Color getStripColor() {
return stripColor;
}
public void setStripColor(Color padColor) {
this.stripColor = padColor;
}
@EditableProperty
public Size getSpacing() {
return spacing;
}
public void setSpacing(Size spacing) {
this.spacing = spacing;
}
@EditableProperty
public OrientationHV getOrientation() {
return orientation;
}
public void setOrientation(OrientationHV orientation) {
this.orientation = orientation;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
g2d.setColor(BOARD_COLOR);
g2d.fillRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(STRIP_COLOR);
g2d.fillRect(4 / factor, width / 4, width - 8 / factor, width / 2);
g2d.setColor(STRIP_COLOR.darker());
g2d.drawRect(4 / factor, width / 4, width - 8 / factor, width / 2);
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(width / 3 - 2 / factor, width / 2 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.fillOval(2 * width / 3 - 2 / factor, width / 2 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.setColor(STRIP_COLOR.darker());
g2d.drawOval(width / 3 - 2 / factor, width / 2 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
g2d.drawOval(2 * width / 3 - 2 / factor, width / 2 - 2 / factor, getClosestOdd(5.0 / factor),
getClosestOdd(5.0 / factor));
}
}
@@ -0,0 +1,15 @@
package org.diylc.components.connectivity;
public enum AWG {
_8, _10, _12, _14, _16, _18, _20, _22, _24, _26, _28, _30;
@Override
public String toString() {
return "#" + name().replace("_", "");
}
public int getValue() {
return Integer.parseInt(name().replace("_", ""));
}
}
@@ -0,0 +1,140 @@
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.common.PCBLayer;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
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 = "Copper Trace", author = "Branislav Stojkovic", category = "Connectivity",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "Trace",
description = "Straight copper trace", zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW,
autoEdit = false)
public class CopperTrace extends AbstractLeadedComponent<Void> {
private static final long serialVersionUID = 1L;
public static Size THICKNESS = new Size(1d, SizeUnit.mm);
public static Color COLOR = Color.black;
private Size thickness = THICKNESS;
private PCBLayer layer = PCBLayer._1;
public CopperTrace() {
super();
this.leadColor = COLOR;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(3));
g2d.setColor(COLOR);
g2d.drawLine(1, height - 2, width - 2, 1);
}
@Override
protected Color getLeadColorForPainting(ComponentState componentState) {
return componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: getLeadColor();
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
@EditableProperty(name = "Color")
public Color getLeadColor() {
return leadColor;
}
@EditableProperty(name = "Width")
public Size getThickness() {
return thickness;
}
public void setThickness(Size thickness) {
this.thickness = thickness;
}
@EditableProperty
public PCBLayer getLayer() {
if (layer == null) {
layer = PCBLayer._1;
}
return layer;
}
public void setLayer(PCBLayer layer) {
this.layer = layer;
}
@Override
protected int getLeadThickness() {
return (int) getThickness().convertToPixels();
}
@Override
protected boolean shouldShadeLeads() {
return false;
}
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,85 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.CubicCurve2D;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
import org.diylc.components.AbstractCurvedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.BomPolicy;
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 = "Curved Trace", author = "Branislav Stojkovic", category = "Connectivity",
instanceNamePrefix = "Trace", description = "Curved copper trace with two control points",
zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
public class CurvedTrace extends AbstractCurvedComponent<Void> {
private static final long serialVersionUID = 1L;
public static Color COLOR = Color.black;
public static Size SIZE = new Size(1d, SizeUnit.mm);
protected Size size = SIZE;
private PCBLayer layer = PCBLayer._1;
@Override
protected Color getDefaultColor() {
return COLOR;
}
@Override
protected void drawCurve(CubicCurve2D curve, Graphics2D g2d, ComponentState componentState) {
int thickness = (int) size.convertToPixels();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness));
Color curveColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color;
g2d.setColor(curveColor);
g2d.draw(curve);
}
@EditableProperty(name = "Width")
public Size getThickness() {
return size;
}
public void setThickness(Size size) {
this.size = size;
}
@EditableProperty
public PCBLayer getLayer() {
if (layer == null) {
layer = PCBLayer._1;
}
return layer;
}
public void setLayer(PCBLayer layer) {
this.layer = layer;
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {}
@Override
public Byte getAlpha() {
return super.getAlpha();
}
@Override
public void setAlpha(Byte alpha) {
super.setAlpha(alpha);
}
}
@@ -0,0 +1,108 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
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.BomPolicy;
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 = "Dot", category = "Connectivity", author = "Branislav Stojkovic",
description = "Connector dot", instanceNamePrefix = "Dot", stretchable = false, zOrder = IDIYComponent.COMPONENT,
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
public class Dot extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L;
public static Size SIZE = new Size(1d, SizeUnit.mm);
public static Color COLOR = Color.black;
private Size size = SIZE;
private Color color = COLOR;
private Point point = new Point(0, 0);
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int diameter = getClosestOdd((int) getSize().convertToPixels());
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color);
g2d.fillOval(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int diameter = 7 * width / 32;
g2d.setColor(COLOR);
g2d.fillOval((width - diameter) / 2, (height - diameter) / 2, diameter, diameter);
}
@EditableProperty
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
@Override
public String getName() {
return super.getName();
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public Point getControlPoint(int index) {
return point;
}
@Override
public void setControlPoint(Point point, int index) {
this.point.setLocation(point);
}
@EditableProperty(name = "Color")
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {}
}
@@ -0,0 +1,138 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
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.BomPolicy;
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 = "Eyelet", category = "Connectivity", author = "Branislav Stojkovic",
description = "Eyelet or turret terminal", instanceNamePrefix = "Eyelet", stretchable = false,
zOrder = IDIYComponent.TRACE + 0.1, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false)
public class Eyelet extends AbstractComponent<String> {
private static final long serialVersionUID = 1L;
public static Size SIZE = new Size(0.2d, SizeUnit.in);
public static Size HOLE_SIZE = new Size(0.1d, SizeUnit.in);
public static Color COLOR = Color.decode("#C3E4ED");
private Size size = SIZE;
private Size holeSize = HOLE_SIZE;
private Color color = COLOR;
private Point point = new Point(0, 0);
private String value = "";
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int diameter = getClosestOdd((int) size.convertToPixels());
int holeDiameter = getClosestOdd((int) holeSize.convertToPixels());
g2d.setColor(color);
g2d.fillOval(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter);
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color.darker());
g2d.drawOval(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter);
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(point.x - holeDiameter / 2, point.y - holeDiameter / 2, holeDiameter, holeDiameter);
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color.darker());
g2d.drawOval(point.x - holeDiameter / 2, point.y - holeDiameter / 2, holeDiameter, holeDiameter);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int diameter = getClosestOdd(width / 2);
int holeDiameter = 5;
g2d.setColor(COLOR);
g2d.fillOval((width - diameter) / 2, (height - diameter) / 2, diameter, diameter);
g2d.setColor(COLOR.darker());
g2d.drawOval((width - diameter) / 2, (height - diameter) / 2, diameter, diameter);
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval((width - holeDiameter) / 2, (height - holeDiameter) / 2, holeDiameter, holeDiameter);
g2d.setColor(COLOR.darker());
g2d.drawOval((width - holeDiameter) / 2, (height - holeDiameter) / 2, holeDiameter, holeDiameter);
}
@EditableProperty
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
@EditableProperty(name = "Hole size")
public Size getHoleSize() {
return holeSize;
}
public void setHoleSize(Size holeSize) {
this.holeSize = holeSize;
}
@Override
public String getName() {
return super.getName();
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public Point getControlPoint(int index) {
return point;
}
@Override
public void setControlPoint(Point point, int index) {
this.point.setLocation(point);
}
@EditableProperty(name = "Color")
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
@Override
@EditableProperty
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
}
@@ -0,0 +1,156 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.Arrays;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
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.BomPolicy;
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 Fill", author = "Branislav Stojkovic", category = "Connectivity",
instanceNamePrefix = "GF", description = "Polygonal ground fill area", zOrder = IDIYComponent.TRACE,
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
public class GroundFill extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L;
public static Color COLOR = Color.black;
public static Size DEFAULT_WIDTH = new Size(1.5d, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(1.2d, SizeUnit.in);
protected Point[] controlPoints = new Point[] {new Point(0, 0), new Point(0, (int) DEFAULT_HEIGHT.convertToPixels()),
new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels()),
new Point((int) DEFAULT_WIDTH.convertToPixels(), 0)};
protected Color color = COLOR;
protected PointCount pointCount = PointCount._4;
private PCBLayer layer = PCBLayer._1;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
Color fillColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color;
g2d.setColor(fillColor);
int[] xPoints = new int[controlPoints.length];
int[] yPoints = new int[controlPoints.length];
for (int i = 0; i < controlPoints.length; i++) {
xPoints[i] = controlPoints[i].x;
yPoints[i] = controlPoints[i].y;
}
g2d.fillPolygon(xPoints, yPoints, controlPoints.length);
// Do not track any changes that follow because the whole board has been
// tracked so far.
drawingObserver.stopTracking();
}
@EditableProperty(name = "Color")
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return false;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
}
@EditableProperty(name = "Edges")
public PointCount getPointCount() {
return pointCount;
}
public void setPointCount(PointCount pointCount) {
if (this.pointCount == pointCount)
return;
int oldPointCount = Integer.parseInt(this.pointCount.toString());
int newPointCount = Integer.parseInt(pointCount.toString());
this.controlPoints = Arrays.copyOf(this.controlPoints, newPointCount);
if (oldPointCount < newPointCount) {
this.controlPoints[newPointCount - 1] = this.controlPoints[oldPointCount - 1];
for (int i = oldPointCount - 1; i < newPointCount - 1; i++) {
this.controlPoints[i] =
new Point((this.controlPoints[i - 1].x + this.controlPoints[newPointCount - 1].x) / 2,
(this.controlPoints[i - 1].y + this.controlPoints[newPointCount - 1].y) / 2);
}
}
this.pointCount = pointCount;
}
@EditableProperty
public PCBLayer getLayer() {
if (layer == null) {
layer = PCBLayer._1;
}
return layer;
}
public void setLayer(PCBLayer layer) {
this.layer = layer;
}
@Deprecated
@Override
public Void getValue() {
return null;
}
@Deprecated
@Override
public void setValue(Void value) {}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
g2d.setColor(COLOR);
int[] x = {2 / factor, width - 2 / factor, width - 4 / factor, 3 / factor};
int[] y = {4 / factor, 2 / factor, height - 5 / factor, height - 2 / factor};
g2d.fillPolygon(x, y, 4);
}
public enum PointCount {
_3, _4, _5, _6, _7, _8;
public String toString() {
return name().substring(1);
};
}
}
@@ -0,0 +1,66 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.CubicCurve2D;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractCurvedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Hookup Wire", author = "Branislav Stojkovic", category = "Connectivity",
instanceNamePrefix = "W", description = "Flexible wire with two control points", zOrder = IDIYComponent.COMPONENT,
bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
public class HookupWire extends AbstractCurvedComponent<Void> {
private static final long serialVersionUID = 1L;
public static Color COLOR = Color.green;
public static double INSULATION_THICKNESS_PCT = 0.3;
protected AWG gauge = AWG._22;
@Override
protected Color getDefaultColor() {
return COLOR;
}
@Override
protected void drawCurve(CubicCurve2D curve, Graphics2D g2d, ComponentState componentState) {
int thickness =
(int) (Math.pow(Math.E, -1.12436 - 0.11594 * gauge.getValue()) * Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT));
Color curveColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color.darker();
g2d.setColor(curveColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness));
g2d.draw(curve);
if (componentState == ComponentState.NORMAL) {
g2d.setColor(color);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness - 2));
g2d.draw(curve);
}
}
@EditableProperty(name = "AWG")
public AWG getGauge() {
return gauge;
}
public void setGauge(AWG gauge) {
this.gauge = gauge;
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {}
}
@@ -0,0 +1,124 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import org.diylc.common.Display;
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.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
@ComponentDescriptor(name = "Jumper", author = "Branislav Stojkovic", category = "Connectivity",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "J", description = "",
zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
public class Jumper extends AbstractLeadedComponent<Void> {
private static final long serialVersionUID = 1L;
public static Color COLOR = Color.blue;
@Deprecated
private Color color;
public Jumper() {
super();
this.leadColor = COLOR;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(3));
g2d.setColor(COLOR.darker());
g2d.drawLine(1, height - 2, width - 2, 1);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.setColor(COLOR);
g2d.drawLine(1, height - 2, width - 2, 1);
}
@Override
public Color getLeadColorForPainting(ComponentState componentState) {
return componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: getLeadColor();
}
@Override
@EditableProperty(name = "Color")
public Color getLeadColor() {
if (color != null) {
this.leadColor = color;
}
return super.getLeadColor();
}
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;
}
@Deprecated
@Override
public Color getLabelColor() {
return super.getLabelColor();
}
@Deprecated
@Override
public String getName() {
return super.getName();
}
@Deprecated
@Override
public Display getDisplay() {
return super.getDisplay();
}
}
@@ -0,0 +1,130 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import org.diylc.common.Display;
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.BomPolicy;
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 = "Shapes",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "LN", description = "",
zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
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 getLeadColorForPainting(ComponentState componentState) {
return componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color;
}
@Override
public Color getLeadColor() {
return super.getLeadColor();
}
@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;
}
@Deprecated
@Override
public Color getLabelColor() {
return super.getLabelColor();
}
@Deprecated
@Override
public String getName() {
return super.getName();
}
@Deprecated
@Override
public Display getDisplay() {
return super.getDisplay();
}
}
@@ -0,0 +1,167 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import org.diylc.common.PCBLayer;
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.BomPolicy;
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 = "Solder Pad", category = "Connectivity", author = "Branislav Stojkovic",
description = "Copper solder pad, round or square", instanceNamePrefix = "Pad", stretchable = false,
zOrder = IDIYComponent.TRACE + 0.1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
public class SolderPad extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L;
public static Size SIZE = new Size(0.09d, SizeUnit.in);
public static Size HOLE_SIZE = new Size(0.8d, SizeUnit.mm);
public static Color COLOR = Color.black;
private Size size = SIZE;
private Color color = COLOR;
private Point point = new Point(0, 0);
private Type type = Type.ROUND;
private Size holeSize = HOLE_SIZE;
private PCBLayer layer = PCBLayer._1;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int diameter = getClosestOdd((int) getSize().convertToPixels());
int holeDiameter = getClosestOdd((int) getHoleSize().convertToPixels());
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color);
if (type == Type.ROUND) {
g2d.fillOval(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter);
} else {
g2d.fillRect(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter);
}
if (getHoleSize().getValue() > 0) {
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(point.x - holeDiameter / 2, point.y - holeDiameter / 2, holeDiameter, holeDiameter);
}
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int diameter = getClosestOdd(width / 2);
int holeDiameter = 5;
g2d.setColor(COLOR);
g2d.fillOval((width - diameter) / 2, (height - diameter) / 2, diameter, diameter);
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval((width - holeDiameter) / 2, (height - holeDiameter) / 2, holeDiameter, holeDiameter);
}
@EditableProperty
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
@EditableProperty(name = "Hole")
public Size getHoleSize() {
if (holeSize == null) {
holeSize = HOLE_SIZE;
}
return holeSize;
}
public void setHoleSize(Size holeSize) {
this.holeSize = holeSize;
}
@EditableProperty
public PCBLayer getLayer() {
if (layer == null) {
layer = PCBLayer._1;
}
return layer;
}
public void setLayer(PCBLayer layer) {
this.layer = layer;
}
@Override
public String getName() {
return super.getName();
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public Point getControlPoint(int index) {
return point;
}
@Override
public void setControlPoint(Point point, int index) {
this.point.setLocation(point);
}
@EditableProperty(name = "Color")
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
@EditableProperty
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {}
static enum Type {
ROUND, SQUARE;
@Override
public String toString() {
return name().substring(0, 1) + name().substring(1).toLowerCase();
}
}
}
@@ -0,0 +1,182 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractComponent;
import org.diylc.components.boards.AbstractBoard;
import org.diylc.components.boards.VeroBoard;
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.BomPolicy;
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 = "Trace Cut", category = "Connectivity", author = "Branislav Stojkovic",
description = "Designates the place where a trace on the vero board needs to be cut", instanceNamePrefix = "Cut",
stretchable = false, zOrder = IDIYComponent.BOARD + 1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
public class TraceCut extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L;
public static Size SIZE = new Size(0.07d, SizeUnit.in);
public static Size CUT_WIDTH = new Size(0.5d, SizeUnit.mm);
public static Color FILL_COLOR = Color.white;
public static Color BORDER_COLOR = Color.red;
public static Color SELECTION_COLOR = Color.blue;
private Size size = SIZE;
private Color fillColor = FILL_COLOR;
private Color borderColor = BORDER_COLOR;
private Color boardColor = AbstractBoard.BOARD_COLOR;
private Boolean cutBetweenHoles = true;
private Size holeSpacing = VeroBoard.SPACING;
protected Point point = new Point(0, 0);
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int size = getClosestOdd((int) this.size.convertToPixels());
int cutWidth = getClosestOdd((int) CUT_WIDTH.convertToPixels());
if (getCutBetweenHoles()) {
int holeSpacing = getClosestOdd(getHoleSpacing().convertToPixels());
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: boardColor);
g2d.fillRect(point.x - holeSpacing / 2 - cutWidth / 2, point.y - size / 2 - 1, cutWidth, size + 2);
} else {
int dotDiameter = size - 6;
g2d.setColor(fillColor);
g2d.fillRect(point.x - size / 2, point.y - size / 2, size, size);
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawRect(point.x - size / 2, point.y - size / 2, size, size);
g2d.fillOval(point.x - dotDiameter / 2, point.y - dotDiameter / 2, dotDiameter, dotDiameter);
}
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int size = 16;
int dotDiameter = size / 4 * 2;
g2d.setColor(FILL_COLOR);
g2d.fillRect((width - size) / 2, (height - size) / 2, size, size);
g2d.setColor(BORDER_COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawRect((width - size) / 2, (height - size) / 2, size, size);
g2d.fillOval((width - dotDiameter) / 2, (height - dotDiameter) / 2, dotDiameter, dotDiameter);
}
@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) {}
@EditableProperty
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
@EditableProperty(name = "Fill")
public Color getFillColor() {
return fillColor;
}
public void setFillColor(Color fillColor) {
this.fillColor = fillColor;
}
@EditableProperty(name = "Border")
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@EditableProperty(name = "Cut between holes")
public boolean getCutBetweenHoles() {
if (cutBetweenHoles == null) {
cutBetweenHoles = false;
}
return cutBetweenHoles;
}
public void setCutBetweenHoles(boolean cutBetweenHoles) {
this.cutBetweenHoles = cutBetweenHoles;
}
@EditableProperty(name = "Board")
public Color getBoardColor() {
if (boardColor == null) {
boardColor = AbstractBoard.BOARD_COLOR;
}
return boardColor;
}
public void setBoardColor(Color boardColor) {
this.boardColor = boardColor;
}
@EditableProperty(name = "Hole spacing")
public Size getHoleSpacing() {
if (holeSpacing == null) {
holeSpacing = VeroBoard.SPACING;
}
return holeSpacing;
}
public void setHoleSpacing(Size holeSpacing) {
this.holeSpacing = holeSpacing;
}
@Deprecated
@Override
public String getName() {
return super.getName();
}
}
@@ -0,0 +1,250 @@
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.Polygon;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
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.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 = "9V Battery Snap", category = "Electromechanical", author = "Branislav Stojkovic",
description = "", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "BTR",
autoEdit = false)
public class BatterySnap9V extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private static Color BODY_COLOR = Color.darkGray;
private static Size WIDTH = new Size(0.5d, SizeUnit.in);
private static Size LENGTH = new Size(0.75d, SizeUnit.in);
private static Size TERMINAL_DIAMETER = new Size(0.3d, SizeUnit.in);
private static Size TERMINAL_SPACING = new Size(0.5d, SizeUnit.in);
private static Size TERMINAL_BORDER = new Size(0.7d, 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 : METAL_COLOR);
g2d.fill(body[1]);
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.brighter();
}
g2d.setColor(finalBorderColor);
g2d.draw(body[0]);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(body[1]);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(body[2]);
}
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 totalLength = length + width / 2;
int terminalDiameter = (int) TERMINAL_DIAMETER.convertToPixels();
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
int terminalBorder = (int) TERMINAL_BORDER.convertToPixels();
Area mainArea = new Area(new Rectangle2D.Double(x, y - width / 2, length, width));
mainArea.add(new Area(new Ellipse2D.Double(x + length - width / 2, y - width / 2, width, width)));
body[0] = mainArea;
Area terminalArea =
new Area(new Ellipse2D.Double(x + (totalLength - terminalSpacing) / 2 - terminalDiameter / 2, y
- terminalDiameter / 2, terminalDiameter, terminalDiameter));
int centerX = x + (totalLength + terminalSpacing) / 2;
int[] terminalX = new int[6];
int[] terminalY = new int[6];
for (int i = 0; i < 6; i++) {
terminalX[i] = (int) (centerX + Math.cos(Math.PI / 3 * i) * terminalDiameter / 2);
terminalY[i] = (int) (y + Math.sin(Math.PI / 3 * i) * terminalDiameter / 2);
}
terminalArea.add(new Area(new Polygon(terminalX, terminalY, 6)));
body[1] = terminalArea;
terminalArea =
new Area(new Ellipse2D.Double(
x + (totalLength - terminalSpacing) / 2 - terminalDiameter / 2 + terminalBorder, y - terminalDiameter / 2
+ terminalBorder, terminalDiameter - 2 * terminalBorder, terminalDiameter - 2 * terminalBorder));
for (int i = 0; i < 6; i++) {
terminalX[i] = (int) (centerX + Math.cos(Math.PI / 3 * i) * (terminalDiameter / 2 + terminalBorder));
terminalY[i] = (int) (y + Math.sin(Math.PI / 3 * i) * (terminalDiameter / 2 + terminalBorder));
}
terminalArea.add(new Area(new Polygon(terminalX, terminalY, 6)));
body[2] = terminalArea;
// 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) {
g2d.setColor(BODY_COLOR);
g2d.fillOval(width / 4, width / 32, width / 2, width / 2);
g2d.setColor(BODY_COLOR.darker());
g2d.drawOval(width / 4, width / 32, width / 2, width / 2);
g2d.setColor(BODY_COLOR);
g2d.fillRect(width / 4, width / 32 + width / 4, width / 2, width * 3 / 4 - 2 * width / 32);
g2d.setColor(BODY_COLOR.darker());
g2d.drawRect(width / 4, width / 32 + width / 4, width / 2, width * 3 / 4 - 2 * width / 32);
g2d.setColor(METAL_COLOR);
g2d.fillOval(width / 4 + 3 * width / 32, width / 32 + 3 * width / 32, width / 2 - 6 * width / 32, width / 2 - 6
* width / 32);
int centerX = width / 2;
int centerY = height * 7 / 9;
int terminalDiameter = width / 2 - 4 * width / 32;
int[] terminalX = new int[6];
int[] terminalY = new int[6];
for (int i = 0; i < 6; i++) {
terminalX[i] = (int) (centerX + Math.cos(Math.PI / 3 * i) * terminalDiameter / 2);
terminalY[i] = (int) (centerY + Math.sin(Math.PI / 3 * i) * terminalDiameter / 2);
}
g2d.fillPolygon(terminalX, terminalY, 6);
g2d.setColor(METAL_COLOR.darker());
g2d.drawOval(width / 4 + 3 * width / 32, width / 32 + 3 * width / 32, width / 2 - 6 * width / 32, width / 2 - 6
* width / 32);
g2d.drawPolygon(terminalX, terminalY, 6);
}
@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;
}
@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,323 @@
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", autoEdit = false)
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;
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
if (outlineMode) {
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];
if (!outlineMode) {
g2d.setColor(METAL_COLOR);
g2d.fill(pins);
}
g2d.setColor(outlineMode ? theme.getOutlineColor() : METAL_COLOR.darker());
g2d.draw(pins);
Color finalLabelColor;
if (outlineMode) {
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,334 @@
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", autoEdit = false)
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();
}
}
@@ -0,0 +1,421 @@
package org.diylc.components.electromechanical;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Area;
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;
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.core.measures.Voltage;
import org.diylc.core.measures.VoltageUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Mini Relay", author = "Branislav Stojkovic", category = "Electromechanical",
instanceNamePrefix = "RY", description = "Miniature PCB mount relay, like Omron G5V-1 or G5V-2",
stretchable = false, zOrder = IDIYComponent.COMPONENT)
public class MiniRelay extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
public static Color BODY_COLOR = Color.gray;
public static Color BORDER_COLOR = Color.gray.darker();
public static Color PIN_COLOR = Color.decode("#00B2EE");
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
public static Color INDENT_COLOR = Color.gray.darker();
public static Color LABEL_COLOR = Color.white;
public static int EDGE_RADIUS = 6;
public static Size PIN_SIZE = new Size(0.03d, SizeUnit.in);
public static Size INDENT_SIZE = new Size(0.07d, SizeUnit.in);
public static Size BODY_MARGIN = new Size(0.05d, SizeUnit.in);
public static Size MINI_PIN_SPACING = new Size(0.2d, SizeUnit.in);
public static Size MINI_ROW_SPACING = new Size(0.3d, SizeUnit.in);
public static Size MINI_WIDTH = new Size(20.1d, SizeUnit.mm);
public static Size MINI_HEIGHT = new Size(9.9d, SizeUnit.mm);
public static Size MINI_GAP = new Size(0.1d, SizeUnit.in);
public static Size ULTRA_PIN_SPACING = new Size(0.1d, SizeUnit.in);
public static Size ULTRA_ROW_SPACING = new Size(0.2d, SizeUnit.in);
public static Size ULTRA_WIDTH = new Size(12.2d, SizeUnit.mm);
public static Size ULTRA_HEIGHT = new Size(7.2d, SizeUnit.mm);
public static Size ULTRA_GAP = new Size(0.1d, SizeUnit.in);
private String value = "";
private Orientation orientation = Orientation.DEFAULT;
private Point[] controlPoints = new Point[] {new Point(0, 0)};
protected Display display = Display.NAME;
private RelayType type = RelayType.DPDT;
private RelaySize size = RelaySize.Miniature;
private Voltage voltage = new Voltage(12d, VoltageUnit.V);
transient private Area[] body;
public MiniRelay() {
super();
updateControlPoints();
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// 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() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
private void updateControlPoints() {
Point firstPoint = controlPoints[0];
int pinCount = 0;
switch (type) {
case DPDT:
pinCount = 8;
break;
case SPDT:
pinCount = 6;
break;
default:
throw new RuntimeException("Unexpected type: " + type);
}
controlPoints = new Point[pinCount];
controlPoints[0] = firstPoint;
int pinSpacing =
size == RelaySize.Miniature ? (int) MINI_PIN_SPACING.convertToPixels() : (int) ULTRA_PIN_SPACING
.convertToPixels();
int rowSpacing =
size == RelaySize.Miniature ? (int) MINI_ROW_SPACING.convertToPixels() : (int) ULTRA_ROW_SPACING
.convertToPixels();
// Update control points.
int dx1;
int dy1;
int dx2;
int dy2;
int delta = 0;
for (int i = 0; i < pinCount / 2; i++) {
if (i == 1) {
delta = size == RelaySize.Miniature ? (int) MINI_GAP.convertToPixels() : (int) ULTRA_GAP.convertToPixels();
if (type == RelayType.SPDT) {
delta += pinSpacing;
}
}
switch (orientation) {
case DEFAULT:
dx1 = 0;
dy1 = i * pinSpacing + delta;
dx2 = rowSpacing;
dy2 = i * pinSpacing + delta;
break;
case _90:
dx1 = -(i * pinSpacing + delta);
dy1 = 0;
dx2 = -(i * pinSpacing + delta);
dy2 = rowSpacing;
break;
case _180:
dx1 = 0;
dy1 = -(i * pinSpacing + delta);
dx2 = -rowSpacing;
dy2 = -(i * pinSpacing + delta);
break;
case _270:
dx1 = i * pinSpacing + delta;
dy1 = 0;
dx2 = i * pinSpacing + delta;
dy2 = -rowSpacing;
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
controlPoints[i] = new Point(firstPoint.x + dx1, firstPoint.y + dy1);
controlPoints[i + pinCount / 2] = new Point(firstPoint.x + dx2, firstPoint.y + dy2);
}
}
public Area[] getBody() {
if (body == null) {
body = new Area[2];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int centerX = (controlPoints[0].x + controlPoints[controlPoints.length - 1].x) / 2;
int centerY = (controlPoints[0].y + controlPoints[controlPoints.length - 1].y) / 2;
int bodyMargin = getClosestOdd(BODY_MARGIN.convertToPixels());
int width = 0;
int height = 0;
int rowSpacing =
size == RelaySize.Miniature ? (int) MINI_ROW_SPACING.convertToPixels() : (int) ULTRA_ROW_SPACING
.convertToPixels();
Area indentation = null;
int indentationSize = getClosestOdd(INDENT_SIZE.convertToPixels());
switch (orientation) {
case DEFAULT:
width = (int) (size == RelaySize.Miniature ? MINI_HEIGHT.convertToPixels() : ULTRA_HEIGHT.convertToPixels());
height = (int) (size == RelaySize.Miniature ? MINI_WIDTH.convertToPixels() : ULTRA_WIDTH.convertToPixels());
x -= bodyMargin;
y -= bodyMargin;
indentation =
new Area(new Rectangle2D.Double(centerX - indentationSize / 2, y - indentationSize / 2, indentationSize,
indentationSize));
break;
case _90:
width = (int) (size == RelaySize.Miniature ? MINI_WIDTH.convertToPixels() : ULTRA_WIDTH.convertToPixels());
height = (int) (size == RelaySize.Miniature ? MINI_HEIGHT.convertToPixels() : ULTRA_HEIGHT.convertToPixels());
x -= -bodyMargin + width;
y -= bodyMargin;
indentation =
new Area(new Rectangle2D.Double(x + width - indentationSize / 2, centerY - indentationSize / 2,
indentationSize, indentationSize));
break;
case _180:
width = (int) (size == RelaySize.Miniature ? MINI_HEIGHT.convertToPixels() : ULTRA_HEIGHT.convertToPixels());
height = (int) (size == RelaySize.Miniature ? MINI_WIDTH.convertToPixels() : ULTRA_WIDTH.convertToPixels());
x -= rowSpacing + bodyMargin;
y -= -bodyMargin + height;
indentation =
new Area(new Rectangle2D.Double(centerX - indentationSize / 2, y + height - indentationSize / 2,
indentationSize, indentationSize));
break;
case _270:
width = (int) (size == RelaySize.Miniature ? MINI_WIDTH.convertToPixels() : ULTRA_WIDTH.convertToPixels());
height = (int) (size == RelaySize.Miniature ? MINI_HEIGHT.convertToPixels() : ULTRA_HEIGHT.convertToPixels());
x -= bodyMargin;
y -= bodyMargin + rowSpacing;
indentation =
new Area(new Rectangle2D.Double(x - indentationSize / 2, centerY - indentationSize / 2, indentationSize,
indentationSize));
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
body[0] =
new Area(new RoundRectangle2D.Double(centerX - width / 2, centerY - height / 2, width, height, EDGE_RADIUS,
EDGE_RADIUS));
body[1] = indentation;
if (indentation != null) {
indentation.intersect(body[0]);
}
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
Area mainArea = getBody()[0];
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(mainArea);
g2d.setComposite(oldComposite);
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
for (Point point : controlPoints) {
if (!outlineMode) {
g2d.setColor(PIN_COLOR);
g2d.fillOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR);
g2d.drawOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
Color finalBorderColor;
if (outlineMode) {
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.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (outlineMode) {
Area area = new Area(mainArea);
area.subtract(getBody()[1]);
g2d.draw(area);
} else {
g2d.draw(mainArea);
if (getBody()[1] != null) {
g2d.setColor(INDENT_COLOR);
g2d.fill(getBody()[1]);
}
}
// Draw label.
g2d.setFont(LABEL_FONT);
Color finalLabelColor;
if (outlineMode) {
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);
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
String label = "";
label = display == Display.VALUE ? getValue() : getName();
if (display == Display.NONE) {
label = "";
}
if (display == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
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(label, x, y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int radius = 6 * width / 32;
g2d.setColor(BODY_COLOR);
g2d.fillRoundRect(width / 6, 1, 4 * width / 6, height - 4, radius, radius);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(width / 6, 1, 4 * width / 6, height - 4, radius, radius);
int pinSize = 2 * width / 32;
g2d.setColor(PIN_COLOR);
for (int i = 0; i < 4; i++) {
if (i == 1)
continue;
g2d.fillOval(width / 4, (height / 5) * (i + 1) - 1, pinSize, pinSize);
g2d.fillOval(3 * width / 4 - pinSize, (height / 5) * (i + 1) - 1, pinSize, pinSize);
}
}
@Override
public String getValueForDisplay() {
return getValue() + " " + getType() + " " + getVoltage();
}
@EditableProperty
public RelayType getType() {
return type;
}
public void setType(RelayType type) {
this.type = type;
updateControlPoints();
// Invalidate body
this.body = null;
}
@EditableProperty
public Voltage getVoltage() {
return voltage;
}
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty
public RelaySize getSize() {
return size;
}
public void setSize(RelaySize size) {
this.size = size;
updateControlPoints();
// Invalidate body
this.body = null;
}
public static enum RelayType {
SPDT, DPDT;
}
public static enum RelaySize {
Miniature, Ultra_miniature;
public String toString() {
return name().replace('_', '-');
};
}
}
@@ -0,0 +1,304 @@
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.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.OrientationHV;
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 = "Mini Toggle Switch", category = "Electromechanical", author = "Branislav Stojkovic",
description = "Panel mounted mini toggle switch", stretchable = false, zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "SW", autoEdit = false)
public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchType> {
private static final long serialVersionUID = 1L;
private static Size SPACING = new Size(0.2d, SizeUnit.in);
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_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.decode("#FFFFAA");
protected Point[] controlPoints = new Point[] {new Point(0, 0)};
transient protected Shape body;
protected String name;
protected ToggleSwitchType switchType = ToggleSwitchType.DPDT;
private OrientationHV orientation = OrientationHV.VERTICAL;
public MiniToggleSwitch() {
super();
updateControlPoints();
}
private void updateControlPoints() {
Point firstPoint = controlPoints[0];
int spacing = (int) SPACING.convertToPixels();
switch (switchType) {
case SPST:
controlPoints = new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing)};
break;
case SPDT:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing)};
break;
case DPDT:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing), new Point(firstPoint.x + spacing, firstPoint.y),
new Point(firstPoint.x + spacing, firstPoint.y + spacing),
new Point(firstPoint.x + spacing, firstPoint.y + 2 * spacing)};
break;
case _3PDT:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing), new Point(firstPoint.x + spacing, firstPoint.y),
new Point(firstPoint.x + spacing, firstPoint.y + spacing),
new Point(firstPoint.x + spacing, firstPoint.y + 2 * spacing),
new Point(firstPoint.x + 2 * spacing, firstPoint.y),
new Point(firstPoint.x + 2 * spacing, firstPoint.y + spacing),
new Point(firstPoint.x + 2 * spacing, firstPoint.y + 2 * spacing)};
break;
case _4PDT:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing), new Point(firstPoint.x + spacing, firstPoint.y),
new Point(firstPoint.x + spacing, firstPoint.y + spacing),
new Point(firstPoint.x + spacing, firstPoint.y + 2 * spacing),
new Point(firstPoint.x + 2 * spacing, firstPoint.y),
new Point(firstPoint.x + 2 * spacing, firstPoint.y + spacing),
new Point(firstPoint.x + 2 * spacing, firstPoint.y + 2 * spacing),
new Point(firstPoint.x + 3 * spacing, firstPoint.y),
new Point(firstPoint.x + 3 * spacing, firstPoint.y + spacing),
new Point(firstPoint.x + 3 * spacing, firstPoint.y + 2 * spacing)};
break;
case _5PDT:
controlPoints =
new Point[] {firstPoint, new Point(firstPoint.x, firstPoint.y + spacing),
new Point(firstPoint.x, firstPoint.y + 2 * spacing), new Point(firstPoint.x + spacing, firstPoint.y),
new Point(firstPoint.x + spacing, firstPoint.y + spacing),
new Point(firstPoint.x + spacing, firstPoint.y + 2 * spacing),
new Point(firstPoint.x + 2 * spacing, firstPoint.y),
new Point(firstPoint.x + 2 * spacing, firstPoint.y + spacing),
new Point(firstPoint.x + 2 * spacing, firstPoint.y + 2 * spacing),
new Point(firstPoint.x + 3 * spacing, firstPoint.y),
new Point(firstPoint.x + 3 * spacing, firstPoint.y + spacing),
new Point(firstPoint.x + 3 * spacing, firstPoint.y + 2 * spacing),
new Point(firstPoint.x + 4 * spacing, firstPoint.y),
new Point(firstPoint.x + 4 * spacing, firstPoint.y + spacing),
new Point(firstPoint.x + 4 * spacing, firstPoint.y + 2 * spacing)};
break;
}
AffineTransform xform = AffineTransform.getRotateInstance(-Math.PI / 2, firstPoint.x, firstPoint.y);
if (getOrientation() == OrientationHV.HORIZONTAL) {
for (int i = 1; i < controlPoints.length; i++) {
xform.transform(controlPoints[i], controlPoints[i]);
}
}
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
// Reset body shape.
body = null;
}
@EditableProperty
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@EditableProperty(name = "Type")
@Override
public ToggleSwitchType getValue() {
return switchType;
}
@Override
public void setValue(ToggleSwitchType value) {
this.switchType = value;
updateControlPoints();
// Reset body shape.
body = null;
}
@EditableProperty
public OrientationHV getOrientation() {
if (orientation == null) {
orientation = OrientationHV.VERTICAL;
}
return orientation;
}
public void setOrientation(OrientationHV orientation) {
this.orientation = orientation;
updateControlPoints();
// Reset body shape.
body = null;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
Shape body = getBody();
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
// Draw body if available.
if (body != null) {
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);
g2d.setComposite(oldComposite);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
Color finalBorderColor;
if (outlineMode) {
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);
}
// Do not track these changes because the whole switch has been tracked
// so far.
drawingObserver.stopTracking();
// Draw lugs.
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(theme.getOutlineColor());
g2d.drawRect(p.x - lugWidth / 2, p.y - lugHeight / 2, lugWidth, lugHeight);
} else {
g2d.setColor(CIRCLE_COLOR);
g2d.fillOval(p.x - circleDiameter / 2, p.y - circleDiameter / 2, circleDiameter, circleDiameter);
g2d.setColor(METAL_COLOR);
g2d.fillRect(p.x - lugWidth / 2, p.y - lugHeight / 2, lugWidth, lugHeight);
}
}
}
public Shape getBody() {
if (body == null) {
Point firstPoint = controlPoints[0];
int margin = (int) MARGIN.convertToPixels();
int spacing = (int) SPACING.convertToPixels();
switch (switchType) {
case SPST:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin, 2 * margin
+ spacing, margin, margin);
break;
case SPDT:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin, 2 * margin + 2
* spacing, margin, margin);
break;
case DPDT:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin + spacing, 2
* margin + 2 * spacing, margin, margin);
break;
case _3PDT:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin + 2 * spacing, 2
* margin + 2 * spacing, margin, margin);
break;
case _4PDT:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin + 3 * spacing, 2
* margin + 2 * spacing, margin, margin);
break;
case _5PDT:
body =
new RoundRectangle2D.Double(firstPoint.x - margin, firstPoint.y - margin, 2 * margin + 4 * spacing, 2
* margin + 2 * spacing, margin, margin);
break;
}
if (getOrientation() == OrientationHV.HORIZONTAL) {
AffineTransform xform = AffineTransform.getRotateInstance(-Math.PI / 2, firstPoint.x, firstPoint.y);
body = new Area(body);
((Area) body).transform(xform);
}
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int circleSize = 5 * width / 32;
g2d.setColor(BODY_COLOR);
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);
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,241 @@
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", autoEdit = false, rotatable = false)
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);
}
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
Color finalBorderColor;
if (outlineMode) {
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(outlineMode ? theme.getOutlineColor() : 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,11 @@
package org.diylc.components.electromechanical;
public enum ToggleSwitchType {
SPST, SPDT, DPDT, _3PDT, _4PDT, _5PDT;
@Override
public String toString() {
return name().replace("_", "");
}
}
@@ -0,0 +1,267 @@
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", autoEdit = false)
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,322 @@
// 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.Shape;
// import java.awt.geom.AffineTransform;
// import java.awt.geom.Area;
// import java.awt.geom.Ellipse2D;
// import java.awt.geom.Rectangle2D;
// import java.awt.geom.RoundRectangle2D;
//
// import org.diylc.appframework.miscutils.ConfigurationManager;
// import org.diylc.common.IPlugInPort;
// 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.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 = "Les Paul Switch", category = "Guitar", author =
// "Branislav Stojkovic", description = "Les Paul-style 3 position switch", stretchable = false,
// zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "SW")
// public class LPSwitch extends AbstractTransparentComponent<String> {
//
// private static final long serialVersionUID = 1L;
//
// private static Color BASE_COLOR = Color.lightGray;
// private static Color WAFER_COLOR = Color.decode("#CD8500");
//
// private static Size BASE_WIDTH = new Size(0.5d, SizeUnit.in);
// private static Size BASE_LENGTH = new Size(47.5d, SizeUnit.mm);
// private static Size WAFER_LENGTH = new Size(40d, SizeUnit.mm);
// private static Size WAFER_SPACING = new Size(7.62d, SizeUnit.mm);
// private static Size WAFER_THICKNESS = new Size(0.05d, SizeUnit.in);
// private static Size HOLE_SIZE = new Size(2d, SizeUnit.mm);
// private static Size HOLE_SPACING = new Size(41.2d, SizeUnit.mm);
// private static Size TERMINAL_LENGTH = new Size(3d, SizeUnit.mm);
// private static Size TERMINAL_SPACING = new Size(0.1d, SizeUnit.in);
// private static Size TERMINAL_THICKNESS = new Size(0.02d, SizeUnit.in);
//
// private String value = "";
// private Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0),
// new Point(0, 0), new Point(0, 0) };
// transient Shape[] body;
// private Orientation orientation = Orientation.DEFAULT;
//
// public LPSwitch() {
// super();
// updateControlPoints();
// }
//
// @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 : BASE_COLOR);
// g2d.fill(body[0]);
// g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : WAFER_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 : BASE_COLOR
// .darker();
// }
//
// g2d.setColor(finalBorderColor);
// g2d.draw(body[0]);
//
// 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 : WAFER_COLOR
// .darker();
// }
//
// g2d.draw(body[1]);
//
// g2d.setColor(METAL_COLOR);
// g2d.fill(body[2]);
// g2d.setColor(METAL_COLOR.darker());
// g2d.draw(body[2]);
// }
//
// public Shape[] getBody() {
// if (body == null) {
// body = new Shape[3];
//
// int x = controlPoints[0].x;
// int y = controlPoints[0].y;
// int baseWidth = (int) BASE_WIDTH.convertToPixels();
// int baseLength = (int) BASE_LENGTH.convertToPixels();
// int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
// int holeSpacing = (int) HOLE_SPACING.convertToPixels();
// int waferLength = (int) WAFER_LENGTH.convertToPixels();
// int waferSpacing = (int) WAFER_SPACING.convertToPixels();
// int waferThickness = (int) WAFER_THICKNESS.convertToPixels();
// int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
// int terminalLength = getClosestOdd(TERMINAL_LENGTH.convertToPixels());
// int terminalWidth = getClosestOdd(TERMINAL_WIDTH.convertToPixels());
//
// int baseX = x - terminalLength / 2 - waferSpacing;
// int baseY = y
// - (baseLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12)) / 2;
// Area baseArea = new Area(new Rectangle2D.Double(baseX, baseY, baseWidth, baseLength));
// baseArea.subtract(new Area(new Ellipse2D.Double(baseX + baseWidth / 2 - holeSize / 2,
// baseY + (baseLength - holeSpacing) / 2 - holeSize / 2, holeSize, holeSize)));
// baseArea.subtract(new Area(new Ellipse2D.Double(baseX + baseWidth / 2 - holeSize / 2,
// baseY + (baseLength - holeSpacing) / 2 - holeSize / 2 + holeSpacing, holeSize,
// holeSize)));
// body[0] = baseArea;
//
// Area waferArea = new Area(new Rectangle2D.Double(x - terminalLength / 2
// - waferThickness / 2,
// y - (waferLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12))
// / 2, waferThickness, waferLength));
//
// if (type == LeverSwitchType._4P5T) {
// waferArea.add(new Area(new Rectangle2D.Double(x - terminalLength / 2
// - waferThickness / 2 + waferSpacing, y
// - (waferLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12))
// / 2, waferThickness, waferLength)));
// }
// body[1] = waferArea;
//
// double theta = 0;
// // Rotate if needed
// if (orientation != Orientation.DEFAULT) {
// switch (orientation) {
// case _90:
// theta = Math.PI / 2;
// break;
// case _180:
// theta = Math.PI;
// break;
// case _270:
// theta = Math.PI * 3 / 2;
// break;
// }
// }
//
// Area terminalArea = new Area();
// for (Point point : controlPoints) {
// Area terminal = new Area(new RoundRectangle2D.Double(point.x - terminalLength / 2,
// point.y - terminalWidth / 2, terminalLength, terminalWidth,
// terminalWidth / 2, terminalWidth / 2));
// terminal.subtract(new Area(
// new RoundRectangle2D.Double(point.x - terminalLength / 4, point.y
// - terminalWidth / 4, terminalLength / 2, terminalWidth / 2,
// terminalWidth / 2, terminalWidth / 2)));
// // Rotate the terminal if needed
// if (theta != 0) {
// AffineTransform rotation = AffineTransform.getRotateInstance(theta, point.x,
// point.y);
// terminal.transform(rotation);
// }
// terminalArea.add(terminal);
// }
// body[2] = terminalArea;
//
// // Rotate if needed
// if (theta != 0) {
// AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
// // Skip the last one because it's already rotated
// for (int i = 0; i < body.length - 1; i++) {
// Shape shape = body[i];
// Area area = (Area) shape;
// area.transform(rotation);
// }
// }
// }
// return body;
// }
//
// private void updateControlPoints() {
// int x = controlPoints[0].x;
// int y = controlPoints[0].y;
// int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
// int baseLength = (int) BASE_LENGTH.convertToPixels();
//
// controlPoints[1].setLocation(x - terminalSpacing * 2 - baseLength, y - terminalSpacing);
// controlPoints[2].setLocation(x - terminalSpacing * 2 - baseLength, y);
// controlPoints[3].setLocation(x - terminalSpacing * 2 - baseLength, y);
//
// // 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 (Point point : controlPoints) {
// rotation.transform(point, point);
// }
// }
// }
//
// @Override
// public void drawIcon(Graphics2D g2d, int width, int height) {
// g2d.setClip(width / 32, width / 32, width, height);
// g2d.setColor(BASE_COLOR);
// g2d.fillRect(0, 0, width * 2 / 3, height);
// g2d.setColor(BASE_COLOR.darker());
// g2d.drawRect(0, 0, width * 2 / 3, height);
// g2d.setColor(WAFER_COLOR);
// g2d.fillRect(width / 8 * 3, 0, width / 8, height);
// g2d.setColor(WAFER_COLOR.darker());
// g2d.drawRect(width / 8 * 3, 0, width / 8, height);
// Area terminals = new Area();
// int terminalLength = getClosestOdd(11 * width / 32);
// int terminalWidth = getClosestOdd(7 * width / 32);
// Area terminal = new Area(new RoundRectangle2D.Double(width / 16 * 7, 4 * width / 32,
// terminalLength, terminalWidth, terminalWidth / 2, terminalWidth / 2));
// terminal.subtract(new Area(new RoundRectangle2D.Double(width / 16 * 7 + terminalLength / 4
// + 1, 4 * width / 32 + terminalWidth / 4 + 1, terminalLength / 2, terminalWidth / 2,
// terminalWidth / 4, terminalWidth / 4)));
// terminals.add(terminal);
// terminal = new Area(terminal);
// terminal.transform(AffineTransform.getTranslateInstance(-terminalLength, terminalWidth + 2
// * width / 32));
// terminals.add(terminal);
// terminal = new Area(terminal);
// terminal.transform(AffineTransform.getTranslateInstance(terminalLength, terminalWidth + 2
// * width / 32));
// terminals.add(terminal);
// g2d.setColor(METAL_COLOR);
// g2d.fill(terminals);
// g2d.setColor(METAL_COLOR.darker());
// g2d.draw(terminals);
// }
//
// @Override
// public int getControlPointCount() {
// return controlPoints.length;
// }
//
// @Override
// public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
// return VisibilityPolicy.NEVER;
// }
//
// @Override
// public boolean isControlPointSticky(int index) {
// return true;
// }
//
// @Override
// public Point getControlPoint(int index) {
// return controlPoints[index];
// }
//
// @Override
// public void setControlPoint(Point point, int index) {
// this.controlPoints[index].setLocation(point);
// // Invalidate the body
// body = null;
// }
//
// @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;
// updateControlPoints();
// // Invalidate the body
// body = null;
// }
// }
@@ -0,0 +1,359 @@
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.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
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.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 = "Lever Switch", category = "Guitar", author = "Branislav Stojkovic",
description = "Strat-style lever switch", stretchable = false, zOrder = IDIYComponent.COMPONENT,
instanceNamePrefix = "SW")
public class LeverSwitch extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private static Color BASE_COLOR = Color.lightGray;
private static Color WAFER_COLOR = Color.decode("#CD8500");
private static Size BASE_WIDTH = new Size(10d, SizeUnit.mm);
private static Size BASE_LENGTH = new Size(47.5d, SizeUnit.mm);
private static Size WAFER_LENGTH = new Size(40d, SizeUnit.mm);
private static Size WAFER_SPACING = new Size(7.62d, SizeUnit.mm);
private static Size WAFER_THICKNESS = new Size(1.27d, SizeUnit.mm);
private static Size HOLE_SIZE = new Size(2d, SizeUnit.mm);
private static Size HOLE_SPACING = new Size(41.2d, SizeUnit.mm);
private static Size TERMINAL_WIDTH = new Size(2d, SizeUnit.mm);
private static Size TERMINAL_LENGTH = new Size(0.1d, SizeUnit.in);
private static Size TERMINAL_SPACING = new Size(0.1d, SizeUnit.in);
private String value = "";
private Point[] controlPoints = new Point[] {new Point(0, 0)};
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private LeverSwitchType type = LeverSwitchType.DP3T;
public LeverSwitch() {
super();
updateControlPoints();
}
@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 : BASE_COLOR);
g2d.fill(body[0]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : WAFER_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
: BASE_COLOR.darker();
}
g2d.setColor(finalBorderColor);
g2d.draw(body[0]);
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
: WAFER_COLOR.darker();
}
g2d.draw(body[1]);
g2d.setColor(METAL_COLOR);
g2d.fill(body[2]);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(body[2]);
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[3];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int baseWidth = (int) BASE_WIDTH.convertToPixels();
int baseLength = (int) BASE_LENGTH.convertToPixels();
int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
int holeSpacing = (int) HOLE_SPACING.convertToPixels();
int waferLength = (int) WAFER_LENGTH.convertToPixels();
int waferSpacing = (int) WAFER_SPACING.convertToPixels();
int waferThickness = (int) WAFER_THICKNESS.convertToPixels();
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
int terminalLength = getClosestOdd(TERMINAL_LENGTH.convertToPixels());
int terminalWidth = getClosestOdd(TERMINAL_WIDTH.convertToPixels());
int baseX = x - terminalLength / 2 - waferSpacing;
int baseY = y - (baseLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12)) / 2;
Area baseArea = new Area(new Rectangle2D.Double(baseX, baseY, baseWidth, baseLength));
baseArea.subtract(new Area(new Ellipse2D.Double(baseX + baseWidth / 2 - holeSize / 2, baseY
+ (baseLength - holeSpacing) / 2 - holeSize / 2, holeSize, holeSize)));
baseArea.subtract(new Area(new Ellipse2D.Double(baseX + baseWidth / 2 - holeSize / 2, baseY
+ (baseLength - holeSpacing) / 2 - holeSize / 2 + holeSpacing, holeSize, holeSize)));
body[0] = baseArea;
Area waferArea =
new Area(new Rectangle2D.Double(x - terminalLength / 2 - waferThickness / 2, y
- (waferLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12)) / 2, waferThickness,
waferLength));
if (type == LeverSwitchType._4P5T) {
waferArea.add(new Area(new Rectangle2D.Double(x - terminalLength / 2 - waferThickness / 2 + waferSpacing, y
- (waferLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12)) / 2, waferThickness,
waferLength)));
}
body[1] = waferArea;
double theta = 0;
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
}
Area terminalArea = new Area();
for (Point point : controlPoints) {
Area terminal =
new Area(new RoundRectangle2D.Double(point.x - terminalLength / 2, point.y - terminalWidth / 2,
terminalLength, terminalWidth, terminalWidth / 2, terminalWidth / 2));
terminal.subtract(new Area(new RoundRectangle2D.Double(point.x - terminalLength / 4, point.y - terminalWidth
/ 4, terminalLength / 2, terminalWidth / 2, terminalWidth / 2, terminalWidth / 2)));
// Rotate the terminal if needed
if (theta != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, point.x, point.y);
terminal.transform(rotation);
}
terminalArea.add(terminal);
}
body[2] = terminalArea;
// Rotate if needed
if (theta != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
// Skip the last one because it's already rotated
for (int i = 0; i < body.length - 1; i++) {
Shape shape = body[i];
Area area = (Area) shape;
area.transform(rotation);
}
}
}
return body;
}
private void updateControlPoints() {
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int waferSpacing = (int) WAFER_SPACING.convertToPixels();
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
int terminalLength = (int) TERMINAL_LENGTH.convertToPixels();
switch (type) {
case DP3T:
controlPoints = new Point[8];
for (int i = 0; i < 8; i++) {
controlPoints[i] = new Point(x - (i % 2 == 1 ? terminalLength : 0), y + i * terminalSpacing);
}
break;
case DP5T:
controlPoints = new Point[12];
for (int i = 0; i < 12; i++) {
controlPoints[i] = new Point(x, y + i * terminalSpacing + (i >= 6 ? terminalSpacing : 0));
}
break;
case _4P5T:
controlPoints = new Point[24];
for (int i = 0; i < 12; i++) {
controlPoints[i] = new Point(x, y + i * terminalSpacing + (i >= 6 ? terminalSpacing : 0));
controlPoints[i + 12] = new Point(x + waferSpacing, y + i * terminalSpacing + (i >= 6 ? terminalSpacing : 0));
}
break;
}
// 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 (Point point : controlPoints) {
rotation.transform(point, point);
}
}
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setClip(width / 32, width / 32, width, height);
g2d.setColor(BASE_COLOR);
g2d.fillRect(0, 0, width * 2 / 3, height);
g2d.setColor(BASE_COLOR.darker());
g2d.drawRect(0, 0, width * 2 / 3, height);
g2d.setColor(WAFER_COLOR);
g2d.fillRect(width / 8 * 3, 0, width / 8, height);
g2d.setColor(WAFER_COLOR.darker());
g2d.drawRect(width / 8 * 3, 0, width / 8, height);
Area terminals = new Area();
int terminalLength = getClosestOdd(11 * width / 32);
int terminalWidth = getClosestOdd(7 * width / 32);
Area terminal =
new Area(new RoundRectangle2D.Double(width / 16 * 7, 4 * width / 32, terminalLength, terminalWidth,
terminalWidth / 2, terminalWidth / 2));
terminal.subtract(new Area(new RoundRectangle2D.Double(width / 16 * 7 + terminalLength / 4 + 1, 4 * width / 32
+ terminalWidth / 4 + 1, terminalLength / 2, terminalWidth / 2, terminalWidth / 4, terminalWidth / 4)));
terminals.add(terminal);
terminal = new Area(terminal);
terminal.transform(AffineTransform.getTranslateInstance(-terminalLength, terminalWidth + 2 * width / 32));
terminals.add(terminal);
terminal = new Area(terminal);
terminal.transform(AffineTransform.getTranslateInstance(terminalLength, terminalWidth + 2 * width / 32));
terminals.add(terminal);
g2d.setColor(METAL_COLOR);
g2d.fill(terminals);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(terminals);
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public void setControlPoint(Point point, int index) {
this.controlPoints[index].setLocation(point);
// Invalidate the body
body = null;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
@EditableProperty
public LeverSwitchType getType() {
return type;
}
public void setType(LeverSwitchType type) {
this.type = type;
updateControlPoints();
// Invalidate body
this.body = null;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Invalidate the body
body = null;
}
public enum LeverSwitchType {
DP3T("DP3T (Standard Strat)"), _4P5T("4P5T (Super/Mega)"), DP5T("DP5T");
private String title;
private LeverSwitchType(String title) {
this.title = title;
}
@Override
public String toString() {
return title;
}
}
}
@@ -0,0 +1,252 @@
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", autoEdit = false)
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,200 @@
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 java.util.Iterator;
import java.util.List;
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.BomPolicy;
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.BomEntry;
import org.diylc.utils.BomMaker;
@ComponentDescriptor(name = "Bill of Materials", author = "Branislav Stojkovic", category = "Misc", description = "",
instanceNamePrefix = "BOM", zOrder = IDIYComponent.TEXT, stretchable = false, bomPolicy = BomPolicy.NEVER_SHOW,
autoEdit = false)
public class BOM extends AbstractComponent<Void> {
public static Size DEFAULT_SIZE = new Size(10d, SizeUnit.cm);
public static Size SPACING = new Size(0.1d, SizeUnit.in);
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 Size size = DEFAULT_SIZE;
private Point point = new Point(0, 0);
private Color color = COLOR;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
List<BomEntry> bom = BomMaker.getInstance().createBom(project.getComponents());
// Cleanup entries that do not have a value set.
Iterator<BomEntry> iterator = bom.iterator();
while (iterator.hasNext()) {
BomEntry entry = iterator.next();
if (entry.getValue() == null || entry.getName().toLowerCase().contains("bom")) {
iterator.remove();
}
}
g2d.setFont(LABEL_FONT);
g2d.setColor(componentState == ComponentState.DRAGGING || componentState == ComponentState.SELECTED ? SELECTION_COLOR
: getColor());
// Determine maximum name length and maximum value length to calculate
// number of columns.
FontMetrics fontMetrics = g2d.getFontMetrics();
int maxNameWidth = 0;
int maxValueWidth = 0;
int maxHeight = 0;
for (BomEntry entry : bom) {
String valueStr;
if (entry.getValue() == null || entry.getValue().trim().isEmpty()) {
valueStr = "qty " + entry.getQuantity().toString();
} else {
valueStr = entry.getValue().toString();
}
Rectangle2D stringBounds = fontMetrics.getStringBounds(entry.getName(), g2d);
if (stringBounds.getWidth() > maxNameWidth) {
maxNameWidth = (int) stringBounds.getWidth();
}
if (stringBounds.getHeight() > maxHeight) {
maxHeight = (int) stringBounds.getHeight();
}
stringBounds = fontMetrics.getStringBounds(valueStr, g2d);
if (stringBounds.getWidth() > maxValueWidth) {
maxValueWidth = (int) stringBounds.getWidth();
}
if (stringBounds.getHeight() > maxHeight) {
maxHeight = (int) stringBounds.getHeight();
}
}
// Calculate maximum entry size.
int maxEntrySize = maxNameWidth + maxValueWidth + 2 * (int) SPACING.convertToPixels();
int columnCount = (int) size.convertToPixels() / maxEntrySize;
if (columnCount == 0)
columnCount = 1;
int columnWidth = (int) size.convertToPixels() / columnCount;
int entriesPerColumn = (int) Math.ceil(1.d * bom.size() / columnCount);
if (entriesPerColumn == 0) {
g2d.drawString(DEFAULT_TEXT, point.x, point.y);
return;
}
for (int i = 0; i < bom.size(); i++) {
String valueStr;
BomEntry entry = bom.get(i);
if (entry.getValue() == null || entry.getValue().trim().isEmpty()) {
valueStr = "qty " + entry.getQuantity().toString();
} else {
valueStr = entry.getValue().toString();
}
int columnIndex = i / entriesPerColumn;
int rowIndex = i % entriesPerColumn;
int x = point.x + columnIndex * columnWidth;
int y = point.y + rowIndex * maxHeight;
g2d.drawString(entry.getName(), x, y);
x += maxNameWidth + SPACING.convertToPixels();
g2d.drawString(valueStr, x, 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);
}
@EditableProperty(name = "Width")
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
@EditableProperty
public Color getColor() {
if (color == null) {
color = COLOR;
}
return color;
}
public void setColor(Color color) {
this.color = color;
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {}
}
@@ -0,0 +1,151 @@
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.BomPolicy;
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 = "Schematics",
instanceNamePrefix = "GND", description = "Ground schematic symbol", stretchable = false,
zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false)
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;
}
}
}
@@ -0,0 +1,132 @@
package org.diylc.components.misc;
import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import javax.swing.ImageIcon;
import org.diylc.appframework.miscutils.IconImageConverter;
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.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import com.thoughtworks.xstream.annotations.XStreamConverter;
@ComponentDescriptor(name = "Image", author = "Branislav Stojkovic", category = "Misc",
description = "User defined image", instanceNamePrefix = "Img", zOrder = IDIYComponent.COMPONENT,
flexibleZOrder = true, stretchable = false, bomPolicy = BomPolicy.NEVER_SHOW)
public class Image extends AbstractTransparentComponent<Void> {
private static final long serialVersionUID = 1L;
public static String DEFAULT_TEXT = "Double click to edit text";
private static ImageIcon ICON;
private static byte DEFAULT_SCALE = 50;
static {
String name = "image.png";
java.net.URL imgURL = Image.class.getResource(name);
if (imgURL != null) {
ICON = new ImageIcon(imgURL, name);
}
}
private Point point = new Point(0, 0);
@XStreamConverter(IconImageConverter.class)
private ImageIcon image = ICON;
private byte scale = 50;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
double s = 1d * scale / DEFAULT_SCALE;
Shape clip = g2d.getClip().getBounds();
if (!clip.intersects(new Rectangle2D.Double(point.getX(), point.getY(), image.getIconWidth() * s, image
.getIconHeight() * s))) {
return;
}
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
g2d.scale(s, s);
g2d.drawImage(image.getImage(), (int) (point.x / s), (int) (point.y / s), null);
if (componentState == ComponentState.SELECTED) {
g2d.setComposite(oldComposite);
g2d.scale(1 / s, 1 / s);
g2d.setColor(SELECTION_COLOR);
g2d.drawRect(point.x, point.y, (int) (image.getIconWidth() * s), (int) (image.getIconHeight() * s));
}
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.drawImage(ICON.getImage(), point.x, point.y, null);
}
@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);
}
@EditableProperty(defaultable = false)
public ImageIcon getImage() {
return image;
}
public void setImage(ImageIcon image) {
this.image = image;
}
@EditableProperty(defaultable = false)
public byte getScale() {
return scale;
}
public void setScale(byte scale) {
this.scale = scale;
}
@Override
public String getName() {
return super.getName();
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {}
}
@@ -0,0 +1,268 @@
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.common.HorizontalAlignment;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
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.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "Label", author = "Branislav Stojkovic", category = "Misc",
description = "User defined label", instanceNamePrefix = "L", zOrder = IDIYComponent.TEXT, flexibleZOrder = true,
stretchable = false, bomPolicy = BomPolicy.NEVER_SHOW)
public class Label extends AbstractComponent<Void> {
public static String DEFAULT_TEXT = "Double click to edit text";
private static final long serialVersionUID = 1L;
private Point point = new Point(0, 0);
private String text = DEFAULT_TEXT;
private Font font = LABEL_FONT;
private Color color = LABEL_COLOR;
@Deprecated
private boolean center;
private HorizontalAlignment horizontalAlignment = HorizontalAlignment.CENTER;
private VerticalAlignment verticalAlignment = VerticalAlignment.CENTER;
private Orientation orientation = Orientation.DEFAULT;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
g2d.setColor(componentState == ComponentState.SELECTED ? LABEL_COLOR_SELECTED : color);
g2d.setFont(font);
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D rect = fontMetrics.getStringBounds(text, g2d);
int textHeight = (int) rect.getHeight();
int textWidth = (int) rect.getWidth();
int x = point.x;
int y = point.y;
switch (getVerticalAlignment()) {
case CENTER:
y = point.y - textHeight / 2 + fontMetrics.getAscent();
break;
case TOP:
y = point.y - textHeight + fontMetrics.getAscent();
break;
case BOTTOM:
y = point.y + fontMetrics.getAscent();
break;
default:
throw new RuntimeException("Unexpected alignment: " + getVerticalAlignment());
}
switch (getHorizontalAlignment()) {
case CENTER:
x = point.x - textWidth / 2;
break;
case LEFT:
x = point.x;
break;
case RIGHT:
x = point.x - textWidth;
break;
default:
throw new RuntimeException("Unexpected alignment: " + getHorizontalAlignment());
}
switch (getOrientation()) {
case _90:
g2d.rotate(Math.PI / 2, point.x, point.y);
break;
case _180:
g2d.rotate(Math.PI, point.x, point.y);
break;
case _270:
g2d.rotate(Math.PI * 3 / 2, point.x, point.y);
break;
}
g2d.drawString(text, x, y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(LABEL_COLOR);
g2d.setFont(LABEL_FONT.deriveFont(13f * width / 32).deriveFont(Font.PLAIN));
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D rect = fontMetrics.getStringBounds("Abc", g2d);
int textHeight = (int) (rect.getHeight());
int textWidth = (int) (rect.getWidth());
// Center text horizontally and vertically.
int x = (width - textWidth) / 2 + 1;
int y = (height - textHeight) / 2 + fontMetrics.getAscent();
g2d.drawString("Abc", x, y);
}
@EditableProperty
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
// Bold and italic fields are named to be alphabetically after Font. This is
// important!
@EditableProperty(name = "Font Bold")
public boolean getBold() {
return font.isBold();
}
public void setBold(boolean bold) {
if (bold) {
if (font.isItalic()) {
font = font.deriveFont(Font.BOLD + Font.ITALIC);
} else {
font = font.deriveFont(Font.BOLD);
}
} else {
if (font.isItalic()) {
font = font.deriveFont(Font.ITALIC);
} else {
font = font.deriveFont(Font.PLAIN);
}
}
}
@EditableProperty(name = "Font Italic")
public boolean getItalic() {
return font.isItalic();
}
public void setItalic(boolean italic) {
if (italic) {
if (font.isBold()) {
font = font.deriveFont(Font.BOLD + Font.ITALIC);
} else {
font = font.deriveFont(Font.ITALIC);
}
} else {
if (font.isBold()) {
font = font.deriveFont(Font.BOLD);
} else {
font = font.deriveFont(Font.PLAIN);
}
}
}
@EditableProperty
public Orientation getOrientation() {
if (orientation == null) {
orientation = Orientation.DEFAULT;
}
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
}
@EditableProperty(name = "Font Size")
public int getFontSize() {
return font.getSize();
}
public void setFontSize(int size) {
font = font.deriveFont((float) size);
}
@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.WHEN_SELECTED;
}
@Override
public void setControlPoint(Point point, int index) {
this.point.setLocation(point);
}
@EditableProperty(defaultable = false)
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@EditableProperty
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
@EditableProperty(name = "Vertical alignment")
public VerticalAlignment getVerticalAlignment() {
if (verticalAlignment == null) {
verticalAlignment = VerticalAlignment.CENTER;
}
return verticalAlignment;
}
public void setVerticalAlignment(VerticalAlignment verticalAlignment) {
this.verticalAlignment = verticalAlignment;
}
@EditableProperty(name = "Horizontal alignment")
public HorizontalAlignment getHorizontalAlignment() {
if (horizontalAlignment == null) {
horizontalAlignment = HorizontalAlignment.CENTER;
}
return horizontalAlignment;
}
public void setHorizontalAlignment(HorizontalAlignment alignment) {
this.horizontalAlignment = alignment;
}
@Override
public String getName() {
return super.getName();
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {}
}
@@ -0,0 +1,277 @@
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.AffineTransform;
import java.awt.geom.Rectangle2D;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
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.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "PCB Text", author = "Branislav Stojkovic", category = "Misc",
description = "Mirrored text for PCB artwork", instanceNamePrefix = "L", zOrder = IDIYComponent.TRACE,
flexibleZOrder = false, stretchable = false, bomPolicy = BomPolicy.NEVER_SHOW)
public class PCBText extends AbstractComponent<Void> {
public static String DEFAULT_TEXT = "Double click to edit text";
public static Font DEFAULT_FONT = new Font("Courier New", Font.BOLD, 15);
private static final long serialVersionUID = 1L;
private Point point = new Point(0, 0);
private String text = DEFAULT_TEXT;
private Font font = DEFAULT_FONT;
private Color color = LABEL_COLOR;
private HorizontalAlignment horizontalAlignment = HorizontalAlignment.CENTER;
private VerticalAlignment verticalAlignment = VerticalAlignment.CENTER;
private Orientation orientation = Orientation.DEFAULT;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
g2d.setColor(componentState == ComponentState.SELECTED ? LABEL_COLOR_SELECTED : color);
g2d.setFont(font);
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D rect = fontMetrics.getStringBounds(text, g2d);
int textHeight = (int) rect.getHeight();
int textWidth = (int) rect.getWidth();
int x = point.x;
int y = point.y;
switch (getVerticalAlignment()) {
case CENTER:
y = point.y - textHeight / 2 + fontMetrics.getAscent();
break;
case TOP:
y = point.y - textHeight + fontMetrics.getAscent();
break;
case BOTTOM:
y = point.y + fontMetrics.getAscent();
break;
default:
throw new RuntimeException("Unexpected alignment: " + getVerticalAlignment());
}
switch (getHorizontalAlignment()) {
case CENTER:
x = point.x - textWidth / 2;
break;
case LEFT:
x = point.x;
break;
case RIGHT:
x = point.x - textWidth;
break;
default:
throw new RuntimeException("Unexpected alignment: " + getHorizontalAlignment());
}
switch (getOrientation()) {
case _90:
g2d.rotate(Math.PI / 2, point.x, point.y);
break;
case _180:
g2d.rotate(Math.PI, point.x, point.y);
break;
case _270:
g2d.rotate(Math.PI * 3 / 2, point.x, point.y);
break;
}
// Flip horizontally
AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
tx.translate(-2 * x - textWidth, 0);
g2d.transform(tx);
g2d.drawString(text, x, y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(LABEL_COLOR);
g2d.setFont(DEFAULT_FONT.deriveFont(15f * width / 32).deriveFont(Font.BOLD));
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D rect = fontMetrics.getStringBounds("Abc", g2d);
int textHeight = (int) (rect.getHeight());
int textWidth = (int) (rect.getWidth());
// Center text horizontally and vertically.
int x = (width - textWidth) / 2 + 1;
int y = (height - textHeight) / 2 + fontMetrics.getAscent();
g2d.scale(-1, 1);
g2d.translate(-width, 0);
g2d.drawString("Abc", x, y);
}
@EditableProperty
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
// Bold and italic fields are named to be alphabetically after Font. This is
// important!
@EditableProperty(name = "Font Bold")
public boolean getBold() {
return font.isBold();
}
public void setBold(boolean bold) {
if (bold) {
if (font.isItalic()) {
font = font.deriveFont(Font.BOLD + Font.ITALIC);
} else {
font = font.deriveFont(Font.BOLD);
}
} else {
if (font.isItalic()) {
font = font.deriveFont(Font.ITALIC);
} else {
font = font.deriveFont(Font.PLAIN);
}
}
}
@EditableProperty(name = "Font Italic")
public boolean getItalic() {
return font.isItalic();
}
public void setItalic(boolean italic) {
if (italic) {
if (font.isBold()) {
font = font.deriveFont(Font.BOLD + Font.ITALIC);
} else {
font = font.deriveFont(Font.ITALIC);
}
} else {
if (font.isBold()) {
font = font.deriveFont(Font.BOLD);
} else {
font = font.deriveFont(Font.PLAIN);
}
}
}
@EditableProperty
public Orientation getOrientation() {
if (orientation == null) {
orientation = Orientation.DEFAULT;
}
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
}
@EditableProperty(name = "Font Size")
public int getFontSize() {
return font.getSize();
}
public void setFontSize(int size) {
font = font.deriveFont((float) size);
}
@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.WHEN_SELECTED;
}
@Override
public void setControlPoint(Point point, int index) {
this.point.setLocation(point);
}
@EditableProperty(defaultable = false)
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@EditableProperty
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
@EditableProperty(name = "Vertical alignment")
public VerticalAlignment getVerticalAlignment() {
if (verticalAlignment == null) {
verticalAlignment = VerticalAlignment.CENTER;
}
return verticalAlignment;
}
public void setVerticalAlignment(VerticalAlignment verticalAlignment) {
this.verticalAlignment = verticalAlignment;
}
@EditableProperty(name = "Horizontal alignment")
public HorizontalAlignment getHorizontalAlignment() {
if (horizontalAlignment == null) {
horizontalAlignment = HorizontalAlignment.CENTER;
}
return horizontalAlignment;
}
public void setHorizontalAlignment(HorizontalAlignment alignment) {
this.horizontalAlignment = alignment;
}
@Override
public String getName() {
return super.getName();
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,80 @@
package org.diylc.components.passive;
import java.awt.Point;
import org.diylc.common.Orientation;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Resistance;
public abstract class AbstractPotentiometer extends AbstractTransparentComponent<Resistance> {
private static final long serialVersionUID = 1L;
protected Point[] controlPoints;
protected Resistance resistance = null;
protected Orientation orientation = Orientation.DEFAULT;
protected Taper taper = Taper.LIN;
@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);
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public String getValueForDisplay() {
return (resistance == null ? "" : resistance.toString()) + " " + taper.toString();
}
@Override
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Resistance getValue() {
return resistance;
}
@Override
public void setValue(Resistance value) {
this.resistance = value;
}
@EditableProperty
public Taper getTaper() {
return taper;
}
public void setTaper(Taper taper) {
this.taper = taper;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
}
}
@@ -0,0 +1,164 @@
package org.diylc.components.passive;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.Theme;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Electrolytic Capacitor (axial)", author = "Branislav Stojkovic", category = "Passive",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
description = "Axial electrolytic capacitor, similar to Sprague Atom, F&T, etc", zOrder = IDIYComponent.COMPONENT)
public class AxialElectrolyticCapacitor extends AbstractLeadedComponent<Capacitance> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_WIDTH = new Size(1d / 2, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(1d / 8, SizeUnit.in);
public static Color BODY_COLOR = Color.decode("#EAADEA");
public static Color BORDER_COLOR = BODY_COLOR.darker();
public static Color MARKER_COLOR = Color.gray;
public static Color TICK_COLOR = Color.white;
private Capacitance value = null;
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = null;
private Color markerColor = MARKER_COLOR;
private Color tickColor = TICK_COLOR;
private boolean polarized = true;
public AxialElectrolyticCapacitor() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Capacitance getValue() {
return value;
}
public void setValue(Capacitance value) {
this.value = value;
}
@Override
public String getValueForDisplay() {
return getValue().toString() + (getVoltageNew() == null ? "" : " " + getVoltageNew().toString());
}
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR_ICON);
g2d.drawLine(0, height / 2, width, height / 2);
g2d.setColor(BODY_COLOR);
g2d.fillRect(4, height / 2 - 3, width - 8, 6);
g2d.setColor(MARKER_COLOR);
g2d.fillRect(width - 9, height / 2 - 3, 5, 6);
g2d.setColor(TICK_COLOR);
g2d.drawLine(width - 6, height / 2 - 1, width - 6, height / 2 + 1);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(4, height / 2 - 3, width - 8, 6);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@EditableProperty(name = "Marker")
public Color getMarkerColor() {
return markerColor;
}
public void setMarkerColor(Color coverColor) {
this.markerColor = coverColor;
}
@EditableProperty(name = "Tick")
public Color getTickColor() {
return tickColor;
}
public void setTickColor(Color tickColor) {
this.tickColor = tickColor;
}
@EditableProperty(name = "Polarized")
public boolean getPolarized() {
return polarized;
}
public void setPolarized(boolean polarized) {
this.polarized = polarized;
}
@Override
protected Shape getBodyShape() {
return new Rectangle2D.Double(0f, 0f, getLength().convertToPixels(), getClosestOdd(getWidth().convertToPixels()));
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
if (polarized) {
int width = getClosestOdd(getWidth().convertToPixels());
int markerLength = (int) (getLength().convertToPixels() * 0.2);
if (!outlineMode) {
g2d.setColor(markerColor);
g2d.fillRect((int) getLength().convertToPixels() - markerLength, 0, markerLength, width);
}
Color finalTickColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalTickColor = theme.getOutlineColor();
} else {
finalTickColor = tickColor;
}
g2d.setColor(finalTickColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.drawLine((int) getLength().convertToPixels() - markerLength / 2, (int) (width / 2 - width * 0.15),
(int) getLength().convertToPixels() - markerLength / 2, (int) (width / 2 + width * 0.15));
}
}
}
@@ -0,0 +1,108 @@
package org.diylc.components.passive;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Film Capacitor (axial)", author = "Branislav Stojkovic", category = "Passive",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
description = "Axial film capacitor, similar to Mallory 150s", zOrder = IDIYComponent.COMPONENT)
public class AxialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_WIDTH = new Size(1d / 2, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(1d / 8, SizeUnit.in);
public static Color BODY_COLOR = Color.decode("#FFE303");
public static Color BORDER_COLOR = BODY_COLOR.darker();
private Capacitance value = null;
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = null;
public AxialFilmCapacitor() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@Override
protected boolean supportsStandingMode() {
return true;
}
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Capacitance getValue() {
return value;
}
public void setValue(Capacitance value) {
this.value = value;
}
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@Override
public String getValueForDisplay() {
return getValue().toString() + (getVoltageNew() == null ? "" : " " + getVoltageNew().toString());
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR_ICON);
g2d.drawLine(0, height / 2, width, height / 2);
g2d.setColor(BODY_COLOR);
g2d.fillRect(4, height / 2 - 3, width - 8, 6);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(4, height / 2 - 3, width - 8, 6);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@Override
protected Shape getBodyShape() {
return new Rectangle2D.Double(0f, 0f, getLength().convertToPixels(), getClosestOdd(getWidth().convertToPixels()));
}
@EditableProperty(name = "Reverse (standing)")
public boolean getFlipStanding() {
return super.getFlipStanding();
}
}
@@ -0,0 +1,119 @@
package org.diylc.components.passive;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import org.diylc.components.AbstractSchematicLeadedSymbol;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Capacitor (schematic symbol)", author = "Branislav Stojkovic", category = "Schematics",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
description = "Capacitor schematic symbol with an optional polarity sign", zOrder = IDIYComponent.COMPONENT)
public class CapacitorSymbol extends AbstractSchematicLeadedSymbol<Capacitance> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_LENGTH = new Size(0.05, SizeUnit.in);
public static Size DEFAULT_WIDTH = new Size(0.15, SizeUnit.in);
private Capacitance value = null;
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = null;
private boolean polarized = false;
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Capacitance getValue() {
return value;
}
public void setValue(Capacitance value) {
this.value = value;
}
@Override
public String getValueForDisplay() {
return getValue().toString() + (getVoltageNew() == null ? "" : " " + getVoltageNew().toString());
}
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
@EditableProperty
public boolean getPolarized() {
return polarized;
}
public void setPolarized(boolean polarized) {
this.polarized = polarized;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR);
g2d.drawLine(0, height / 2, 13, height / 2);
g2d.drawLine(width - 13, height / 2, width, height / 2);
g2d.setColor(COLOR);
g2d.drawLine(14, height / 2 - 6, 14, height / 2 + 6);
g2d.drawLine(width - 14, height / 2 - 6, width - 14, height / 2 + 6);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_WIDTH;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_LENGTH;
}
@Override
protected Shape getBodyShape() {
GeneralPath polyline = new GeneralPath();
double length = getLength().convertToPixels();
double width = getWidth().convertToPixels();
polyline.moveTo(0, 0);
polyline.lineTo(0, width);
polyline.moveTo(length, 0);
polyline.lineTo(length, width);
return polyline;
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
if (polarized) {
// Draw + sign.
g2d.setColor(getBorderColor());
int plusSize = getClosestOdd(getWidth().convertToPixels() / 4);
int x = -plusSize;
int y = plusSize;
g2d.drawLine(x - plusSize / 2, y, x + plusSize / 2, y);
g2d.drawLine(x, y - plusSize / 2, x, y + plusSize / 2);
}
}
}
@@ -0,0 +1,130 @@
package org.diylc.components.passive;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import org.diylc.components.AbstractSchematicLeadedSymbol;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Current;
import org.diylc.core.measures.Inductance;
import org.diylc.core.measures.Resistance;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Inductor (schematic symbol)", author = "Branislav Stojkovic", category = "Schematics",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "L",
description = "Inductor schematic symbol", zOrder = IDIYComponent.COMPONENT)
public class InductorSymbol extends AbstractSchematicLeadedSymbol<Inductance> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_LENGTH = new Size(0.3, SizeUnit.in);
public static Size DEFAULT_WIDTH = new Size(0.08, SizeUnit.in);
private Inductance value = null;
private Current current = null;
private Resistance resistance = null;
private boolean core = false;
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Inductance getValue() {
return value;
}
public void setValue(Inductance value) {
this.value = value;
}
@EditableProperty
public Current getCurrent() {
return current;
}
public void setCurrent(Current current) {
this.current = current;
}
@EditableProperty
public Resistance getResistance() {
return resistance;
}
public void setResistance(Resistance resistance) {
this.resistance = resistance;
}
@Override
public String getValueForDisplay() {
return getValue().toString() + (getCurrent() == null ? "" : " " + getCurrent().toString());
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR);
g2d.drawLine(0, height / 2, width / 8, height / 2);
g2d.drawLine(width * 7 / 8, height / 2, width, height / 2);
g2d.setColor(COLOR);
GeneralPath polyline = new GeneralPath();
polyline.moveTo(width / 8, height / 2);
polyline.curveTo(width / 8, height / 4, width * 3 / 8, height / 4, width * 3 / 8, height / 2);
polyline.curveTo(width * 3 / 8, height / 4, width * 5 / 8, height / 4, width * 5 / 8, height / 2);
polyline.curveTo(width * 5 / 8, height / 4, width * 7 / 8, height / 4, width * 7 / 8, height / 2);
polyline.moveTo(width / 8, height * 6 / 10);
polyline.lineTo(width * 7 / 8, height * 6 / 10);
polyline.moveTo(width / 8, height * 7 / 10);
polyline.lineTo(width * 7 / 8, height * 7 / 10);
g2d.draw(polyline);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_WIDTH;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_LENGTH;
}
@Override
protected Shape getBodyShape() {
GeneralPath polyline = new GeneralPath();
double length = getLength().convertToPixels();
double width = getWidth().convertToPixels();
double d = length / 10;
polyline.moveTo(0, width / 2);
polyline.curveTo(0, 0, 2 * d, 0, 2 * d, width / 2);
polyline.curveTo(2 * d, 0, 4 * d, 0, 4 * d, width / 2);
polyline.curveTo(4 * d, 0, 6 * d, 0, 6 * d, width / 2);
polyline.curveTo(6 * d, 0, 8 * d, 0, 8 * d, width / 2);
polyline.curveTo(8 * d, 0, 10 * d, 0, 10 * d, width / 2);
if (core) {
polyline.moveTo(0, width * 3 / 4);
polyline.lineTo(length, width * 3 / 4);
polyline.moveTo(0, width * 7 / 8);
polyline.lineTo(length, width * 7 / 8);
}
return polyline;
}
@Override
protected boolean useShapeRectAsPosition() {
return false;
}
@EditableProperty
public boolean getCore() {
return core;
}
public void setCore(boolean core) {
this.core = core;
}
}
@@ -0,0 +1,303 @@
package org.diylc.components.passive;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
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.Theme;
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 = "Potentiometer (panel mount)", author = "Branislav Stojkovic", category = "Passive",
creationMethod = CreationMethod.SINGLE_CLICK, instanceNamePrefix = "VR",
description = "Panel mount potentiometer with solder lugs", zOrder = IDIYComponent.COMPONENT, stretchable = false)
public class PotentiometerPanel extends AbstractPotentiometer {
private static final long serialVersionUID = 1L;
protected static Size BODY_DIAMETER = new Size(1d, SizeUnit.in);
protected static Size SPACING = new Size(0.3d, SizeUnit.in);
protected static Size LUG_DIAMETER = new Size(0.15d, SizeUnit.in);
protected static Color BODY_COLOR = Color.gray.brighter();
protected static Color BORDER_COLOR = Color.gray;
protected Size bodyDiameter = BODY_DIAMETER;
protected Size spacing = SPACING;
protected Size lugDiameter = LUG_DIAMETER;
protected Color bodyColor = BODY_COLOR;
protected Color borderColor = BORDER_COLOR;
// Array of 7 elements: 3 lug connectors, 1 pot body and 3 lugs
transient protected Area[] body = null;
public PotentiometerPanel() {
controlPoints = new Point[] {new Point(0, 0), new Point(0, 0), new Point(0, 0)};
updateControlPoints();
}
protected void updateControlPoints() {
int spacing = (int) this.spacing.convertToPixels();
switch (orientation) {
case DEFAULT:
controlPoints[1].setLocation(controlPoints[0].x + spacing, controlPoints[0].y);
controlPoints[2].setLocation(controlPoints[0].x + 2 * spacing, controlPoints[0].y);
break;
case _90:
controlPoints[1].setLocation(controlPoints[0].x, controlPoints[0].y + spacing);
controlPoints[2].setLocation(controlPoints[0].x, controlPoints[0].y + 2 * spacing);
break;
case _180:
controlPoints[1].setLocation(controlPoints[0].x - spacing, controlPoints[0].y);
controlPoints[2].setLocation(controlPoints[0].x - 2 * spacing, controlPoints[0].y);
break;
case _270:
controlPoints[1].setLocation(controlPoints[0].x, controlPoints[0].y - spacing);
controlPoints[2].setLocation(controlPoints[0].x, controlPoints[0].y - 2 * spacing);
break;
default:
break;
}
}
public Area[] getBody() {
int spacing = (int) this.spacing.convertToPixels();
int diameter = getClosestOdd(bodyDiameter.convertToPixels());
if (body == null) {
body = new Area[7];
// Add lugs.
int lugDiameter = getClosestOdd(this.lugDiameter.convertToPixels());
int holeDiameter = getClosestOdd(this.lugDiameter.convertToPixels() / 2);
for (int i = 0; i < 3; i++) {
Area area =
new Area(new Ellipse2D.Double(controlPoints[i].x - lugDiameter / 2, controlPoints[i].y - lugDiameter / 2,
lugDiameter, lugDiameter));
body[4 + i] = area;
}
switch (orientation) {
case DEFAULT:
body[3] =
new Area(new Ellipse2D.Double(controlPoints[0].x + spacing - diameter / 2, controlPoints[0].y - spacing
/ 2 - diameter, diameter, diameter));
for (int i = 0; i < 3; i++) {
body[i] =
new Area(new Rectangle2D.Double(controlPoints[i].x - holeDiameter / 2, controlPoints[i].y
- (spacing + diameter) / 2, holeDiameter, (spacing + diameter) / 2));
}
break;
case _90:
body[3] =
new Area(new Ellipse2D.Double(controlPoints[0].x + spacing / 2, controlPoints[0].y + spacing - diameter
/ 2, diameter, diameter));
for (int i = 0; i < 3; i++) {
body[i] =
new Area(new Rectangle2D.Double(controlPoints[i].x, controlPoints[i].y - holeDiameter / 2,
(spacing + diameter) / 2, holeDiameter));
}
break;
case _180:
body[3] =
new Area(new Ellipse2D.Double(controlPoints[0].x - spacing - diameter / 2, controlPoints[0].y + spacing
/ 2, diameter, diameter));
for (int i = 0; i < 3; i++) {
body[i] =
new Area(new Rectangle2D.Double(controlPoints[i].x - holeDiameter / 2, controlPoints[i].y,
holeDiameter, (spacing + diameter) / 2));
}
break;
case _270:
body[3] =
new Area(new Ellipse2D.Double(controlPoints[0].x - spacing / 2 - diameter, controlPoints[0].y - spacing
- diameter / 2, diameter, diameter));
for (int i = 0; i < 3; i++) {
body[i] =
new Area(new Rectangle2D.Double(controlPoints[i].x - (spacing + diameter) / 2, controlPoints[i].y
- holeDiameter / 2, (spacing + diameter) / 2, holeDiameter));
}
break;
default:
break;
}
for (int i = 0; i < 3; i++) {
for (int j = 3; j < 7; j++) {
body[i].subtract(body[j]);
}
}
// Make holes in the lugs.
for (int i = 0; i < 3; i++) {
body[4 + i].subtract(new Area(new Ellipse2D.Double(controlPoints[i].x - holeDiameter / 2, controlPoints[i].y
- holeDiameter / 2, holeDiameter, holeDiameter)));
}
}
return body;
}
@Override
public void setControlPoint(Point point, int index) {
super.setControlPoint(point, index);
body = null;
}
@Override
public void setOrientation(Orientation orientation) {
super.setOrientation(orientation);
updateControlPoints();
body = null;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
for (Area shape : getBody()) {
if (shape != null) {
g2d.setColor(bodyColor);
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
if (!outlineMode) {
g2d.fill(shape);
}
g2d.setComposite(oldComposite);
Color finalBorderColor;
if (outlineMode) {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: theme.getOutlineColor();
} else {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor;
}
g2d.setColor(finalBorderColor);
g2d.draw(shape);
}
}
// Draw caption.
g2d.setFont(LABEL_FONT);
Color finalLabelColor;
if (outlineMode) {
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);
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D bodyRect = getBody()[3].getBounds2D();
Rectangle2D rect = fontMetrics.getStringBounds(getName(), g2d);
int textHeight = (int) rect.getHeight();
int textWidth = (int) rect.getWidth();
int panelHeight = (int) bodyRect.getHeight();
int panelWidth = (int) bodyRect.getWidth();
int x = (panelWidth - textWidth) / 2;
int y = panelHeight / 2 - textHeight + fontMetrics.getAscent();
g2d.drawString(getName(), (int) (bodyRect.getX() + x), (int) (bodyRect.getY() + y));
// Draw value.
rect = fontMetrics.getStringBounds(getValueForDisplay(), g2d);
textHeight = (int) rect.getHeight();
textWidth = (int) rect.getWidth();
x = (panelWidth - textWidth) / 2;
y = panelHeight / 2 + fontMetrics.getAscent();
g2d.drawString(getValueForDisplay(), (int) (bodyRect.getX() + x), (int) (bodyRect.getY() + y));
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int margin = 4 * width / 32;
int spacing = width / 3 - 1;
g2d.setColor(BORDER_COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2 * width / 32));
g2d.drawLine(width / 2 - spacing, height / 2, width / 2 - spacing, height - margin);
g2d.drawLine(width / 2 + spacing, height / 2, width / 2 + spacing, height - margin);
g2d.drawLine(width / 2, height / 2, width / 2, height - margin);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(4 * width / 32));
g2d.drawLine(width / 2 - spacing, height - margin, width / 2 - spacing, height - margin);
g2d.drawLine(width / 2 + spacing, height - margin, width / 2 + spacing, height - margin);
g2d.drawLine(width / 2, height - margin, width / 2, height - margin);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.setColor(BODY_COLOR);
g2d.fillOval(margin, margin / 2, width - 2 * margin, height - 2 * margin);
g2d.setColor(BORDER_COLOR);
g2d.drawOval(margin, margin / 2, width - 2 * margin, height - 2 * margin);
}
@EditableProperty
public Size getSpacing() {
return spacing;
}
public void setSpacing(Size spacing) {
this.spacing = spacing;
updateControlPoints();
body = null;
}
@EditableProperty(name = "Diameter")
public Size getBodyDiameter() {
return bodyDiameter;
}
public void setBodyDiameter(Size bodyDiameter) {
this.bodyDiameter = bodyDiameter;
body = null;
}
@EditableProperty(name = "Lug size")
public Size getLugDiameter() {
return lugDiameter;
}
public void setLugDiameter(Size lugDiameter) {
this.lugDiameter = lugDiameter;
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;
}
}
@@ -0,0 +1,112 @@
package org.diylc.components.passive;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.components.semiconductors.AbstractTransistorSymbol;
@ComponentDescriptor(name = "Potentiometer Symbol", author = "MCbx", category = "Schematics",
instanceNamePrefix = " VR", description = "Potentiometer symbol", stretchable = false,
zOrder = IDIYComponent.COMPONENT, rotatable = true)
public class PotentiometerSymbol extends AbstractTransistorSymbol {
private static final long serialVersionUID = 1L;
public PotentiometerSymbol() {
this.color = Color.blue;
}
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 * 2);
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing * 2 + pinSpacing / 2);
polyline.lineTo(x + pinSpacing * 2 - pinSpacing / 4, (y - pinSpacing * 2) + pinSpacing / 2 + pinSpacing / 4);
polyline.lineTo(x + pinSpacing * 2 + pinSpacing / 4, (y - pinSpacing * 2) + 2 * pinSpacing / 2);
polyline.lineTo(x + pinSpacing * 2 - pinSpacing / 4, (y - pinSpacing * 2) + 3 * pinSpacing / 2 - pinSpacing / 8);
polyline.lineTo(x + pinSpacing * 2 + pinSpacing / 4, (y - pinSpacing * 2) + 4 * pinSpacing / 2 - pinSpacing / 4);
polyline.lineTo(x + pinSpacing * 2 - pinSpacing / 4, (y - pinSpacing * 2) + 5 * pinSpacing / 2 - pinSpacing / 3
- pinSpacing / 16);
polyline.lineTo(x + pinSpacing * 2 + pinSpacing / 4, (y - pinSpacing * 2) + 6 * pinSpacing / 2 - pinSpacing / 2
+ pinSpacing / 16);
polyline.lineTo(x + pinSpacing * 2 - pinSpacing / 4, (y - pinSpacing * 2) + 7 * pinSpacing / 2 - pinSpacing / 2
- pinSpacing / 16);
polyline.lineTo(x + pinSpacing * 2 + pinSpacing / 4, (y - pinSpacing * 2) + 7 * pinSpacing / 2 - pinSpacing / 2
+ pinSpacing / 4);
polyline.lineTo(x + pinSpacing * 2, (y - pinSpacing * 2) + 7 * pinSpacing / 2);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing * 2);
polyline.moveTo(x, y);
polyline.lineTo(x + pinSpacing * 2 - pinSpacing / 2, y);
body[1] = polyline;
polyline = new GeneralPath();
body[0] = polyline;
polyline = new GeneralPath();
polyline.moveTo(x + pinSpacing * 2 - pinSpacing / 3, y);
polyline.lineTo(x + pinSpacing * 2 - pinSpacing * 2 / 3, y - pinSpacing / 3);
polyline.lineTo(x + pinSpacing * 2 - pinSpacing * 2 / 3, y + pinSpacing / 3);
polyline.lineTo(x + pinSpacing * 2 - pinSpacing / 3, y);
body[2] = polyline;
}
return body;
}
@Override
protected int getLabelX(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics, boolean outlineMode) {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
if (controlPoints[0].x < controlPoints[1].x && controlPoints[0].x < controlPoints[2].x)
return controlPoints[1].x + pinSpacing / 3;
if (controlPoints[0].y < controlPoints[1].y && controlPoints[0].y < controlPoints[2].y)
return controlPoints[0].x - (int) (textRect.getWidth() / 2);
if (controlPoints[0].x > controlPoints[1].x && controlPoints[0].x > controlPoints[2].x)
return controlPoints[1].x - pinSpacing / 2 - (int) textRect.getWidth();
if (controlPoints[0].y > controlPoints[1].y && controlPoints[0].y > controlPoints[2].y)
return controlPoints[0].x - (int) (textRect.getWidth() / 2);
return 2 * ((int) (shapeRect.getWidth() - textRect.getWidth()) / 2 + (int) shapeRect.getX());
}
@Override
protected int getLabelY(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics, boolean outlineMode) {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
if (controlPoints[0].x < controlPoints[1].x && controlPoints[0].x < controlPoints[2].x)
return controlPoints[0].y;
if (controlPoints[0].y < controlPoints[1].y && controlPoints[0].y < controlPoints[2].y)
return controlPoints[1].y + pinSpacing * 2 / 3;
if (controlPoints[0].x > controlPoints[1].x && controlPoints[0].x > controlPoints[2].x)
return controlPoints[0].y;
if (controlPoints[0].y > controlPoints[1].y && controlPoints[0].y > controlPoints[2].y)
return controlPoints[1].y - pinSpacing * 2 / 3;
return 2 * ((int) (shapeRect.getHeight() - textRect.getHeight()) / 2 + fontMetrics.getAscent() + (int) shapeRect
.getY());
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(Color.blue);
g2d.drawLine(0, height / 2, 4, height / 2);
g2d.drawLine(width - 4, height / 2, width, height / 2);
g2d.drawPolyline(new int[] {4, 6, 10, 14, 18, 22, 26, 28}, new int[] {height / 2, height / 2 + 2, height / 2 - 2,
height / 2 + 2, height / 2 - 2, height / 2 + 2, height / 2 - 2, height / 2}, 8);
g2d.drawPolyline(new int[] {width / 2, width / 2 - 2}, new int[] {height, height / 2 + 2}, 2);
g2d.fill(new Polygon(new int[] {width / 2 - 4, width / 2 + 2, width / 2 - 2}, new int[] {height / 2 + 6,
height / 2 + 6, height / 2 + 2}, 3));
}
}
@@ -0,0 +1,28 @@
package org.diylc.components.passive;
import org.diylc.core.measures.Resistance;
public class PotentiometerValue {
private Resistance resistance;
private Taper taper;
public PotentiometerValue(Resistance resistance, Taper taper) {
super();
this.resistance = resistance;
this.taper = taper;
}
public Resistance getResistance() {
return resistance;
}
public Taper getTaper() {
return taper;
}
@Override
public String toString() {
return resistance.toString() + " " + taper.toString();
}
}
@@ -0,0 +1,56 @@
package org.diylc.components.passive;
import org.diylc.core.measures.PowerUnit;
public enum Power {
EIGHT("1/8W"), QUARTER("1/4W"), HALF("1/2W"), ONE("1W"), TWO("2W"), FIVE("5W"), TEN("10W"), FIFTY("50W"), HUNDRED(
"100W");
String label;
Power(String label) {
this.label = label;
}
@Override
public String toString() {
return label;
}
public org.diylc.core.measures.Power convertToNewFormat() {
org.diylc.core.measures.Power powerNew;
switch (this) {
case EIGHT:
powerNew = new org.diylc.core.measures.Power(1 / 8d, PowerUnit.W);
break;
case FIVE:
powerNew = new org.diylc.core.measures.Power(5d, PowerUnit.W);
break;
case FIFTY:
powerNew = new org.diylc.core.measures.Power(50d, PowerUnit.W);
break;
case HALF:
powerNew = new org.diylc.core.measures.Power(1 / 2d, PowerUnit.W);
break;
case HUNDRED:
powerNew = new org.diylc.core.measures.Power(100d, PowerUnit.W);
break;
case ONE:
powerNew = new org.diylc.core.measures.Power(1d, PowerUnit.W);
break;
case QUARTER:
powerNew = new org.diylc.core.measures.Power(1 / 4d, PowerUnit.W);
break;
case TEN:
powerNew = new org.diylc.core.measures.Power(10d, PowerUnit.W);
break;
case TWO:
powerNew = new org.diylc.core.measures.Power(2d, PowerUnit.W);
break;
default:
powerNew = new org.diylc.core.measures.Power(1 / 2d, PowerUnit.W);
}
return powerNew;
}
}
@@ -0,0 +1,97 @@
package org.diylc.components.passive;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import org.diylc.components.AbstractRadialComponent;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Ceramic Capacitor (radial)", author = "Branislav Stojkovic", category = "Passive",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
description = "Standard radial ceramic capacitor", zOrder = IDIYComponent.COMPONENT)
public class RadialCeramicDiskCapacitor extends AbstractRadialComponent<Capacitance> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_WIDTH = new Size(1d / 4, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(1d / 8, SizeUnit.in);
public static Color BODY_COLOR = Color.decode("#F0E68C");
public static Color BORDER_COLOR = BODY_COLOR.darker();
private Capacitance value = null;
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = null;
public RadialCeramicDiskCapacitor() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Capacitance getValue() {
return value;
}
public void setValue(Capacitance value) {
this.value = value;
}
@Override
public String getValueForDisplay() {
return getValue().toString() + (getVoltageNew() == null ? "" : " " + getVoltageNew().toString());
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
@Deprecated
public Voltage getVoltage() {
return voltage;
}
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR_ICON);
g2d.drawLine(0, height / 2, width, height / 2);
g2d.setColor(BODY_COLOR);
g2d.fillOval(4, height / 2 - 3, width - 8, 6);
g2d.setColor(BORDER_COLOR);
g2d.drawOval(4, height / 2 - 3, width - 8, 6);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@Override
protected Shape getBodyShape() {
return new Ellipse2D.Double(0f, 0f, getLength().convertToPixels(), getClosestOdd(getWidth().convertToPixels()));
}
}
@@ -0,0 +1,266 @@
package org.diylc.components.passive;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractRadialComponent;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.Theme;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Electrolytic Capacitor", author = "Branislav Stojkovic", category = "Passive",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
description = "Vertical mounted electrolytic capacitor, polarized or bipolar", zOrder = IDIYComponent.COMPONENT)
public class RadialElectrolytic extends AbstractRadialComponent<Capacitance> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_SIZE = new Size(1d / 4, SizeUnit.in);
public static Color BODY_COLOR = Color.decode("#EAADEA");
public static Color BORDER_COLOR = BODY_COLOR.darker();
public static Color MARKER_COLOR = Color.gray;
public static Color TICK_COLOR = Color.white;
public static Size HEIGHT = new Size(0.4d, SizeUnit.in);
public static Size EDGE_RADIUS = new Size(1d, SizeUnit.mm);
private Capacitance value = null;
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = null;
private Color markerColor = MARKER_COLOR;
private Color tickColor = TICK_COLOR;
private boolean polarized = true;
private boolean folded = false;
private Size height = HEIGHT;
private boolean invert = false;
public RadialElectrolytic() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Capacitance getValue() {
return value;
}
public void setValue(Capacitance value) {
this.value = value;
}
@Override
public String getValueForDisplay() {
return getValue().toString() + (getVoltageNew() == null ? "" : " " + getVoltageNew().toString());
}
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(BODY_COLOR);
int margin = 3;
Ellipse2D body =
new Ellipse2D.Double(margin, margin, getClosestOdd(width - 2 * margin), getClosestOdd(width - 2 * margin));
g2d.fill(body);
Area marker = new Area(body);
marker.subtract(new Area(new Rectangle2D.Double(margin, margin, width - 4 * margin, getClosestOdd(width - 2
* margin))));
g2d.setColor(MARKER_COLOR);
g2d.fill(marker);
g2d.setColor(TICK_COLOR);
g2d.drawLine(width - 2 * margin, height / 2 - 2, width - 2 * margin, height / 2 + 2);
g2d.setColor(BORDER_COLOR);
g2d.draw(body);
// g2d.setColor(COVER_COLOR.darker());
// g2d.drawLine(innerMargin + 2, innerMargin + 2, width - innerMargin -
// 2, width - innerMargin
// - 2);
// g2d.drawLine(innerMargin + 2, width - innerMargin - 2, width -
// innerMargin - 2,
// innerMargin + 2);
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
int height = (int) getHeight().convertToPixels();
if (polarized) {
int totalDiameter = getClosestOdd(getLength().convertToPixels());
if (!outlineMode) {
if (folded) {
Area area = new Area(getBodyShape());
if (invert) {
area.subtract(new Area(new Rectangle2D.Double(totalDiameter * 0.2, -height, totalDiameter, height * 2)));
} else {
area.subtract(new Area(new Rectangle2D.Double(0, -height, totalDiameter * 0.8, height * 2)));
}
g2d.setColor(markerColor);
g2d.fill(area);
} else {
Area area = new Area(getBodyShape());
if (invert) {
area.subtract(new Area(new Rectangle2D.Double(totalDiameter * 0.2, 0, totalDiameter, totalDiameter)));
} else {
area.subtract(new Area(new Rectangle2D.Double(0, 0, totalDiameter * 0.8, totalDiameter)));
}
g2d.setColor(markerColor);
g2d.fill(area);
}
}
Color finalTickColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalTickColor = theme.getOutlineColor();
} else {
finalTickColor = tickColor;
}
g2d.setColor(finalTickColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
if (folded) {
int tickLength = height / 7;
for (int i = 0; i < 3; i++) {
g2d.drawLine((int) (totalDiameter * (invert ? 0.08 : 0.92)), -height / 2 + tickLength + i * tickLength * 2,
(int) (totalDiameter * (invert ? 0.08 : 0.92)), -height / 2 + tickLength + i * tickLength * 2
+ tickLength);
}
} else {
g2d.drawLine((int) (totalDiameter * (invert ? 0.1 : 0.9)), totalDiameter / 2 - (int) (totalDiameter * 0.05),
(int) (totalDiameter * (invert ? 0.1 : 0.9)), totalDiameter / 2 + (int) (totalDiameter * 0.05));
}
}
// int coverDiameter = getClosestOdd(totalDiameter * 3 / 4);
// g2d.setColor(coverColor);
// int position = (totalDiameter - coverDiameter) / 2;
// g2d.fillOval(position, position, coverDiameter, coverDiameter);
// g2d.setColor(coverColor.darker());
// g2d.drawLine(position + coverDiameter / 5, position + coverDiameter /
// 5, position + 4
// * coverDiameter / 5, position + 4 * coverDiameter / 5);
// g2d.drawLine(position + coverDiameter / 5, position + 4 *
// coverDiameter / 5, position + 4
// * coverDiameter / 5, position + coverDiameter / 5);
}
@Override
protected Size getDefaultWidth() {
return null;
}
@Override
public Size getWidth() {
return super.getWidth();
}
@Override
protected Size getDefaultLength() {
// We'll reuse width property to set the diameter.
return DEFAULT_SIZE;
}
@EditableProperty(name = "Diameter")
@Override
public Size getLength() {
return super.getLength();
}
@EditableProperty(name = "Marker")
public Color getMarkerColor() {
return markerColor;
}
public void setMarkerColor(Color coverColor) {
this.markerColor = coverColor;
}
@EditableProperty(name = "Tick")
public Color getTickColor() {
return tickColor;
}
public void setTickColor(Color tickColor) {
this.tickColor = tickColor;
}
@EditableProperty(name = "Polarized")
public boolean getPolarized() {
return polarized;
}
public void setPolarized(boolean polarized) {
this.polarized = polarized;
}
@EditableProperty
public boolean getFolded() {
return folded;
}
public void setFolded(boolean folded) {
this.folded = folded;
}
@EditableProperty
public Size getHeight() {
if (height == null) {
height = HEIGHT;
}
return height;
}
public void setHeight(Size height) {
this.height = height;
}
@EditableProperty(name = "Invert polarity")
public boolean getInvert() {
return invert;
}
public void setInvert(boolean invert) {
this.invert = invert;
}
@Override
protected Shape getBodyShape() {
double height = (int) getHeight().convertToPixels();
double diameter = (int) getLength().convertToPixels();
if (folded) {
return new RoundRectangle2D.Double(0f, -height / 2 - LEAD_THICKNESS.convertToPixels() / 2,
getClosestOdd(diameter), getClosestOdd(height), EDGE_RADIUS.convertToPixels(), EDGE_RADIUS.convertToPixels());
}
return new Ellipse2D.Double(0f, 0f, getClosestOdd(diameter), getClosestOdd(diameter));
}
}
@@ -0,0 +1,100 @@
package org.diylc.components.passive;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import org.diylc.components.AbstractRadialComponent;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Film Capacitor (radial)", author = "Branislav Stojkovic", category = "Passive",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C",
description = "Radial film capacitor, similar to Sprague Orange Drop", zOrder = IDIYComponent.COMPONENT)
public class RadialFilmCapacitor extends AbstractRadialComponent<Capacitance> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_WIDTH = new Size(1d / 4, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(1d / 8, SizeUnit.in);
public static Color BODY_COLOR = Color.decode("#FF8000");
public static Color BORDER_COLOR = BODY_COLOR.darker();
private Capacitance value = null;
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = null;
public RadialFilmCapacitor() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Capacitance getValue() {
return value;
}
public void setValue(Capacitance value) {
this.value = value;
}
@Override
public String getValueForDisplay() {
return getValue().toString() + (getVoltageNew() == null ? "" : " " + getVoltageNew().toString());
}
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR_ICON);
g2d.drawLine(0, height / 2, width, height / 2);
g2d.setColor(BODY_COLOR);
g2d.fillRoundRect(4, height / 2 - 3, width - 8, 6, 5, 5);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(4, height / 2 - 3, width - 8, 6, 5, 5);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@Override
protected Shape getBodyShape() {
double radius = getWidth().convertToPixels() * 0.7;
return new RoundRectangle2D.Double(0f, 0f, getLength().convertToPixels(), getClosestOdd(getWidth()
.convertToPixels()), radius, radius);
}
}
@@ -0,0 +1,157 @@
package org.diylc.components.passive;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import org.diylc.common.ObjectCache;
import org.diylc.common.ResistorColorCode;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Resistance;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Resistor", author = "Branislav Stojkovic", category = "Passive",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "R", description = "Resistor layout symbol",
zOrder = IDIYComponent.COMPONENT)
public class Resistor extends AbstractLeadedComponent<Resistance> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_WIDTH = new Size(1d / 2, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(1d / 8, SizeUnit.in);
public static Color BODY_COLOR = Color.decode("#82CFFD");
public static Color BORDER_COLOR = BODY_COLOR.darker();
public static int BAND_SPACING = 5;
public static int FIRST_BAND = 4;
private Resistance value = null;
@Deprecated
private Power power = Power.HALF;
private org.diylc.core.measures.Power powerNew = null;
private ResistorColorCode colorCode = ResistorColorCode._5_BAND;
public Resistor() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@Override
protected boolean supportsStandingMode() {
return true;
}
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Resistance getValue() {
return value;
}
public void setValue(Resistance value) {
this.value = value;
}
@Override
public String getValueForDisplay() {
return getValue().toString() + (getPowerNew() == null ? "" : " " + getPowerNew().toString());
}
@Deprecated
public Power getPower() {
return power;
}
@Deprecated
public void setPower(Power power) {
this.power = power;
}
@EditableProperty(name = "Power rating")
public org.diylc.core.measures.Power getPowerNew() {
return powerNew;
}
public void setPowerNew(org.diylc.core.measures.Power powerNew) {
this.powerNew = powerNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR_ICON);
g2d.drawLine(0, height / 2, width, height / 2);
g2d.setColor(BODY_COLOR);
g2d.fillRect(4, height / 2 - 3, width - 8, 6);
g2d.setColor(Color.red);
g2d.drawLine(7, height / 2 - 3, 7, height / 2 + 3);
g2d.setColor(Color.orange);
g2d.drawLine(11, height / 2 - 3, 11, height / 2 + 3);
g2d.setColor(Color.black);
g2d.drawLine(15, height / 2 - 3, 15, height / 2 + 3);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(4, height / 2 - 3, width - 8, 6);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@EditableProperty(name = "Color code")
public ResistorColorCode getColorCode() {
return colorCode;
}
public void setColorCode(ResistorColorCode colorCode) {
this.colorCode = colorCode;
}
@Override
protected Shape getBodyShape() {
return new Rectangle2D.Double(0f, 0f, getLength().convertToPixels(), getClosestOdd(getWidth().convertToPixels()));
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
// int width = getWidth().convertToPixels();
if (colorCode == ResistorColorCode.NONE || outlineMode || value == null) {
return;
}
int height = getClosestOdd(getWidth().convertToPixels());
Color[] bands = value.getColorCode(colorCode);
int x = FIRST_BAND;
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
for (int i = 0; i < bands.length; i++) {
g2d.setColor(bands[i]);
g2d.drawLine(x, 1, x, height - 1);
x += BAND_SPACING;
}
}
@Override
protected int getLabelOffset(int bodyWidth, int labelWidth) {
if (value == null)
return 0;
Color[] bands = value.getColorCode(colorCode);
int bandArea = FIRST_BAND + BAND_SPACING * (bands.length - 1);
// Only offset the label if overlaping with the band area.
if (labelWidth > bodyWidth - 2 * bandArea)
return bandArea / 2;
return 0;
}
@EditableProperty(name = "Reverse (standing)")
public boolean getFlipStanding() {
return super.getFlipStanding();
}
}
@@ -0,0 +1,109 @@
package org.diylc.components.passive;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import org.diylc.components.AbstractSchematicLeadedSymbol;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.PowerUnit;
import org.diylc.core.measures.Resistance;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Resistor (schematic symbol)", author = "Branislav Stojkovic", category = "Schematics",
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;
public static Size DEFAULT_LENGTH = new Size(0.3, SizeUnit.in);
public static Size DEFAULT_WIDTH = new Size(0.08, SizeUnit.in);
private Resistance value = null;
@Deprecated
private Power power = Power.HALF;
private org.diylc.core.measures.Power powerNew = new org.diylc.core.measures.Power(0.5, PowerUnit.W);
@EditableProperty
public Resistance getValue() {
return value;
}
public void setValue(Resistance value) {
this.value = value;
}
@Override
public String getValueForDisplay() {
return getValue().toString() + (getPowerNew() == null ? "" : " " + getPowerNew().toString());
}
@Deprecated
public Power getPower() {
return power;
}
@Deprecated
public void setPower(Power power) {
this.power = power;
}
@EditableProperty(name = "Power rating")
public org.diylc.core.measures.Power getPowerNew() {
// Backward compatibility
if (powerNew == null) {
powerNew = power.convertToNewFormat();
// Clear old value, don't need it anymore
power = null;
}
return powerNew;
}
public void setPowerNew(org.diylc.core.measures.Power powerNew) {
this.powerNew = powerNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR);
g2d.drawLine(0, height / 2, 4, height / 2);
g2d.drawLine(width - 4, height / 2, width, height / 2);
g2d.setColor(COLOR);
g2d.drawPolyline(new int[] {4, 6, 10, 14, 18, 22, 26, 28}, new int[] {height / 2, height / 2 + 2, height / 2 - 2,
height / 2 + 2, height / 2 - 2, height / 2 + 2, height / 2 - 2, height / 2}, 8);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_WIDTH;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_LENGTH;
}
@Override
protected Shape getBodyShape() {
GeneralPath polyline = new GeneralPath();
double length = getLength().convertToPixels();
double width = getWidth().convertToPixels();
polyline.moveTo(0, width / 2);
polyline.lineTo(length / 16, width);
polyline.lineTo(3 * length / 16, 0);
polyline.lineTo(5 * length / 16, width);
polyline.lineTo(7 * length / 16, 0);
polyline.lineTo(9 * length / 16, width);
polyline.lineTo(11 * length / 16, 0);
polyline.lineTo(13 * length / 16, width);
polyline.lineTo(15 * length / 16, 0);
polyline.lineTo(length, width / 2);
return polyline;
}
}
@@ -0,0 +1,28 @@
package org.diylc.components.passive;
import org.diylc.core.measures.Resistance;
public class ResistorValue {
private Resistance resistance;
private Power power;
public ResistorValue(Resistance resistance, Power power) {
super();
this.resistance = resistance;
this.power = power;
}
public Resistance getResistance() {
return resistance;
}
public Power getPower() {
return power;
}
@Override
public String toString() {
return resistance.toString() + power.toString();
}
}
@@ -0,0 +1,11 @@
package org.diylc.components.passive;
public enum Taper {
LIN, LOG, REV_LOG, W, S;
@Override
public String toString() {
return name().substring(0, 1).toUpperCase() + name().substring(1).toLowerCase().replace("_", " ");
}
}
@@ -0,0 +1,427 @@
package org.diylc.components.passive;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
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;
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.Theme;
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 = "Trimmer Potentiometer", author = "Branislav Stojkovic", category = "Passive",
creationMethod = CreationMethod.SINGLE_CLICK, instanceNamePrefix = "VR",
description = "Various types of board mounted trimmer potentiometers", zOrder = IDIYComponent.COMPONENT,
stretchable = false)
public class TrimmerPotentiometer extends AbstractPotentiometer {
private static final long serialVersionUID = 1L;
protected static Size FLAT_BODY_SIZE = new Size(9.5d, SizeUnit.mm);
protected static Size FLAT_SHAFT_SIZE = new Size(4d, SizeUnit.mm);
protected static Size VERTICAL_BODY_LENGTH = new Size(9.5d, SizeUnit.mm);
protected static Size VERTICAL_BODY_WIDTH = new Size(4.5d, SizeUnit.mm);
protected static Size SPACING = new Size(0.1d, SizeUnit.in);
private static Color BODY_COLOR = Color.decode("#FFFFE0");
private static Color BORDER_COLOR = Color.decode("#8E8E38");
private static Color SHAFT_COLOR = Color.decode("#FFFFE0");
private static Color SHAFT_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(0.03d, SizeUnit.in);
protected static Display DISPLAY = Display.NAME;
protected Color bodyColor = BODY_COLOR;
protected Color borderColor = BORDER_COLOR;
protected static Display display = DISPLAY;
// Array of 7 elements: 3 lug connectors, 1 pot body and 3 lugs
transient protected Shape[] body = null;
protected TrimmerType type = TrimmerType.FLAT_SMALL;
public TrimmerPotentiometer() {
controlPoints = new Point[] {new Point(0, 0), new Point(0, 0), new Point(0, 0)};
updateControlPoints();
}
protected void updateControlPoints() {
int spacing = (int) SPACING.convertToPixels();
int dx1 = 0;
int dy1 = 0;
int dx2 = 0;
int dy2 = 0;
switch (orientation) {
case DEFAULT:
switch (type) {
case FLAT_SMALL:
dx1 = 2 * spacing;
dy1 = spacing;
dx2 = 0;
dy2 = 2 * spacing;
break;
case FLAT_LARGE:
dx1 = 4 * spacing;
dy1 = spacing;
dx2 = 0;
dy2 = 2 * spacing;
break;
case VERTICAL_INLINE:
dx1 = 0;
dy1 = spacing;
dx2 = 0;
dy2 = 2 * spacing;
break;
case VERTICAL_OFFSET:
dx1 = spacing;
dy1 = spacing;
dx2 = 0;
dy2 = 2 * spacing;
break;
}
break;
case _90:
switch (type) {
case FLAT_SMALL:
dx1 = -spacing;
dy1 = 2 * spacing;
dx2 = -2 * spacing;
dy2 = 0;
break;
case FLAT_LARGE:
dx1 = -spacing;
dy1 = 4 * spacing;
dx2 = -2 * spacing;
dy2 = 0;
break;
case VERTICAL_INLINE:
dx1 = -spacing;
dy1 = 0;
dx2 = -2 * spacing;
dy2 = 0;
break;
case VERTICAL_OFFSET:
dx1 = -spacing;
dy1 = spacing;
dx2 = -2 * spacing;
dy2 = 0;
break;
}
break;
case _180:
switch (type) {
case FLAT_SMALL:
dx1 = -2 * spacing;
dy1 = -spacing;
dx2 = 0;
dy2 = -2 * spacing;
break;
case FLAT_LARGE:
dx1 = -4 * spacing;
dy1 = -spacing;
dx2 = 0;
dy2 = -2 * spacing;
break;
case VERTICAL_INLINE:
dx1 = 0;
dy1 = -spacing;
dx2 = 0;
dy2 = -2 * spacing;
break;
case VERTICAL_OFFSET:
dx1 = -spacing;
dy1 = -spacing;
dx2 = 0;
dy2 = -2 * spacing;
break;
}
break;
case _270:
switch (type) {
case FLAT_SMALL:
dx1 = spacing;
dy1 = -2 * spacing;
dx2 = 2 * spacing;
dy2 = 0;
break;
case FLAT_LARGE:
dx1 = spacing;
dy1 = -4 * spacing;
dx2 = 2 * spacing;
dy2 = 0;
break;
case VERTICAL_INLINE:
dx1 = spacing;
dy1 = 0;
dx2 = 2 * spacing;
dy2 = 0;
break;
case VERTICAL_OFFSET:
dx1 = spacing;
dy1 = -spacing;
dx2 = 2 * spacing;
dy2 = 0;
break;
}
break;
default:
break;
}
controlPoints[1].setLocation(controlPoints[0].x + dx1, controlPoints[0].y + dy1);
controlPoints[2].setLocation(controlPoints[0].x + dx2, controlPoints[0].y + dy2);
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[2];
// Calculate the center point as center of the minimum bounding
// rectangle.
int centerX =
(Math.max(Math.max(controlPoints[0].x, controlPoints[1].x), controlPoints[2].x) + Math.min(
Math.min(controlPoints[0].x, controlPoints[1].x), controlPoints[2].x)) / 2;
int centerY =
(Math.max(Math.max(controlPoints[0].y, controlPoints[1].y), controlPoints[2].y) + Math.min(
Math.min(controlPoints[0].y, controlPoints[1].y), controlPoints[2].y)) / 2;
// Calculate body dimensions based on the selected type.
int length = 0;
int width = 0;
switch (type) {
case FLAT_LARGE:
case FLAT_SMALL:
length = getClosestOdd(FLAT_BODY_SIZE.convertToPixels());
width = length;
int shaftSize = getClosestOdd(FLAT_SHAFT_SIZE.convertToPixels());
Area shaft =
new Area(new Ellipse2D.Double(centerX - shaftSize / 2, centerY - shaftSize / 2, shaftSize, shaftSize));
Area slot =
new Area(new Rectangle2D.Double(centerX - shaftSize / 2, centerY - shaftSize / 8, shaftSize,
shaftSize / 4));
slot.transform(AffineTransform.getRotateInstance(Math.PI / 4, centerX, centerY));
shaft.subtract(slot);
body[1] = shaft;
break;
case VERTICAL_INLINE:
case VERTICAL_OFFSET:
length = getClosestOdd(VERTICAL_BODY_LENGTH.convertToPixels());
width = getClosestOdd(VERTICAL_BODY_WIDTH.convertToPixels());
break;
}
if (orientation == Orientation.DEFAULT || orientation == Orientation._180) {
int p = length;
length = width;
width = p;
}
body[0] = new Rectangle2D.Double(centerX - length / 2, centerY - width / 2, length, width);
}
return body;
}
@Override
public void setControlPoint(Point point, int index) {
super.setControlPoint(point, index);
body = null;
}
@Override
public void setOrientation(Orientation orientation) {
super.setOrientation(orientation);
updateControlPoints();
body = null;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
Shape mainShape = getBody()[0];
Shape shaftShape = getBody()[1];
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
if (mainShape != null) {
g2d.setColor(bodyColor);
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
}
if (!outlineMode) {
g2d.fill(mainShape);
}
if (!outlineMode && shaftShape != null) {
g2d.setColor(SHAFT_COLOR);
g2d.fill(shaftShape);
g2d.setColor(SHAFT_BORDER_COLOR);
g2d.draw(shaftShape);
}
g2d.setComposite(oldComposite);
Color finalBorderColor;
if (outlineMode) {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: theme.getOutlineColor();
} else {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor;
}
g2d.setColor(finalBorderColor);
g2d.draw(mainShape);
}
// Draw pins.
int pinSize = getClosestOdd(PIN_SIZE.convertToPixels());
for (Point point : controlPoints) {
if (!outlineMode) {
g2d.setColor(PIN_COLOR);
g2d.fillOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR);
g2d.drawOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
// Draw label.
g2d.setFont(LABEL_FONT);
Color finalLabelColor;
if (outlineMode) {
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);
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D bodyRect = getBody()[0].getBounds2D();
Rectangle2D rect = fontMetrics.getStringBounds(getName(), g2d);
int textHeight = (int) rect.getHeight();
int textWidth = (int) rect.getWidth();
int panelHeight = (int) bodyRect.getHeight();
int panelWidth = (int) bodyRect.getWidth();
int x = (panelWidth - textWidth) / 2;
int y = (panelHeight - textHeight) / 2 + fontMetrics.getAscent();
String label = "";
label = (getDisplay() == Display.NAME) ? getName() : getValue().toString();
if (getDisplay() == Display.NONE) {
label = "";
}
if (getDisplay() == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
g2d.drawString(label, (int) (bodyRect.getX() + x), (int) (bodyRect.getY() + y));
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int margin = 4;
g2d.setColor(BODY_COLOR);
g2d.fillRect(margin, margin, width - 2 * margin, width - 2 * margin);
g2d.setColor(BORDER_COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawRect(margin, margin, width - 2 * margin, width - 2 * margin);
int shaftSize = 11;
int slotSize = 2;
Area area =
new Area(new Ellipse2D.Double(width / 2 - shaftSize / 2, width / 2 - shaftSize / 2, shaftSize, shaftSize));
Area slot = new Area(new Rectangle2D.Double(0, width / 2 - slotSize / 2, width, slotSize));
slot.transform(AffineTransform.getRotateInstance(Math.PI / 4, width / 2, width / 2));
area.subtract(slot);
g2d.setColor(SHAFT_COLOR);
g2d.fill(area);
g2d.setColor(SHAFT_BORDER_COLOR);
g2d.draw(area);
int pinSize = 3;
g2d.setColor(PIN_COLOR);
g2d.fillOval(margin - pinSize / 2, 10 - pinSize / 2, pinSize, pinSize);
g2d.setColor(PIN_BORDER_COLOR);
g2d.drawOval(margin - pinSize / 2, 10 - pinSize / 2, pinSize, pinSize);
g2d.setColor(PIN_COLOR);
g2d.fillOval(margin - pinSize / 2, 21 - pinSize / 2, pinSize, pinSize);
g2d.setColor(PIN_BORDER_COLOR);
g2d.drawOval(margin - pinSize / 2, 21 - pinSize / 2, pinSize, pinSize);
g2d.setColor(PIN_COLOR);
g2d.fillOval(width - margin - pinSize / 2, width / 2 - pinSize / 2, pinSize, pinSize);
g2d.setColor(PIN_BORDER_COLOR);
g2d.drawOval(width - margin - pinSize / 2, width / 2 - pinSize / 2, pinSize, pinSize);
}
@EditableProperty(name = "Body")
public Color getBodyColor() {
return bodyColor;
}
public void setBodyColor(Color bodyColor) {
this.bodyColor = bodyColor;
}
@EditableProperty
public Display getDisplay() {
if (display == null) {
display = Display.VALUE;
}
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
@EditableProperty(name = "Border")
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@EditableProperty
public TrimmerType getType() {
return type;
}
public void setType(TrimmerType type) {
this.type = type;
updateControlPoints();
body = null;
}
public static enum TrimmerType {
FLAT_LARGE, FLAT_SMALL, VERTICAL_INLINE, VERTICAL_OFFSET;
@Override
public String toString() {
return name().substring(0, 1) + name().substring(1).toLowerCase().replace("_", " ");
}
}
}
@@ -0,0 +1,58 @@
package org.diylc.components.passive;
import org.diylc.core.measures.VoltageUnit;
public enum Voltage {
_16V, _25V, _63V, _100V, _160V, _250V, _300V, _350V, _400V, _500V, _630V, _1KV;
@Override
public String toString() {
return name().replace("_", "");
}
public org.diylc.core.measures.Voltage convertToNewFormat() {
org.diylc.core.measures.Voltage voltageNew;
switch (this) {
case _100V:
voltageNew = new org.diylc.core.measures.Voltage(100d, VoltageUnit.V);
break;
case _160V:
voltageNew = new org.diylc.core.measures.Voltage(160d, VoltageUnit.V);
break;
case _16V:
voltageNew = new org.diylc.core.measures.Voltage(16d, VoltageUnit.V);
break;
case _1KV:
voltageNew = new org.diylc.core.measures.Voltage(1d, VoltageUnit.KV);
break;
case _250V:
voltageNew = new org.diylc.core.measures.Voltage(250d, VoltageUnit.V);
break;
case _25V:
voltageNew = new org.diylc.core.measures.Voltage(25d, VoltageUnit.V);
break;
case _300V:
voltageNew = new org.diylc.core.measures.Voltage(300d, VoltageUnit.V);
break;
case _350V:
voltageNew = new org.diylc.core.measures.Voltage(350d, VoltageUnit.V);
break;
case _400V:
voltageNew = new org.diylc.core.measures.Voltage(400d, VoltageUnit.V);
break;
case _500V:
voltageNew = new org.diylc.core.measures.Voltage(500d, VoltageUnit.V);
break;
case _630V:
voltageNew = new org.diylc.core.measures.Voltage(630d, VoltageUnit.V);
break;
case _63V:
voltageNew = new org.diylc.core.measures.Voltage(63d, VoltageUnit.V);
break;
default:
voltageNew = new org.diylc.core.measures.Voltage(100d, VoltageUnit.V);
}
return voltageNew;
}
}
@@ -0,0 +1,84 @@
package org.diylc.components.semiconductors;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import org.diylc.components.AbstractSchematicLeadedSymbol;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
public abstract class AbstractDiodeSymbol extends AbstractSchematicLeadedSymbol<String> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_SIZE = new Size(0.1, SizeUnit.in);
private String value = null;
public AbstractDiodeSymbol() {
super();
this.bodyColor = COLOR;
this.borderColor = null;
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String getValueForDisplay() {
return getValue();
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_SIZE;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_SIZE;
}
@Override
protected Shape getBodyShape() {
double width = getWidth().convertToPixels();
Polygon p =
new Polygon(new int[] {0, 0, (int) (width / Math.sqrt(2))}, new int[] {0, (int) (width), (int) (width / 2)}, 3);
// Area a = new Area(p);
// int bandSize = (int) BAND_SIZE.convertToPixels();
// a.add(new Area(new Rectangle2D.Double((int) (width / Math.sqrt(2)) +
// 1,
// 0, bandSize, (int) width)));
return p;
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {}
@Deprecated
@Override
public Size getLength() {
return super.getLength();
}
@Deprecated
@Override
public Color getBorderColor() {
return super.getBorderColor();
}
@Override
@EditableProperty(name = "Color")
public Color getBodyColor() {
return super.getBodyColor();
}
}
@@ -0,0 +1,231 @@
package org.diylc.components.semiconductors;
import java.awt.Color;
import java.awt.FontMetrics;
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.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.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;
public static SymbolFlipping FLIPPING = SymbolFlipping.NONE;
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 SymbolFlipping flip = FLIPPING;
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 || componentState == ComponentState.DRAGGING) {
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();
int rotation = 0;
// determine rotation using control points
if (controlPoints[1].x == controlPoints[2].x) {
if (controlPoints[0].x > controlPoints[1].x) {
rotation = 180;
}
}
if (controlPoints[1].y == controlPoints[2].y) {
rotation = 90;
if (controlPoints[0].y > controlPoints[1].y) {
rotation = 270;
}
}
AffineTransform old = g2d.getTransform();
g2d.rotate(Math.toRadians(rotation), controlPoints[0].x, controlPoints[0].y);
if (this.flip == SymbolFlipping.Y) {
g2d.translate(0, controlPoints[0].y);
g2d.scale(1, -1);
g2d.translate(0, -1 * controlPoints[0].y);
}
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.draw(body[0]);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.draw(body[1]);
g2d.fill(body[2]);
g2d.setTransform(old);
// 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);
String label = "";
label = display == Display.NAME ? getName() : (getValue() == null ? "" : getValue().toString());
if (display == Display.NONE) {
label = "";
}
if (display == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D textRect = fontMetrics.getStringBounds(label, g2d);
Rectangle shapeRect = body[0].getBounds().union(body[1].getBounds()).union(body[2].getBounds());
drawCenteredText(g2d, label, getLabelX(shapeRect, textRect, fontMetrics, outlineMode),
getLabelY(shapeRect, textRect, fontMetrics, outlineMode), HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
protected int getLabelX(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics, boolean outlineMode) {
return controlPoints[0].x + (int) PIN_SPACING.convertToPixels() * 2;
}
protected int getLabelY(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics, boolean outlineMode) {
return controlPoints[0].y;
}
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 SymbolFlipping getFlip() {
return flip;
}
public void setFlip(SymbolFlipping flip) {
this.flip = flip;
}
@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 = "Schematics",
instanceNamePrefix = "Q", description = "Bipolar junction transistor schematic symbol", stretchable = false,
zOrder = IDIYComponent.COMPONENT, rotatable = true)
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;
}
}
@@ -0,0 +1,507 @@
package org.diylc.components.semiconductors;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
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;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.components.misc.Label;
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 = "DIP IC", author = "Branislav Stojkovic", category = "Semiconductors",
instanceNamePrefix = "IC", description = "Dual-in-line package IC", stretchable = false,
zOrder = IDIYComponent.COMPONENT)
public class DIL_IC extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
public static Color BODY_COLOR = Color.gray;
public static Color BORDER_COLOR = Color.gray.darker();
public static Color PIN_COLOR = Color.decode("#00B2EE");
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
public static Color INDENT_COLOR = Color.gray.darker();
public static Color LABEL_COLOR = Color.white;
public static int EDGE_RADIUS = 6;
public static Size PIN_SIZE = new Size(0.04d, SizeUnit.in);
public static Size INDENT_SIZE = new Size(0.07d, SizeUnit.in);
public static DisplayNumbers DISPLAY_NUMBERS = DisplayNumbers.NO;
private String value = "";
private Orientation orientation = Orientation.DEFAULT;
private PinCount pinCount = PinCount._8;
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;
private Color bodyColor = BODY_COLOR;
private Color borderColor = BORDER_COLOR;
private Color labelColor = LABEL_COLOR;
private Color indentColor = INDENT_COLOR;
private DisplayNumbers displayNumbers = DISPLAY_NUMBERS;
// new Point(0, pinSpacing.convertToPixels()),
// new Point(0, 2 * pinSpacing.convertToPixels()),
// new Point(0, 3 * pinSpacing.convertToPixels()),
// new Point(3 * pinSpacing.convertToPixels(), 0),
// new Point(3 * pinSpacing.convertToPixels(),
// pinSpacing.convertToPixels()),
// new Point(3 * pinSpacing.convertToPixels(), 2 *
// pinSpacing.convertToPixels()),
// new Point(3 * pinSpacing.convertToPixels(), 3 *
// pinSpacing.convertToPixels()) };
transient private Area[] body;
public DIL_IC() {
super();
updateControlPoints();
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Reset body shape.
body = null;
}
@EditableProperty(name = "Pins")
public PinCount getPinCount() {
return pinCount;
}
public void setPinCount(PinCount pinCount) {
this.pinCount = pinCount;
updateControlPoints();
// Reset body shape;
body = null;
}
@EditableProperty(name = "Pin spacing")
public Size getPinSpacing() {
return pinSpacing;
}
public void setPinSpacing(Size pinSpacing) {
this.pinSpacing = pinSpacing;
}
@EditableProperty(name = "Row spacing")
public Size getRowSpacing() {
return rowSpacing;
}
public void setRowSpacing(Size rowSpacing) {
this.rowSpacing = rowSpacing;
updateControlPoints();
// 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() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
private void updateControlPoints() {
Point firstPoint = controlPoints[0];
controlPoints = new Point[pinCount.getValue()];
controlPoints[0] = firstPoint;
int pinSpacing = (int) this.pinSpacing.convertToPixels();
int rowSpacing = (int) this.rowSpacing.convertToPixels();
// Update control points.
int dx1;
int dy1;
int dx2;
int dy2;
for (int i = 0; i < pinCount.getValue() / 2; i++) {
switch (orientation) {
case DEFAULT:
dx1 = 0;
dy1 = i * pinSpacing;
dx2 = rowSpacing;
dy2 = i * pinSpacing;
break;
case _90:
dx1 = -i * pinSpacing;
dy1 = 0;
dx2 = -i * pinSpacing;
dy2 = rowSpacing;
break;
case _180:
dx1 = 0;
dy1 = -i * pinSpacing;
dx2 = -rowSpacing;
dy2 = -i * pinSpacing;
break;
case _270:
dx1 = i * pinSpacing;
dy1 = 0;
dx2 = i * pinSpacing;
dy2 = -rowSpacing;
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
controlPoints[i] = new Point(firstPoint.x + dx1, firstPoint.y + dy1);
controlPoints[i + pinCount.getValue() / 2] = new Point(firstPoint.x + dx2, firstPoint.y + dy2);
}
}
public Area[] getBody() {
if (body == null) {
body = new Area[2];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int width;
int height;
int pinSize = (int) PIN_SIZE.convertToPixels();
int pinSpacing = (int) this.pinSpacing.convertToPixels();
int rowSpacing = (int) this.rowSpacing.convertToPixels();
Area indentation = null;
int indentationSize = getClosestOdd(INDENT_SIZE.convertToPixels());
switch (orientation) {
case DEFAULT:
width = rowSpacing - pinSize;
height = (pinCount.getValue() / 2) * pinSpacing;
x += pinSize / 2;
y -= pinSpacing / 2;
indentation =
new Area(new Ellipse2D.Double(x + width / 2 - indentationSize / 2, y - indentationSize / 2,
indentationSize, indentationSize));
break;
case _90:
width = (pinCount.getValue() / 2) * pinSpacing;
height = rowSpacing - pinSize;
x -= (pinSpacing / 2) + width - pinSpacing;
y += pinSize / 2;
indentation =
new Area(new Ellipse2D.Double(x + width - indentationSize / 2, y + height / 2 - indentationSize / 2,
indentationSize, indentationSize));
break;
case _180:
width = rowSpacing - pinSize;
height = (pinCount.getValue() / 2) * pinSpacing;
x -= rowSpacing - pinSize / 2;
y -= (pinSpacing / 2) + height - pinSpacing;
indentation =
new Area(new Ellipse2D.Double(x + width / 2 - indentationSize / 2, y + height - indentationSize / 2,
indentationSize, indentationSize));
break;
case _270:
width = (pinCount.getValue() / 2) * pinSpacing;
height = rowSpacing - pinSize;
x -= pinSpacing / 2;
y += pinSize / 2 - rowSpacing;
indentation =
new Area(new Ellipse2D.Double(x - indentationSize / 2, y + height / 2 - indentationSize / 2,
indentationSize, indentationSize));
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
body[0] = new Area(new RoundRectangle2D.Double(x, y, width, height, EDGE_RADIUS, EDGE_RADIUS));
body[1] = indentation;
if (indentation != null) {
indentation.intersect(body[0]);
}
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
Area mainArea = getBody()[0];
if (!outlineMode) {
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
for (Point point : controlPoints) {
g2d.setColor(PIN_COLOR);
g2d.fillRect(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
g2d.setColor(PIN_BORDER_COLOR);
g2d.drawRect(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
}
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 : getBodyColor());
g2d.fill(mainArea);
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
: getBorderColor();
}
g2d.setColor(finalBorderColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (outlineMode) {
Area area = new Area(mainArea);
area.subtract(getBody()[1]);
g2d.draw(area);
} else {
g2d.draw(mainArea);
if (getBody()[1] != null) {
g2d.setColor(getIndentColor());
g2d.fill(getBody()[1]);
}
}
// 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
: getLabelColor();
}
g2d.setColor(finalLabelColor);
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
String label = "";
label = (getDisplay() == Display.NAME) ? getName() : getValue();
if (getDisplay() == Display.NONE) {
label = "";
}
if (getDisplay() == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
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(label, x, y);
// draw pin numbers
int pinNo = 0;
int j = 0;
int k = 0;
int pinSize = (int) PIN_SIZE.convertToPixels();
for (Point point : controlPoints) {
pinNo++;
// determine points relative to rotation
int textX1 = point.x - 2 * pinSize;
int textY1 = point.y + pinSize / 2;
int textX2 = point.x + pinSize;
int textY2 = point.y + pinSize / 2;
if (orientation == Orientation._90) {
textX2 = textX2 - pinSize - pinSize / 2;
textY2 = textY2 + pinSize;
textX1 = textX1 + 2 * pinSize - pinSize / 2;
textY1 = textY1 - pinSize;
}
if (orientation == Orientation._180) {
textX1 = textX1 + 3 * pinSize;
textX2 = textX2 - 3 * pinSize;
}
if (orientation == Orientation._270) {
textX1 = textX1 + pinSize + pinSize / 2;
textY1 = textY1 + pinSize;
textX2 = textX2 - pinSize - pinSize / 2;
textY2 = textY2 - pinSize;
}
g2d.setFont(LABEL_FONT.deriveFont((float) (Label.LABEL_FONT.getSize2D() * 0.66)));
if (displayNumbers == DisplayNumbers.DIP) {
if (pinNo > pinCount.getValue() / 2) {
g2d.drawString(Integer.toString(pinCount.getValue() - j), textX1, textY1);
j++;
} else {
g2d.drawString(Integer.toString(pinNo), textX2, textY2);
}
}
if (displayNumbers == DisplayNumbers.CONNECTOR) {
if (pinNo > pinCount.getValue() / 2) {
k++;
g2d.drawString(Integer.toString(pinNo - (pinCount.getValue() / 2) + k), textX1, textY1);
} else {
g2d.drawString(Integer.toString(pinNo + j), textX2, textY2);
j++;
}
}
}
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int radius = 6 * width / 32;
g2d.setColor(BODY_COLOR);
g2d.fillRoundRect(width / 6, 1, 4 * width / 6, height - 4, radius, radius);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(width / 6, 1, 4 * width / 6, height - 4, radius, radius);
int pinSize = 2 * width / 32;
g2d.setColor(PIN_COLOR);
for (int i = 0; i < 4; i++) {
g2d.fillRect(width / 6 - pinSize, (height / 5) * (i + 1) - 1, pinSize, pinSize);
g2d.fillRect(5 * width / 6 + 1, (height / 5) * (i + 1) - 1, pinSize, pinSize);
}
}
@EditableProperty(name = "Body")
public Color getBodyColor() {
if (bodyColor == null) {
bodyColor = BODY_COLOR;
}
return bodyColor;
}
public void setBodyColor(Color bodyColor) {
this.bodyColor = bodyColor;
}
@EditableProperty(name = "Border")
public Color getBorderColor() {
if (borderColor == null) {
borderColor = BORDER_COLOR;
}
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@EditableProperty(name = "Label")
public Color getLabelColor() {
if (labelColor == null) {
labelColor = LABEL_COLOR;
}
return labelColor;
}
public void setLabelColor(Color labelColor) {
this.labelColor = labelColor;
}
@EditableProperty(name = "Indent")
public Color getIndentColor() {
if (indentColor == null) {
indentColor = INDENT_COLOR;
}
return indentColor;
}
public void setIndentColor(Color indentColor) {
this.indentColor = indentColor;
}
@EditableProperty(name = "Display pin numbers")
public DisplayNumbers getDisplayNumbers() {
return displayNumbers;
}
public void setDisplayNumbers(DisplayNumbers numbers) {
this.displayNumbers = numbers;
}
public static enum PinCount {
_4, _6, _8, _10, _12, _14, _16, _18, _20, _22, _24, _26, _28, _30, _32, _34, _36, _38, _40, _42, _44, _46, _48, _50;
@Override
public String toString() {
return name().replace("_", "");
}
public int getValue() {
return Integer.parseInt(toString());
}
}
public enum DisplayNumbers {
NO, DIP, CONNECTOR;
@Override
public String toString() {
return name();
}
}
}
@@ -0,0 +1,121 @@
package org.diylc.components.semiconductors;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.Theme;
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 = "Diode (plastic)", author = "Branislav Stojkovic", category = "Semiconductors",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "D",
description = "Plastic diode, like most rectifier, zener, schottky, etc.", zOrder = IDIYComponent.COMPONENT)
public class DiodePlastic extends AbstractLeadedComponent<String> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_WIDTH = new Size(1d / 4, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(1d / 8, SizeUnit.in);
public static Size MARKER_WIDTH = new Size(1d, SizeUnit.mm);
public static Color BODY_COLOR = Color.darkGray;
public static Color MARKER_COLOR = Color.decode("#DDDDDD");
public static Color LABEL_COLOR = Color.white;
public static Color BORDER_COLOR = BODY_COLOR.darker();
private String value = "";
private Color markerColor = MARKER_COLOR;
public DiodePlastic() {
super();
this.labelColor = LABEL_COLOR;
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@Override
protected boolean supportsStandingMode() {
return true;
}
@Override
public Color getStandingBodyColor() {
return getFlipStanding() ? getBodyColor() : getMarkerColor();
}
@EditableProperty(name = "Reverse (standing)")
public boolean getFlipStanding() {
return super.getFlipStanding();
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR_ICON);
g2d.drawLine(0, height / 2, width, height / 2);
g2d.setColor(BODY_COLOR);
g2d.fillRect(6, height / 2 - 3, width - 12, 6);
g2d.setColor(MARKER_COLOR);
int markerWidth = 4 * width / 32;
g2d.fillRect(width - 6 - markerWidth, height / 2 - 3, markerWidth, 6);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(6, height / 2 - 3, width - 12, 6);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@Override
protected Shape getBodyShape() {
return new Rectangle2D.Double(0f, 0f, getLength().convertToPixels(), getClosestOdd(getWidth().convertToPixels()));
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
Color finalMarkerColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalMarkerColor = theme.getOutlineColor();
} else {
finalMarkerColor = markerColor;
}
g2d.setColor(finalMarkerColor);
int width = (int) getLength().convertToPixels();
int markerWidth = (int) MARKER_WIDTH.convertToPixels();
g2d.fillRect(width - markerWidth, 0, markerWidth, getClosestOdd(getWidth().convertToPixels()));
}
@EditableProperty(name = "Marker")
public Color getMarkerColor() {
return markerColor;
}
public void setMarkerColor(Color markerColor) {
this.markerColor = markerColor;
}
}
@@ -0,0 +1,46 @@
package org.diylc.components.semiconductors;
import java.awt.Graphics2D;
import java.awt.Polygon;
import org.diylc.common.ObjectCache;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Diode (schematic symbol)", author = "Branislav Stojkovic", category = "Schematics",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "D", description = "Diode schematic symbol",
zOrder = IDIYComponent.COMPONENT)
public class DiodeSymbol extends AbstractDiodeSymbol {
private static final long serialVersionUID = 1L;
public static Size BAND_SIZE = new Size(0.01, SizeUnit.in);
public void drawIcon(Graphics2D g2d, int width, int height) {
int size = width * 3 / 8;
int bandSize = 1;
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR);
g2d.drawLine(0, height / 2, (width - size) / 2, height / 2);
g2d.drawLine((int) (width + size / Math.sqrt(2) + bandSize) / 2, height / 2, width, height / 2);
g2d.setColor(COLOR);
g2d.fill(new Polygon(new int[] {(width - size) / 2, (width - size) / 2,
(int) ((width - size) / 2 + size / Math.sqrt(2))}, new int[] {(height - size) / 2, (height + size) / 2,
height / 2}, 3));
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(bandSize));
g2d.drawLine((int) ((width - size) / 2 + size / Math.sqrt(2)), (height - size) / 2,
(int) ((width - size) / 2 + size / Math.sqrt(2)), (height + size) / 2);
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
double width = getWidth().convertToPixels();
int bandSize = (int) BAND_SIZE.convertToPixels();
g2d.setColor(getBodyColor());
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(bandSize));
g2d.drawLine((int) (width / Math.sqrt(2)) + bandSize, 0, (int) (width / Math.sqrt(2) + bandSize), (int) width);
}
}
@@ -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,265 @@
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 = "Schematics",
instanceNamePrefix = "IC", description = "IC symbol with 3 or 5 contacts", stretchable = false,
zOrder = IDIYComponent.COMPONENT, rotatable = false)
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;
String label = "";
label = display == Display.VALUE ? getValue() : getName();
if (display == Display.NONE) {
label = "";
}
if (display == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
drawCenteredText(g2d, label, 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,90 @@
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 = "Schematics",
instanceNamePrefix = "Q", description = "JFET transistor schematic symbol", stretchable = false,
zOrder = IDIYComponent.COMPONENT, rotatable = true)
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,103 @@
package org.diylc.components.semiconductors;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
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 = "LED", author = "Branislav Stojkovic", category = "Semiconductors",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "D", description = "Light Emitting Diode",
zOrder = IDIYComponent.COMPONENT)
public class LED extends AbstractLeadedComponent<String> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_SIZE = new Size(5d, SizeUnit.mm);
public static Color BODY_COLOR = Color.decode("#5DFC0A");
public static Color BORDER_COLOR = BODY_COLOR.darker();
private String value = "";
public LED() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR_ICON);
g2d.drawLine(0, height / 2, width, height / 2);
int margin = 4 * width / 32;
Area area = new Area(new Ellipse2D.Double(margin, margin, width - 2 * margin, width - 2 * margin));
area.intersect(new Area(new Rectangle2D.Double(margin, margin, width - 5 * margin / 2, width - 2 * margin)));
g2d.setColor(BODY_COLOR);
g2d.fill(area);
g2d.setColor(BORDER_COLOR);
g2d.draw(area);
g2d.drawOval(margin * 2 - 1, margin * 2 - 1, width - 4 * margin + 2, width - 4 * margin + 2);
}
@Override
protected Size getDefaultWidth() {
return DEFAULT_SIZE;
}
@Override
protected Size getDefaultLength() {
return DEFAULT_SIZE;
}
@Override
protected Shape getBodyShape() {
int size = getClosestOdd((int) (getLength().convertToPixels() * 1.2));
Area area = new Area(new Ellipse2D.Double(0, 0, size, size));
area.intersect(new Area(new Rectangle2D.Double(0, 0, getLength().convertToPixels() * 1.15, size)));
return area;
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
if (!outlineMode) {
int size = getClosestOdd((int) (getLength().convertToPixels() * 1.2));
int innerSize = getClosestOdd(getLength().convertToPixels());
int x = (size - innerSize) / 2;
Shape s = new Ellipse2D.Double(x, x, innerSize, innerSize);
g2d.setColor(getBorderColor());
g2d.draw(s);
}
}
@EditableProperty(name = "Size")
@Override
public Size getLength() {
return super.getLength();
}
@Override
public Size getWidth() {
return super.getWidth();
}
}
@@ -0,0 +1,57 @@
package org.diylc.components.semiconductors;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.geom.AffineTransform;
import org.diylc.common.ObjectCache;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
@ComponentDescriptor(name = "LED (schematic symbol)", author = "Branislav Stojkovic", category = "Schematics",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "D", description = "Diode schematic symbol",
zOrder = IDIYComponent.COMPONENT)
public class LEDSymbol extends DiodeSymbol {
private static final long serialVersionUID = 1L;
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
AffineTransform tx = g2d.getTransform();
super.drawIcon(g2d, width, height);
int arrowSize = 3 * width / 32;
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
// Go back to original transform
g2d.setTransform(tx);
// g2d.drawLine((width - size) / 2 + size / 8, (height + size) / 2,
// (width - size) / 2 + size
// / 8 + arrowSize, (height + size) / 2 + arrowSize);
g2d.drawLine(width * 9 / 16, height * 10 / 16, width * 9 / 16 + arrowSize, height * 10 / 16);
g2d.drawLine(width * 9 / 16, height * 11 / 16, width * 9 / 16 + arrowSize, height * 11 / 16);
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
super.decorateComponentBody(g2d, outlineMode);
// Draw arrows
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
double width = getWidth().convertToPixels();
double arrowLength = width / 3;
double arrowSize = width / 6;
int d = (int) (width / 3);
int x2 = (int) (d / 2 + Math.cos(Math.PI / 4) * arrowLength);
int y2 = (int) (width + Math.sin(Math.PI / 4) * arrowLength);
g2d.drawLine(d / 2, (int) width, x2 - 2, y2 - 2);
g2d.fillPolygon(new Polygon(new int[] {x2, x2, (int) (x2 - arrowSize)}, new int[] {y2, (int) (y2 - arrowSize), y2},
3));
x2 = (int) (3 * d / 2 + Math.cos(Math.PI / 4) * arrowLength);
y2 = (int) (width + Math.sin(Math.PI / 4) * arrowLength);
g2d.drawLine(3 * d / 2, (int) width, x2 - 2, y2 - 2);
g2d.fillPolygon(new Polygon(new int[] {x2, x2, (int) (x2 - arrowSize)}, new int[] {y2, (int) (y2 - arrowSize), y2},
3));
}
}
@@ -0,0 +1,93 @@
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 = "Schematics",
instanceNamePrefix = "Q", description = "MOSFET transistor schematic symbol", stretchable = false,
zOrder = IDIYComponent.COMPONENT, rotatable = true)
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;
}
}
@@ -0,0 +1,412 @@
package org.diylc.components.semiconductors;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
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;
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 = "SIP IC", author = "Branislav Stojkovic", category = "Semiconductors",
instanceNamePrefix = "IC", description = "Single-in-line package IC", stretchable = false,
zOrder = IDIYComponent.COMPONENT)
public class SIL_IC extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
public static Color BODY_COLOR = Color.gray;
public static Color BORDER_COLOR = Color.gray.darker();
public static Color PIN_COLOR = Color.decode("#00B2EE");
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
public static Color INDENT_COLOR = Color.gray.darker();
public static Color LABEL_COLOR = Color.white;
public static int EDGE_RADIUS = 6;
public static Size PIN_SIZE = new Size(0.8d, SizeUnit.mm);
public static Size INDENT_SIZE = new Size(0.07d, SizeUnit.in);
public static Size THICKNESS = new Size(0.13d, SizeUnit.in);
private String value = "";
private Orientation orientation = Orientation.DEFAULT;
private PinCount pinCount = PinCount._8;
private Size pinSpacing = new Size(0.1d, SizeUnit.in);
private Point[] controlPoints = new Point[] {new Point(0, 0)};
protected Display display = Display.NAME;
private Color bodyColor = BODY_COLOR;
private Color borderColor = BORDER_COLOR;
private Color labelColor = LABEL_COLOR;
private Color indentColor = INDENT_COLOR;
// new Point(0, pinSpacing.convertToPixels()),
// new Point(0, 2 * pinSpacing.convertToPixels()),
// new Point(0, 3 * pinSpacing.convertToPixels()),
// new Point(3 * pinSpacing.convertToPixels(), 0),
// new Point(3 * pinSpacing.convertToPixels(),
// pinSpacing.convertToPixels()),
// new Point(3 * pinSpacing.convertToPixels(), 2 *
// pinSpacing.convertToPixels()),
// new Point(3 * pinSpacing.convertToPixels(), 3 *
// pinSpacing.convertToPixels()) };
transient private Area[] body;
public SIL_IC() {
super();
updateControlPoints();
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Reset body shape.
body = null;
}
@EditableProperty(name = "Pins")
public PinCount getPinCount() {
return pinCount;
}
public void setPinCount(PinCount pinCount) {
this.pinCount = pinCount;
updateControlPoints();
// Reset body shape;
body = null;
}
@EditableProperty(name = "Pin spacing")
public Size getPinSpacing() {
return pinSpacing;
}
public void setPinSpacing(Size pinSpacing) {
this.pinSpacing = pinSpacing;
}
@EditableProperty
public Display getDisplay() {
if (display == null) {
display = Display.VALUE;
}
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
private void updateControlPoints() {
Point firstPoint = controlPoints[0];
controlPoints = new Point[pinCount.getValue()];
controlPoints[0] = firstPoint;
int pinSpacing = (int) this.pinSpacing.convertToPixels();
// Update control points.
int dx1;
int dy1;
for (int i = 0; i < pinCount.getValue(); i++) {
switch (orientation) {
case DEFAULT:
dx1 = 0;
dy1 = i * pinSpacing;
break;
case _90:
dx1 = -i * pinSpacing;
dy1 = 0;
break;
case _180:
dx1 = 0;
dy1 = -i * pinSpacing;
break;
case _270:
dx1 = i * pinSpacing;
dy1 = 0;
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
controlPoints[i] = new Point(firstPoint.x + dx1, firstPoint.y + dy1);
}
}
public Area[] getBody() {
if (body == null) {
body = new Area[2];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int thickness = getClosestOdd(THICKNESS.convertToPixels());
int width;
int height;
int pinSpacing = (int) this.pinSpacing.convertToPixels();
Area indentation = null;
int indentationSize = getClosestOdd(INDENT_SIZE.convertToPixels());
switch (orientation) {
case DEFAULT:
width = thickness;
height = pinCount.getValue() * pinSpacing;
x -= thickness / 2;
y -= pinSpacing / 2;
indentation =
new Area(new Ellipse2D.Double(x + width / 2 - indentationSize / 2, y - indentationSize / 2,
indentationSize, indentationSize));
break;
case _90:
width = pinCount.getValue() * pinSpacing;
height = thickness;
x -= (pinSpacing / 2) + width - pinSpacing;
y -= thickness / 2;
indentation =
new Area(new Ellipse2D.Double(x + width - indentationSize / 2, y + height / 2 - indentationSize / 2,
indentationSize, indentationSize));
break;
case _180:
width = thickness;
height = pinCount.getValue() * pinSpacing;
x -= thickness / 2;
y -= (pinSpacing / 2) + height - pinSpacing;
indentation =
new Area(new Ellipse2D.Double(x + width / 2 - indentationSize / 2, y + height - indentationSize / 2,
indentationSize, indentationSize));
break;
case _270:
width = pinCount.getValue() * pinSpacing;
height = thickness;
x -= pinSpacing / 2;
y -= thickness / 2;
indentation =
new Area(new Ellipse2D.Double(x - indentationSize / 2, y + height / 2 - indentationSize / 2,
indentationSize, indentationSize));
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
body[0] = new Area(new RoundRectangle2D.Double(x, y, width, height, EDGE_RADIUS, EDGE_RADIUS));
body[1] = indentation;
if (indentation != null) {
indentation.intersect(body[0]);
}
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
Area mainArea = getBody()[0];
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 : getBodyColor());
g2d.fill(mainArea);
g2d.setComposite(oldComposite);
if (!outlineMode) {
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
for (Point point : controlPoints) {
g2d.setColor(PIN_COLOR);
g2d.fillOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
g2d.setColor(PIN_BORDER_COLOR);
g2d.drawOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
}
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
: getBorderColor();
}
g2d.setColor(finalBorderColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (outlineMode) {
Area area = new Area(mainArea);
area.subtract(getBody()[1]);
g2d.draw(area);
} else {
g2d.draw(mainArea);
if (getBody()[1] != null) {
g2d.setColor(getIndentColor());
g2d.fill(getBody()[1]);
}
}
// 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
: getLabelColor();
}
g2d.setColor(finalLabelColor);
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
String label = "";
label = (getDisplay() == Display.NAME) ? getName() : getValue();
if (getDisplay() == Display.NONE) {
label = "";
}
if (getDisplay() == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
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(label, x, y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int radius = 6 * width / 32;
int thickness = getClosestOdd(width / 3);
g2d.rotate(Math.PI / 4, width / 2, height / 2);
g2d.setColor(BODY_COLOR);
g2d.fillRoundRect((width - thickness) / 2, 0, thickness, height, radius, radius);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect((width - thickness) / 2, 0, thickness, height, radius, radius);
int pinSize = 2 * width / 32;
g2d.setColor(PIN_COLOR);
for (int i = 0; i < 4; i++) {
g2d.fillOval(width / 2 - pinSize / 2, (height / 5) * (i + 1), pinSize, pinSize);
}
}
@EditableProperty(name = "Body")
public Color getBodyColor() {
if (bodyColor == null) {
bodyColor = BODY_COLOR;
}
return bodyColor;
}
public void setBodyColor(Color bodyColor) {
this.bodyColor = bodyColor;
}
@EditableProperty(name = "Border")
public Color getBorderColor() {
if (borderColor == null) {
borderColor = BORDER_COLOR;
}
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@EditableProperty(name = "Label")
public Color getLabelColor() {
if (labelColor == null) {
labelColor = LABEL_COLOR;
}
return labelColor;
}
public void setLabelColor(Color labelColor) {
this.labelColor = labelColor;
}
@EditableProperty(name = "Indent")
public Color getIndentColor() {
if (indentColor == null) {
indentColor = INDENT_COLOR;
}
return indentColor;
}
public void setIndentColor(Color indentColor) {
this.indentColor = indentColor;
}
public static enum PinCount {
_2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20;
@Override
public String toString() {
return name().replace("_", "");
}
public int getValue() {
return Integer.parseInt(toString());
}
}
}
@@ -0,0 +1,61 @@
package org.diylc.components.semiconductors;
import java.awt.Graphics2D;
import java.awt.Polygon;
import org.diylc.common.ObjectCache;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Schottky diode (schematic symbol)", author = "Branislav Stojkovic",
category = "Schematics", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "D",
description = "Schottky diode schematic symbol", zOrder = IDIYComponent.COMPONENT)
public class SchottkyDiodeSymbol extends AbstractDiodeSymbol {
private static final long serialVersionUID = 1L;
public static Size BAND_SIZE = new Size(0.01, SizeUnit.in);
public void drawIcon(Graphics2D g2d, int width, int height) {
int size = width * 3 / 8;
int bandSize = 1;
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR);
g2d.drawLine(0, height / 2, (width - size) / 2, height / 2);
g2d.drawLine((int) (width + size / Math.sqrt(2) + bandSize) / 2, height / 2, width, height / 2);
g2d.setColor(COLOR);
g2d.fill(new Polygon(new int[] {(width - size) / 2, (width - size) / 2,
(int) ((width - size) / 2 + size / Math.sqrt(2))}, new int[] {(height - size) / 2, (height + size) / 2,
height / 2}, 3));
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(bandSize));
g2d.drawLine((int) ((width - size) / 2 + size / Math.sqrt(2)), (height - size) / 2,
(int) ((width - size) / 2 + size / Math.sqrt(2)), (height + size) / 2);
int finSize = 2 * width / 32;
g2d.drawLine((int) ((width - size) / 2 + size / Math.sqrt(2)), (height - size) / 2, (int) ((width - size) / 2
+ size / Math.sqrt(2) + finSize), (height - size) / 2);
g2d.drawLine((int) ((width - size) / 2 + size / Math.sqrt(2) + finSize), (height - size) / 2, (int) ((width - size)
/ 2 + size / Math.sqrt(2) + finSize), (height - size) / 2 + finSize);
g2d.drawLine((int) ((width - size) / 2 + size / Math.sqrt(2)), (height + size) / 2, (int) ((width - size) / 2
+ size / Math.sqrt(2) - finSize), (height + size) / 2);
g2d.drawLine((int) ((width - size) / 2 + size / Math.sqrt(2) - finSize), (height + size) / 2, (int) ((width - size)
/ 2 + size / Math.sqrt(2) - finSize), (height + size) / 2 - finSize);
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
double width = getWidth().convertToPixels();
int finSize = (int) (width / 6);
int bandSize = (int) BAND_SIZE.convertToPixels();
g2d.setColor(getBodyColor());
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(bandSize));
g2d.drawPolyline(new int[] {(int) (width / Math.sqrt(2) + bandSize) + finSize + 1,
(int) (width / Math.sqrt(2) + bandSize) + finSize + 1, (int) (width / Math.sqrt(2) + bandSize),
(int) (width / Math.sqrt(2) + bandSize), (int) (width / Math.sqrt(2) + bandSize) - finSize - 1,
(int) (width / Math.sqrt(2) + bandSize) - finSize - 1}, new int[] {(int) finSize, 0, 0, (int) width,
(int) width, (int) (width - finSize)}, 6);
}
}
@@ -0,0 +1,18 @@
package org.diylc.components.semiconductors;
public enum SymbolFlipping {
NONE, Y;
@Override
public String toString() {
switch (this) {
case Y:
return "Y-axis";
case NONE:
return "None";
default:
return name();
}
}
}
@@ -0,0 +1,336 @@
package org.diylc.components.semiconductors;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
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;
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 = "Transistor (TO-1 package)", author = "Branislav Stojkovic", category = "Semiconductors",
instanceNamePrefix = "Q", description = "Transistor with small metal body", stretchable = false,
zOrder = IDIYComponent.COMPONENT)
public class TransistorTO1 extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
public static Color BODY_COLOR = Color.decode("#D0E0EF");
public static Color BORDER_COLOR = BODY_COLOR.darker();
public static Color PIN_COLOR = Color.decode("#00B2EE");
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
public static Color LABEL_COLOR = Color.black;
public static Size PIN_SIZE = new Size(0.03d, SizeUnit.in);
public static Size PIN_SPACING = new Size(0.05d, SizeUnit.in);
public static Size BODY_DIAMETER = new Size(0.24d, SizeUnit.in);
public static Size BODY_LENGTH = new Size(0.4d, SizeUnit.in);
public static Size EDGE_RADIUS = new Size(2d, SizeUnit.mm);
private String value = "";
private Orientation orientation = Orientation.DEFAULT;
private Point[] controlPoints = new Point[] {new Point(0, 0), new Point(0, 0), new Point(0, 0)};
transient private Area body;
private Color bodyColor = BODY_COLOR;
private Color borderColor = BORDER_COLOR;
private Color labelColor = LABEL_COLOR;
protected Display display = Display.NAME;
private boolean folded = false;
private Size pinSpacing = PIN_SPACING;
public TransistorTO1() {
super();
updateControlPoints();
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Reset body shape;
body = null;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
private void updateControlPoints() {
int pinSpacing = (int) getPinSpacing().convertToPixels();
// Update control points.
int x = controlPoints[0].x;
int y = controlPoints[0].y;
switch (orientation) {
case DEFAULT:
controlPoints[1].setLocation(x - (folded ? 0 : pinSpacing), y + pinSpacing);
controlPoints[2].setLocation(x, y + 2 * pinSpacing);
break;
case _90:
controlPoints[1].setLocation(x - pinSpacing, y - (folded ? 0 : pinSpacing));
controlPoints[2].setLocation(x - 2 * pinSpacing, y);
break;
case _180:
controlPoints[1].setLocation(x + (folded ? 0 : pinSpacing), y - pinSpacing);
controlPoints[2].setLocation(x, y - 2 * pinSpacing);
break;
case _270:
controlPoints[1].setLocation(x + pinSpacing, y + (folded ? 0 : pinSpacing));
controlPoints[2].setLocation(x + 2 * pinSpacing, y);
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
}
public Area getBody() {
if (body == null) {
int x = (controlPoints[0].x + controlPoints[1].x + controlPoints[2].x) / 3;
int y = (controlPoints[0].y + controlPoints[1].y + controlPoints[2].y) / 3;
int bodyDiameter = getClosestOdd(BODY_DIAMETER.convertToPixels());
int bodyLength = getClosestOdd(BODY_LENGTH.convertToPixels());
int edgeRadius = (int) EDGE_RADIUS.convertToPixels();
if (folded) {
switch (orientation) {
case DEFAULT:
body =
new Area(new RoundRectangle2D.Double(x - bodyLength, y - bodyDiameter / 2, bodyLength, bodyDiameter,
edgeRadius, edgeRadius));
body.add(new Area(new Rectangle2D.Double(x - bodyLength / 2, y - bodyDiameter / 2, bodyLength / 2,
bodyDiameter)));
break;
case _90:
body =
new Area(new RoundRectangle2D.Double(x - bodyDiameter / 2, y - bodyLength, bodyDiameter, bodyLength,
edgeRadius, edgeRadius));
body.add(new Area(new Rectangle2D.Double(x - bodyDiameter / 2, y - bodyLength / 2, bodyDiameter,
bodyLength / 2)));
break;
case _180:
body =
new Area(new RoundRectangle2D.Double(x, y - bodyDiameter / 2, bodyLength, bodyDiameter, edgeRadius,
edgeRadius));
body.add(new Area(new Rectangle2D.Double(x, y - bodyDiameter / 2, bodyLength / 2, bodyDiameter)));
break;
case _270:
body =
new Area(new RoundRectangle2D.Double(x - bodyDiameter / 2, y, bodyDiameter, bodyLength, edgeRadius,
edgeRadius));
body.add(new Area(new Rectangle2D.Double(x - bodyDiameter / 2, y, bodyDiameter, bodyLength / 2)));
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
} else {
body = new Area(new Ellipse2D.Double(x - bodyDiameter / 2, y - bodyDiameter / 2, bodyDiameter, bodyDiameter));
}
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
Area mainArea = getBody();
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 : bodyColor);
g2d.fill(mainArea);
g2d.setComposite(oldComposite);
Color finalBorderColor;
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
if (outlineMode) {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: theme.getOutlineColor();
} else {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor;
}
g2d.setColor(finalBorderColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.draw(mainArea);
for (Point point : controlPoints) {
if (!outlineMode) {
g2d.setColor(PIN_COLOR);
g2d.fillOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR);
g2d.drawOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
// Draw label.
g2d.setFont(LABEL_FONT);
Color finalLabelColor;
if (outlineMode) {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: theme.getOutlineColor();
} else {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: getLabelColor();
}
g2d.setColor(finalLabelColor);
String label = "";
label = (getDisplay() == Display.NAME) ? getName() : getValue();
if (getDisplay() == Display.NONE) {
label = "";
}
if (getDisplay() == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
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(label, x, y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int margin = 2 * width / 32;
Area area = new Area(new Ellipse2D.Double(margin / 2, margin, width - 2 * margin, width - 2 * margin));
g2d.setColor(BODY_COLOR);
g2d.fill(area);
g2d.setColor(BORDER_COLOR);
g2d.draw(area);
g2d.setColor(PIN_COLOR);
int pinSize = 2 * width / 32;
for (int i = 0; i < 3; i++) {
g2d.fillOval((i == 1 ? width * 3 / 8 : width / 2) - pinSize / 2, (height / 4) * (i + 1), pinSize, pinSize);
}
}
@EditableProperty(name = "Body")
public Color getBodyColor() {
return bodyColor;
}
public void setBodyColor(Color bodyColor) {
this.bodyColor = bodyColor;
}
@EditableProperty
public boolean getFolded() {
return folded;
}
public void setFolded(boolean folded) {
this.folded = folded;
updateControlPoints();
// Reset body shape;
body = null;
}
@EditableProperty(name = "Pin spacing")
public Size getPinSpacing() {
return pinSpacing;
}
public void setPinSpacing(Size pinSpacing) {
this.pinSpacing = pinSpacing;
updateControlPoints();
// Reset body shape;
body = null;
}
@EditableProperty(name = "Border")
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@EditableProperty(name = "Label")
public Color getLabelColor() {
return labelColor;
}
public void setLabelColor(Color labelColor) {
this.labelColor = labelColor;
}
@EditableProperty
public Display getDisplay() {
if (display == null) {
display = Display.NAME;
}
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
}
@@ -0,0 +1,477 @@
package org.diylc.components.semiconductors;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
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 java.awt.geom.Rectangle2D;
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;
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 = "Transistor (TO-220 package)", author = "Branislav Stojkovic", category = "Semiconductors",
instanceNamePrefix = "Q", description = "Transistors with metal tab for heat sink mounting", stretchable = false,
zOrder = IDIYComponent.COMPONENT)
public class TransistorTO220 extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
public static Color BODY_COLOR = Color.gray;
public static Color BORDER_COLOR = Color.gray.darker();
public static Color PIN_COLOR = Color.decode("#00B2EE");
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
public static Color TAB_COLOR = Color.decode("#C3E4ED");
public static Color TAB_BORDER_COLOR = TAB_COLOR.darker();
public static Color LABEL_COLOR = Color.white;
public static Size PIN_SIZE = new Size(0.03d, SizeUnit.in);
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
public static Size BODY_WIDTH = new Size(0.4d, SizeUnit.in);
public static Size BODY_THICKNESS = new Size(4.5d, SizeUnit.mm);
public static Size BODY_HEIGHT = new Size(9d, SizeUnit.mm);
public static Size TAB_THICKNESS = new Size(1d, SizeUnit.mm);
public static Size TAB_HEIGHT = new Size(6.2d, SizeUnit.mm);
public static Size TAB_HOLE_DIAMETER = new Size(3.6d, SizeUnit.mm);
public static Size LEAD_LENGTH = new Size(3.5d, SizeUnit.mm);
public static Size LEAD_THICKNESS = new Size(0.8d, SizeUnit.mm);
private String value = "";
private Orientation orientation = Orientation.DEFAULT;
private Point[] controlPoints = new Point[] {new Point(0, 0), new Point(0, 0), new Point(0, 0)};
transient private Shape[] body;
private Color bodyColor = BODY_COLOR;
private Color borderColor = BORDER_COLOR;
private Color tabColor = TAB_COLOR;
private Color tabBorderColor = TAB_BORDER_COLOR;
private Display display = Display.NAME;
private boolean folded = false;
private Size leadLength = LEAD_LENGTH;
public TransistorTO220() {
super();
updateControlPoints();
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Reset body shape;
body = null;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
private void updateControlPoints() {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
// Update control points.
int x = controlPoints[0].x;
int y = controlPoints[0].y;
switch (orientation) {
case DEFAULT:
controlPoints[1].setLocation(x, y + pinSpacing);
controlPoints[2].setLocation(x, y + 2 * pinSpacing);
break;
case _90:
controlPoints[1].setLocation(x - pinSpacing, y);
controlPoints[2].setLocation(x - 2 * pinSpacing, y);
break;
case _180:
controlPoints[1].setLocation(x, y - pinSpacing);
controlPoints[2].setLocation(x, y - 2 * pinSpacing);
break;
case _270:
controlPoints[1].setLocation(x + pinSpacing, y);
controlPoints[2].setLocation(x + 2 * pinSpacing, y);
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[2];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int pinSpacing = (int) PIN_SPACING.convertToPixels();
int bodyWidth = getClosestOdd(BODY_WIDTH.convertToPixels());
int bodyThickness = getClosestOdd(BODY_THICKNESS.convertToPixels());
int bodyHeight = getClosestOdd(BODY_HEIGHT.convertToPixels());
int tabThickness = (int) TAB_THICKNESS.convertToPixels();
int tabHeight = (int) TAB_HEIGHT.convertToPixels();
int tabHoleDiameter = (int) TAB_HOLE_DIAMETER.convertToPixels();
double leadLength = getLeadLength().convertToPixels();
switch (orientation) {
case DEFAULT:
if (folded) {
body[0] = new Rectangle2D.Double(x + leadLength, y + pinSpacing - bodyWidth / 2, bodyHeight, bodyWidth);
body[1] =
new Area(new Rectangle2D.Double(x + leadLength + bodyHeight, y + pinSpacing - bodyWidth / 2, tabHeight,
bodyWidth));
((Area) body[1]).subtract(new Area(new Ellipse2D.Double(x + leadLength + bodyHeight + tabHeight / 2
- tabHoleDiameter / 2, y + pinSpacing - tabHoleDiameter / 2, tabHoleDiameter, tabHoleDiameter)));
} else {
body[0] =
new Rectangle2D.Double(x - bodyThickness / 2, y + pinSpacing - bodyWidth / 2, bodyThickness, bodyWidth);
body[1] =
new Rectangle2D.Double(x + bodyThickness / 2 - tabThickness, y + pinSpacing - bodyWidth / 2,
tabThickness, bodyWidth);
}
break;
case _90:
if (folded) {
body[0] = new Rectangle2D.Double(x - pinSpacing - bodyWidth / 2, y + leadLength, bodyWidth, bodyHeight);
body[1] =
new Area(new Rectangle2D.Double(x - pinSpacing - bodyWidth / 2, y + leadLength + bodyHeight, bodyWidth,
tabHeight));
((Area) body[1]).subtract(new Area(new Ellipse2D.Double(x - pinSpacing - tabHoleDiameter / 2, y
+ leadLength + bodyHeight + tabHeight / 2 - tabHoleDiameter / 2, tabHoleDiameter, tabHoleDiameter)));
} else {
body[0] =
new Rectangle2D.Double(x - pinSpacing - bodyWidth / 2, y - bodyThickness / 2, bodyWidth, bodyThickness);
body[1] =
new Rectangle2D.Double(x - pinSpacing - bodyWidth / 2, y + bodyThickness / 2 - tabThickness, bodyWidth,
tabThickness);
}
break;
case _180:
if (folded) {
body[0] =
new Rectangle2D.Double(x - leadLength - bodyHeight, y - pinSpacing - bodyWidth / 2, bodyHeight,
bodyWidth);
body[1] =
new Area(new Rectangle2D.Double(x - leadLength - bodyHeight - tabHeight,
y - pinSpacing - bodyWidth / 2, tabHeight, bodyWidth));
((Area) body[1]).subtract(new Area(new Ellipse2D.Double(x - leadLength - bodyHeight - tabHeight / 2
- tabHoleDiameter / 2, y - pinSpacing - tabHoleDiameter / 2, tabHoleDiameter, tabHoleDiameter)));
} else {
body[0] =
new Rectangle2D.Double(x - bodyThickness / 2, y - pinSpacing - bodyWidth / 2, bodyThickness, bodyWidth);
body[1] =
new Rectangle2D.Double(x - bodyThickness / 2, y - pinSpacing - bodyWidth / 2, tabThickness, bodyWidth);
}
break;
case _270:
if (folded) {
body[0] =
new Rectangle2D.Double(x + pinSpacing - bodyWidth / 2, y - leadLength - bodyHeight, bodyWidth,
bodyHeight);
body[1] =
new Area(new Rectangle2D.Double(x + pinSpacing - bodyWidth / 2,
y - leadLength - bodyHeight - tabHeight, bodyWidth, tabHeight));
((Area) body[1]).subtract(new Area(new Ellipse2D.Double(x + pinSpacing - tabHoleDiameter / 2, y
- leadLength - bodyHeight - tabHeight / 2 - tabHoleDiameter / 2, tabHoleDiameter, tabHoleDiameter)));
} else {
body[0] =
new Rectangle2D.Double(x + pinSpacing - bodyWidth / 2, y - bodyThickness / 2, bodyWidth, bodyThickness);
body[1] =
new Rectangle2D.Double(x + pinSpacing - bodyWidth / 2, y - bodyThickness / 2, bodyWidth, tabThickness);
}
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
Shape mainArea = getBody()[0];
Shape tabArea = getBody()[1];
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 : bodyColor);
g2d.fill(mainArea);
Color finalTabColor;
if (outlineMode) {
Theme theme =
(Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalTabColor = theme.getOutlineColor();
} else {
finalTabColor = tabColor;
}
g2d.setColor(finalTabColor);
g2d.fill(tabArea);
g2d.setComposite(oldComposite);
if (!outlineMode) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.setColor(tabBorderColor);
g2d.draw(tabArea);
}
Color finalBorderColor;
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
if (outlineMode) {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: theme.getOutlineColor();
} else {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor;
}
g2d.setColor(finalBorderColor);
g2d.draw(mainArea);
if (folded) {
g2d.draw(tabArea);
}
// Draw pins.
if (folded) {
int leadThickness = getClosestOdd(LEAD_THICKNESS.convertToPixels());
int leadLength = (int) getLeadLength().convertToPixels();
Color finalPinColor;
Color finalPinBorderColor;
if (outlineMode) {
finalPinColor = new Color(0, 0, 0, 0);
finalPinBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: theme.getOutlineColor();
} else {
finalPinColor = METAL_COLOR;
finalPinBorderColor = METAL_COLOR.darker();
}
for (Point point : controlPoints) {
switch (orientation) {
case DEFAULT:
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
g2d.setColor(finalPinBorderColor);
g2d.drawLine(point.x, point.y, point.x + leadLength - leadThickness / 2, point.y);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2));
g2d.setColor(finalPinColor);
g2d.drawLine(point.x, point.y, point.x + leadLength - leadThickness / 2, point.y);
break;
case _90:
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
g2d.setColor(finalPinBorderColor);
g2d.drawLine(point.x, point.y, point.x, point.y + leadLength - leadThickness / 2);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2));
g2d.setColor(finalPinColor);
g2d.drawLine(point.x, point.y, point.x, point.y + leadLength - leadThickness / 2);
break;
case _180:
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
g2d.setColor(finalPinBorderColor);
g2d.drawLine(point.x, point.y, point.x - leadLength - leadThickness / 2, point.y);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2));
g2d.setColor(finalPinColor);
g2d.drawLine(point.x, point.y, point.x - leadLength - leadThickness / 2, point.y);
break;
case _270:
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
g2d.setColor(finalPinBorderColor);
g2d.drawLine(point.x, point.y, point.x, point.y - leadLength);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2));
g2d.setColor(finalPinColor);
g2d.drawLine(point.x, point.y, point.x, point.y - leadLength);
break;
}
}
} else {
if (!outlineMode) {
for (Point point : controlPoints) {
g2d.setColor(PIN_COLOR);
g2d.fillOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR);
g2d.drawOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
}
}
// Draw label.
g2d.setFont(LABEL_FONT);
Color finalLabelColor;
if (outlineMode) {
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);
String label = "";
label = (getDisplay() == Display.NAME) ? getName() : getValue();
if (getDisplay() == Display.NONE) {
label = "";
}
if (getDisplay() == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
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(label, x, y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int margin = 2 * width / 32;
int bodySize = width * 5 / 10;
int tabSize = bodySize * 6 / 10;
int holeSize = 5 * width / 32;
Area a = new Area(new Rectangle2D.Double((width - bodySize) / 2, margin, bodySize, tabSize));
a.subtract(new Area(new Ellipse2D.Double(width / 2 - holeSize / 2, margin + tabSize / 2 - holeSize / 2, holeSize,
holeSize)));
g2d.setColor(TAB_COLOR);
g2d.fill(a);
g2d.setColor(BORDER_COLOR);
g2d.draw(a);
g2d.setColor(BODY_COLOR);
g2d.fillRect((width - bodySize) / 2, margin + tabSize, bodySize, bodySize);
g2d.setColor(BORDER_COLOR);
g2d.drawRect((width - bodySize) / 2, margin + tabSize, bodySize, bodySize);
g2d.setColor(METAL_COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.drawLine(width / 2, margin + tabSize + bodySize, width / 2, height - margin);
g2d.drawLine(width / 2 - bodySize / 3, margin + tabSize + bodySize, width / 2 - bodySize / 3, height - margin);
g2d.drawLine(width / 2 + bodySize / 3, margin + tabSize + bodySize, width / 2 + bodySize / 3, height - margin);
}
@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(name = "Tab")
public Color getTabColor() {
return tabColor;
}
public void setTabColor(Color tabColor) {
this.tabColor = tabColor;
}
@EditableProperty
public boolean getFolded() {
return folded;
}
public void setFolded(boolean folded) {
this.folded = folded;
// Invalidate the body
this.body = null;
}
@EditableProperty(name = "Lead length")
public Size getLeadLength() {
if (leadLength == null) {
leadLength = LEAD_LENGTH;
}
return leadLength;
}
public void setLeadLength(Size leadLength) {
this.leadLength = leadLength;
// Invalidate the body
this.body = null;
}
@EditableProperty(name = "Tab border")
public Color getTabBorderColor() {
return tabBorderColor;
}
public void setTabBorderColor(Color tabBorderColor) {
this.tabBorderColor = tabBorderColor;
}
@EditableProperty
public Display getDisplay() {
if (display == null) {
display = Display.NAME;
}
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
}
@@ -0,0 +1,368 @@
package org.diylc.components.semiconductors;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
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;
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 = "Transistor (TO-3 package)", author = "Branislav Stojkovic", category = "Semiconductors",
instanceNamePrefix = "Q", description = "Transistor with large metal body", stretchable = false,
zOrder = IDIYComponent.COMPONENT)
public class TransistorTO3 extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
public static Color BODY_COLOR = Color.decode("#D0E0EF");
public static Color BORDER_COLOR = BODY_COLOR.darker();
public static Color PIN_COLOR = Color.decode("#00B2EE");
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
public static Color LABEL_COLOR = Color.black;
public static Size LARGE_DIAMETER = new Size(26.2d, SizeUnit.mm);
public static Size INNER_DIAMETER = new Size(21.3d, SizeUnit.mm);
public static Size SMALL_DIAMETER = new Size(8d, SizeUnit.mm);
public static Size HOLE_DISTANCE = new Size(30.1d, SizeUnit.mm);
public static Size HOLE_SIZE = new Size(4.1d, SizeUnit.mm);
public static Size PIN_SPACING = new Size(10.9d, SizeUnit.mm);
public static Size PIN_OFFSET = new Size(1.85d, SizeUnit.mm);
public static Size PIN_DIAMETER = new Size(1d, SizeUnit.mm);
private String value = "";
private Orientation orientation = Orientation.DEFAULT;
private Point[] controlPoints = new Point[] {new Point(0, 0), new Point(0, 0)};
transient private Area[] body;
private Color bodyColor = BODY_COLOR;
private Color borderColor = BORDER_COLOR;
private Color labelColor = LABEL_COLOR;
protected Display display = Display.NAME;
public TransistorTO3() {
super();
updateControlPoints();
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Reset body shape;
body = null;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
private void updateControlPoints() {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
// Update control points.
int x = controlPoints[0].x;
int y = controlPoints[0].y;
switch (orientation) {
case DEFAULT:
controlPoints[1].setLocation(x, y + pinSpacing);
break;
case _90:
controlPoints[1].setLocation(x - pinSpacing, y);
break;
case _180:
controlPoints[1].setLocation(x, y - pinSpacing);
break;
case _270:
controlPoints[1].setLocation(x + pinSpacing, y);
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
}
public Area[] getBody() {
if (body == null) {
body = new Area[2];
int pinOffset = (int) PIN_OFFSET.convertToPixels();
int x = (controlPoints[0].x + controlPoints[1].x) / 2;
int y = (controlPoints[0].y + controlPoints[1].y) / 2;
switch (orientation) {
case DEFAULT:
x += pinOffset;
break;
case _90:
y += pinOffset;
break;
case _180:
x -= pinOffset;
break;
case _270:
y -= pinOffset;
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
int largeDiameter = getClosestOdd(LARGE_DIAMETER.convertToPixels());
int innerDiameter = getClosestOdd(INNER_DIAMETER.convertToPixels());
int smallDiameter = getClosestOdd(SMALL_DIAMETER.convertToPixels());
int holeDistance = getClosestOdd(HOLE_DISTANCE.convertToPixels());
int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
body[0] =
new Area(new Ellipse2D.Double(x - largeDiameter / 2, y - largeDiameter / 2, largeDiameter, largeDiameter));
int[] xPoints =
new int[] {x + (int) (Math.cos(Math.PI / 4) * largeDiameter / 2),
x + holeDistance / 2 + (int) (Math.cos(Math.PI / 4) * smallDiameter / 2),
x + holeDistance / 2 + (int) (Math.cos(Math.PI / 4) * smallDiameter / 2),
x + (int) (Math.cos(Math.PI / 4) * largeDiameter / 2),
x - (int) (Math.cos(Math.PI / 4) * largeDiameter / 2),
x - holeDistance / 2 - (int) (Math.cos(Math.PI / 4) * smallDiameter / 2),
x - holeDistance / 2 - (int) (Math.cos(Math.PI / 4) * smallDiameter / 2),
x - (int) (Math.cos(Math.PI / 4) * largeDiameter / 2)};
int[] yPoints =
new int[] {y - (int) (Math.sin(Math.PI / 4) * largeDiameter / 2),
y - (int) (Math.sin(Math.PI / 4) * smallDiameter / 2),
y + (int) (Math.sin(Math.PI / 4) * smallDiameter / 2),
y + (int) (Math.sin(Math.PI / 4) * largeDiameter / 2),
y + (int) (Math.sin(Math.PI / 4) * largeDiameter / 2),
y + (int) (Math.sin(Math.PI / 4) * smallDiameter / 2),
y - (int) (Math.sin(Math.PI / 4) * smallDiameter / 2),
y - (int) (Math.sin(Math.PI / 4) * largeDiameter / 2)};
body[0].add(new Area(new Polygon(xPoints, yPoints, xPoints.length)));
body[0].add(new Area(new Ellipse2D.Double(x - holeDistance / 2 - smallDiameter / 2, y - smallDiameter / 2,
smallDiameter, smallDiameter)));
body[0].subtract(new Area(new Ellipse2D.Double(x - holeDistance / 2 - holeSize / 2, y - holeSize / 2, holeSize,
holeSize)));
body[0].add(new Area(new Ellipse2D.Double(x + holeDistance / 2 - smallDiameter / 2, y - smallDiameter / 2,
smallDiameter, smallDiameter)));
body[0].subtract(new Area(new Ellipse2D.Double(x + holeDistance / 2 - holeSize / 2, y - holeSize / 2, holeSize,
holeSize)));
switch (orientation) {
case DEFAULT:
break;
case _90:
body[0].transform(AffineTransform.getRotateInstance(Math.PI / 2, x, y));
break;
case _180:
body[0].transform(AffineTransform.getRotateInstance(Math.PI, x, y));
break;
case _270:
body[0].transform(AffineTransform.getRotateInstance(Math.PI * 3 / 2, x, y));
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
body[1] =
new Area(new Ellipse2D.Double(x - innerDiameter / 2, y - innerDiameter / 2, innerDiameter, innerDiameter));
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int pinSize = (int) PIN_DIAMETER.convertToPixels() / 2 * 2;
Area mainArea = getBody()[0];
Area innerArea = getBody()[1];
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 : bodyColor);
g2d.fill(mainArea);
g2d.setComposite(oldComposite);
Color finalBorderColor;
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
if (outlineMode) {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: theme.getOutlineColor();
} else {
finalBorderColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor;
}
g2d.setColor(finalBorderColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.draw(mainArea);
g2d.draw(innerArea);
for (Point point : controlPoints) {
if (!outlineMode) {
g2d.setColor(PIN_COLOR);
g2d.fillOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
g2d.setColor(outlineMode ? theme.getOutlineColor() : PIN_BORDER_COLOR);
g2d.drawOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
// Draw label.
g2d.setFont(LABEL_FONT);
Color finalLabelColor;
if (outlineMode) {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: theme.getOutlineColor();
} else {
finalLabelColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: getLabelColor();
}
g2d.setColor(finalLabelColor);
String label = "";
label = (getDisplay() == Display.NAME) ? getName() : getValue();
if (getDisplay() == Display.NONE) {
label = "";
}
if (getDisplay() == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
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(label, x, y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int sizeLarge = getClosestOdd(width * 3d / 4);
int sizeInner = getClosestOdd(width * 5d / 10);
int sizeSmall = getClosestOdd(width / 3d);
int hole = 4 * width / 32;
Area area = new Area(new Ellipse2D.Double((width - sizeLarge) / 2, (height - sizeLarge) / 2, sizeLarge, sizeLarge));
// int[] x = new int[] { width / 2 + sizeSmall / 2,
// width / 2 + sizeLarge / 2, width / 2 + sizeSmall / 2,
// width / 2 - sizeSmall / 2, width / 2 - sizeLarge / 2,
// width / 2 - sizeSmall / 2 };
// int[] y = new int[] { height / 8, height / 2, height * 7 / 8,
// height * 7 / 8, height / 2, height / 8 };
// Area p = new Area(new Polygon(x, y, x.length));
// AffineTransform t = AffineTransform.getTranslateInstance(width / 2,
// height / 2);
// t.concatenate(AffineTransform.getScaleInstance(1.05, 1.05));
// t.concatenate(AffineTransform.getTranslateInstance(-width / 2,
// -height / 2));
// p.transform(t);
// area.add(new Area(p));
area.add(new Area(new Ellipse2D.Double((width - sizeSmall) / 2, height / 8 - sizeSmall / 2, sizeSmall, sizeSmall)));
area.add(new Area(new Ellipse2D.Double((width - sizeSmall) / 2, height * 7 / 8 - sizeSmall / 2, sizeSmall,
sizeSmall)));
area.subtract(new Area(new Ellipse2D.Double((width - hole) / 2, height / 8 - hole / 2, hole, hole)));
area.subtract(new Area(new Ellipse2D.Double((width - hole) / 2, height * 7 / 8 - hole / 2, hole, hole)));
area.transform(AffineTransform.getRotateInstance(Math.PI / 4, width / 2, height / 2));
g2d.setColor(BODY_COLOR);
g2d.fill(area);
g2d.setColor(BORDER_COLOR);
g2d.draw(area);
g2d.drawOval((width - sizeInner) / 2, (height - sizeInner) / 2, sizeInner, sizeInner);
}
@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(name = "Label")
public Color getLabelColor() {
return labelColor;
}
public void setLabelColor(Color labelColor) {
this.labelColor = labelColor;
}
@EditableProperty
public Display getDisplay() {
if (display == null) {
display = Display.NAME;
}
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
}
@@ -0,0 +1,354 @@
package org.diylc.components.semiconductors;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
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;
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 = "Transistor (TO-92 package)", author = "Branislav Stojkovic", category = "Semiconductors",
instanceNamePrefix = "Q", description = "Transistor with small plastic or epoxy body", stretchable = false,
zOrder = IDIYComponent.COMPONENT)
public class TransistorTO92 extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
public static Color BODY_COLOR = Color.gray;
public static Color BORDER_COLOR = Color.gray.darker();
public static Color PIN_COLOR = Color.decode("#00B2EE");
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
public static Color LABEL_COLOR = Color.white;
public static Size PIN_SIZE = new Size(0.03d, SizeUnit.in);
public static Size PIN_SPACING = new Size(0.05d, SizeUnit.in);
public static Size BODY_DIAMETER = new Size(0.2d, SizeUnit.in);
private String value = "";
private Orientation orientation = Orientation.DEFAULT;
private Point[] controlPoints = new Point[] {new Point(0, 0), new Point(0, 0), new Point(0, 0)};
transient private Area body;
private Color bodyColor = BODY_COLOR;
private Color borderColor = BORDER_COLOR;
private Color labelColor = LABEL_COLOR;
protected Display display = Display.NAME;
private boolean folded = false;
private Size pinSpacing = PIN_SPACING;
public TransistorTO92() {
super();
updateControlPoints();
}
@EditableProperty
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Reset body shape;
body = null;
}
@EditableProperty
public boolean getFolded() {
return folded;
}
public void setFolded(boolean folded) {
this.folded = folded;
// Reset body shape;
body = null;
}
@EditableProperty(name = "Pin spacing")
public Size getPinSpacing() {
if (pinSpacing == null) {
pinSpacing = new Size(0.1, SizeUnit.in);
}
return pinSpacing;
}
public void setPinSpacing(Size pinSpacing) {
this.pinSpacing = pinSpacing;
updateControlPoints();
// Reset body shape;
body = null;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
private void updateControlPoints() {
int pinSpacing = (int) getPinSpacing().convertToPixels();
// Update control points.
int x = controlPoints[0].x;
int y = controlPoints[0].y;
switch (orientation) {
case DEFAULT:
controlPoints[1].setLocation(x, y + pinSpacing);
controlPoints[2].setLocation(x, y + 2 * pinSpacing);
break;
case _90:
controlPoints[1].setLocation(x - pinSpacing, y);
controlPoints[2].setLocation(x - 2 * pinSpacing, y);
break;
case _180:
controlPoints[1].setLocation(x, y - pinSpacing);
controlPoints[2].setLocation(x, y - 2 * pinSpacing);
break;
case _270:
controlPoints[1].setLocation(x + pinSpacing, y);
controlPoints[2].setLocation(x + 2 * pinSpacing, y);
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
}
public Area getBody() {
if (body == null) {
int x = (controlPoints[0].x + controlPoints[1].x + controlPoints[2].x) / 3;
int y = (controlPoints[0].y + controlPoints[1].y + controlPoints[2].y) / 3;
int bodyDiameter = getClosestOdd(BODY_DIAMETER.convertToPixels());
if (folded) {
switch (orientation) {
case DEFAULT:
body = new Area(new Rectangle2D.Double(x - bodyDiameter, y - bodyDiameter / 2, bodyDiameter, bodyDiameter));
break;
case _90:
body = new Area(new Rectangle2D.Double(x - bodyDiameter / 2, y - bodyDiameter, bodyDiameter, bodyDiameter));
break;
case _180:
body = new Area(new Rectangle2D.Double(x, y - bodyDiameter / 2, bodyDiameter, bodyDiameter));
break;
case _270:
body = new Area(new Rectangle2D.Double(x - bodyDiameter / 2, y, bodyDiameter, bodyDiameter));
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
} else {
switch (orientation) {
case DEFAULT:
body =
new Area(new Ellipse2D.Double(x - bodyDiameter / 2, y - bodyDiameter / 2, bodyDiameter, bodyDiameter));
body.subtract(new Area(new Rectangle2D.Double(x - bodyDiameter, y - bodyDiameter / 2, 3 * bodyDiameter / 4,
bodyDiameter)));
break;
case _90:
body =
new Area(new Ellipse2D.Double(x - bodyDiameter / 2, y - bodyDiameter / 2, bodyDiameter, bodyDiameter));
body.subtract(new Area(new Rectangle2D.Double(x - bodyDiameter / 2, y - bodyDiameter, bodyDiameter,
3 * bodyDiameter / 4)));
break;
case _180:
body =
new Area(new Ellipse2D.Double(x - bodyDiameter / 2, y - bodyDiameter / 2, bodyDiameter, bodyDiameter));
body.subtract(new Area(new Rectangle2D.Double(x + bodyDiameter / 4, y - bodyDiameter / 2,
3 * bodyDiameter / 4, bodyDiameter)));
break;
case _270:
body =
new Area(new Ellipse2D.Double(x - bodyDiameter / 2, y - bodyDiameter / 2, bodyDiameter, bodyDiameter));
body.subtract(new Area(new Rectangle2D.Double(x - bodyDiameter / 2, y + bodyDiameter / 4, bodyDiameter,
3 * bodyDiameter / 4)));
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
}
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int pinSize = (int) PIN_SIZE.convertToPixels() / 2 * 2;
Area mainArea = getBody();
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 : bodyColor);
g2d.fill(mainArea);
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
: borderColor;
}
g2d.setColor(finalBorderColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.draw(mainArea);
if (!outlineMode) {
for (Point point : controlPoints) {
g2d.setColor(PIN_COLOR);
g2d.fillOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
g2d.setColor(PIN_BORDER_COLOR);
g2d.drawOval(point.x - pinSize / 2, point.y - pinSize / 2, pinSize, pinSize);
}
}
// 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
: getLabelColor();
}
g2d.setColor(finalLabelColor);
String label = "";
label = (getDisplay() == Display.NAME) ? getName() : getValue();
if (display == Display.NONE) {
label = "";
}
if (display == Display.BOTH) {
label = getName() + " " + getValue();
}
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
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(label, x, y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int margin = 3 * width / 32;
Area area = new Area(new Ellipse2D.Double(margin / 2, margin, width - 2 * margin, width - 2 * margin));
// 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.draw(area);
g2d.setColor(PIN_COLOR);
int pinSize = 2 * width / 32;
for (int i = 0; i < 3; i++) {
g2d.fillOval(width / 2 - pinSize / 2, (height / 4) * (i + 1), pinSize, pinSize);
}
}
@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(name = "Label")
public Color getLabelColor() {
if (labelColor == null) {
labelColor = LABEL_COLOR;
}
return labelColor;
}
public void setLabelColor(Color labelColor) {
this.labelColor = labelColor;
}
@EditableProperty
public Display getDisplay() {
if (display == null) {
display = Display.NAME;
}
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
}
@@ -0,0 +1,63 @@
package org.diylc.components.semiconductors;
import java.awt.Graphics2D;
import java.awt.Polygon;
import org.diylc.common.ObjectCache;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Zener diode (schematic symbol)", author = "Branislav Stojkovic", category = "Schematics",
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "D",
description = "Zener diode schematic symbol", zOrder = IDIYComponent.COMPONENT)
public class ZenerDiodeSymbol extends AbstractDiodeSymbol {
private static final long serialVersionUID = 1L;
public static Size BAND_SIZE = new Size(0.01, SizeUnit.in);
public void drawIcon(Graphics2D g2d, int width, int height) {
int size = width * 3 / 8;
int bandSize = 1;
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR);
g2d.drawLine(0, height / 2, (width - size) / 2, height / 2);
g2d.drawLine((int) (width + size / Math.sqrt(2) + bandSize) / 2, height / 2, width, height / 2);
g2d.setColor(COLOR);
g2d.fill(new Polygon(new int[] {(width - size) / 2, (width - size) / 2,
(int) ((width - size) / 2 + size / Math.sqrt(2))}, new int[] {(height - size) / 2, (height + size) / 2,
height / 2}, 3));
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(bandSize));
g2d.drawLine((int) ((width - size) / 2 + size / Math.sqrt(2)), (height - size) / 2,
(int) ((width - size) / 2 + size / Math.sqrt(2)), (height + size) / 2);
int finSize = 2 * width / 32;
g2d.drawLine((int) ((width - size) / 2 + size / Math.sqrt(2)), (height - size) / 2, (int) ((width - size) / 2
+ size / Math.sqrt(2) + finSize), (height - size) / 2 - finSize);
g2d.drawLine((int) ((width - size) / 2 + size / Math.sqrt(2)), (height + size) / 2, (int) ((width - size) / 2
+ size / Math.sqrt(2) - finSize), (height + size) / 2 + finSize);
}
@Override
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
double width = getWidth().convertToPixels();
double finSize = width / 5;
int bandSize = (int) BAND_SIZE.convertToPixels();
g2d.setColor(getBodyColor());
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(bandSize));
// g2d.drawLine((int) (width / Math.sqrt(2)) + bandSize, 0, (int) (width
// / Math.sqrt(2) + bandSize), (int) width);
// g2d.drawLine((int) (width / Math.sqrt(2)) + bandSize, 0, (int) (width
// / Math.sqrt(2) + bandSize + finSize), -(int) finSize);
// g2d.drawLine((int) (width / Math.sqrt(2) + bandSize), (int) width,
// (int) (width / Math.sqrt(2) + bandSize - finSize),
// (int) (width + finSize));
g2d.drawPolyline(new int[] {(int) (width / Math.sqrt(2) + bandSize + finSize),
(int) (width / Math.sqrt(2) + bandSize), (int) (width / Math.sqrt(2) + bandSize),
(int) (width / Math.sqrt(2) + bandSize - finSize)}, new int[] {(int) -finSize, 0, (int) width,
(int) (width + finSize)}, 4);
}
}
@@ -0,0 +1,103 @@
package org.diylc.components.shapes;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
public abstract class AbstractShape extends AbstractTransparentComponent<Void> {
private static final long serialVersionUID = 1L;
public static Color COLOR = Color.white;
public static Color BORDER_COLOR = Color.black;
public static Size DEFAULT_WIDTH = new Size(0.6d, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(0.4d, SizeUnit.in);
protected String value = "";
protected Point[] controlPoints = new Point[] {new Point(0, 0),
new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels())};
protected Point firstPoint = new Point();
protected Point secondPoint = new Point();
protected Color color = COLOR;
protected Color borderColor = BORDER_COLOR;
protected Size borderThickness = new Size(0.2d, SizeUnit.mm);
@EditableProperty(name = "Color")
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
@EditableProperty(name = "Border")
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@EditableProperty(name = "Border thickness")
public Size getBorderThickness() {
return borderThickness;
}
public void setBorderThickness(Size borderThickness) {
this.borderThickness = borderThickness;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public boolean isControlPointSticky(int index) {
return false;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
firstPoint.setLocation(Math.min(controlPoints[0].x, controlPoints[1].x),
Math.min(controlPoints[0].y, controlPoints[1].y));
secondPoint.setLocation(Math.max(controlPoints[0].x, controlPoints[1].x),
Math.max(controlPoints[0].y, controlPoints[1].y));
}
@Deprecated
@Override
public Void getValue() {
return null;
}
@Deprecated
@Override
public void setValue(Void value) {}
}
@@ -0,0 +1,52 @@
package org.diylc.components.shapes;
import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Graphics2D;
import org.diylc.common.ObjectCache;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
@ComponentDescriptor(name = "Ellipse", author = "Branislav Stojkovic", category = "Shapes", instanceNamePrefix = "ELL",
description = "Elliptical area", zOrder = IDIYComponent.COMPONENT, flexibleZOrder = true,
bomPolicy = BomPolicy.SHOW_ALL_NAMES, autoEdit = false)
public class Ellipse extends AbstractShape {
private static final long serialVersionUID = 1L;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels()));
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(color);
g2d.fillOval(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);
g2d.setComposite(oldComposite);
}
// Do not track any changes that follow because the whole oval has been
// tracked so far.
drawingObserver.stopTracking();
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor);
g2d.drawOval(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
g2d.setColor(COLOR);
g2d.fillOval(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(BORDER_COLOR);
g2d.drawOval(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
}
}
@@ -0,0 +1,105 @@
package org.diylc.components.shapes;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.Arrays;
import org.diylc.common.ObjectCache;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "Polygon", author = "Branislav Stojkovic", category = "Shapes",
instanceNamePrefix = "POLY", description = "Polygonal area", zOrder = IDIYComponent.COMPONENT,
flexibleZOrder = true, bomPolicy = BomPolicy.SHOW_ALL_NAMES, autoEdit = false)
public class Polygon extends AbstractShape {
private static final long serialVersionUID = 1L;
protected PointCount pointCount = PointCount._4;
public Polygon() {
super();
this.controlPoints =
new Point[] {new Point(0, 0), new Point(0, (int) DEFAULT_HEIGHT.convertToPixels()),
new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels()),
new Point((int) DEFAULT_WIDTH.convertToPixels(), 0)};
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels()));
g2d.setColor(color);
int[] xPoints = new int[controlPoints.length];
int[] yPoints = new int[controlPoints.length];
for (int i = 0; i < controlPoints.length; i++) {
xPoints[i] = controlPoints[i].x;
yPoints[i] = controlPoints[i].y;
}
Composite oldComposite = g2d.getComposite();
if (this.alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(3, 1.0F * this.alpha / MAX_ALPHA));
}
g2d.fillPolygon(xPoints, yPoints, controlPoints.length);
g2d.setComposite(oldComposite);
// Do not track any changes that follow because the whole board has been
// tracked so far.
drawingObserver.stopTracking();
Color lineColor =
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor;
g2d.setColor(lineColor);
g2d.drawPolygon(xPoints, yPoints, controlPoints.length);
}
@EditableProperty(name = "Edges")
public PointCount getPointCount() {
return pointCount;
}
public void setPointCount(PointCount pointCount) {
if (this.pointCount == pointCount)
return;
int oldPointCount = Integer.parseInt(this.pointCount.toString());
int newPointCount = Integer.parseInt(pointCount.toString());
this.controlPoints = Arrays.copyOf(this.controlPoints, newPointCount);
if (oldPointCount < newPointCount) {
this.controlPoints[newPointCount - 1] = this.controlPoints[oldPointCount - 1];
for (int i = oldPointCount - 1; i < newPointCount - 1; i++) {
this.controlPoints[i] =
new Point((this.controlPoints[i - 1].x + this.controlPoints[newPointCount - 1].x) / 2,
(this.controlPoints[i - 1].y + this.controlPoints[newPointCount - 1].y) / 2);
}
}
this.pointCount = pointCount;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
g2d.setColor(COLOR);
int[] x = {2 / factor, width - 2 / factor, width - 4 / factor, 3 / factor};
int[] y = {4 / factor, 2 / factor, height - 5 / factor, height - 2 / factor};
g2d.fillPolygon(x, y, 4);
g2d.setColor(BORDER_COLOR);
g2d.drawPolygon(x, y, 4);
}
public enum PointCount {
_3, _4, _5, _6, _7, _8;
public String toString() {
return name().substring(1);
};
}
}
@@ -0,0 +1,68 @@
package org.diylc.components.shapes;
import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Graphics2D;
import org.diylc.common.ObjectCache;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
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 = "Rectangle", author = "Branislav Stojkovic", category = "Shapes",
instanceNamePrefix = "RECT", description = "Ractangular area, with or withouth rounded edges",
zOrder = IDIYComponent.COMPONENT, flexibleZOrder = true, bomPolicy = BomPolicy.SHOW_ALL_NAMES, autoEdit = false)
public class Rectangle extends AbstractShape {
private static final long serialVersionUID = 1L;
protected Size edgeRadius = new Size(0d, SizeUnit.mm);
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels()));
int radius = (int) edgeRadius.convertToPixels();
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(color);
g2d.fillRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius,
radius);
g2d.setComposite(oldComposite);
}
// Do not track any changes that follow because the whole rect has been
// tracked so far.
drawingObserver.stopTracking();
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: borderColor);
g2d.drawRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius,
radius);
}
@EditableProperty(name = "Radius")
public Size getEdgeRadius() {
return edgeRadius;
}
public void setEdgeRadius(Size edgeRadius) {
this.edgeRadius = edgeRadius;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int factor = 32 / width;
g2d.setColor(COLOR);
g2d.fillRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor);
}
}
@@ -0,0 +1,145 @@
package org.diylc.components.tube;
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.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
public abstract class AbstractTubeSymbol 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 Color color = COLOR;
protected Display display = Display.NAME;
transient protected Shape[] body;
protected boolean showHeaters;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
Color finalColor;
if (componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING) {
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 tube
Shape[] body = getBody();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.draw(body[0]);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.draw(body[1]);
if (body[2] != null) {
g2d.draw(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);
Point p = getTextLocation();
String label = "";
label = display == Display.VALUE ? getValue() : getName();
if (display == Display.NONE) {
label = "";
}
if (display == Display.BOTH) {
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
}
drawCenteredText(g2d, label, p.x, p.y, HorizontalAlignment.LEFT, VerticalAlignment.TOP);
}
@EditableProperty
@Override
public String getValue() {
return this.value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@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;
}
@EditableProperty(name = "Heaters")
public boolean getShowHeaters() {
return showHeaters;
}
public void setShowHeaters(boolean showHeaters) {
this.showHeaters = showHeaters;
// Invalidate body
body = null;
}
/**
* Returns transistor shape consisting of 3 parts, in this order: electrodes, connectors, bulb.
*
* @return
*/
protected abstract Shape[] getBody();
protected abstract Point getTextLocation();
}
@@ -0,0 +1,199 @@
package org.diylc.components.tube;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import org.diylc.common.ObjectCache;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IPropertyValidator;
import org.diylc.core.ValidationException;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "Diode Symbol", author = "Branislav Stojkovic", category = "Schematics",
instanceNamePrefix = "V", description = "Diode tube symbol", stretchable = false, zOrder = IDIYComponent.COMPONENT,
rotatable = false)
public class DiodeSymbol extends AbstractTubeSymbol {
private static final long serialVersionUID = 1L;
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 boolean directlyHeated = false;
public DiodeSymbol() {
super();
updateControlPoints();
}
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();
// electrodes
GeneralPath polyline = new GeneralPath();
// plate
polyline.moveTo(x + pinSpacing * 3 / 2, y - pinSpacing);
polyline.lineTo(x + pinSpacing * 9 / 2, y - pinSpacing);
// cathode
if (directlyHeated) {
polyline.moveTo(controlPoints[2].x, controlPoints[2].y - pinSpacing);
polyline.lineTo(controlPoints[2].x + pinSpacing, controlPoints[2].y - pinSpacing * 2);
polyline.lineTo(controlPoints[4].x, controlPoints[4].y - pinSpacing);
} else {
polyline.moveTo(x + pinSpacing * 2, y + pinSpacing);
polyline.lineTo(x + pinSpacing * 4, y + pinSpacing);
}
body[0] = polyline;
// connectors
polyline = new GeneralPath();
// plate
polyline.moveTo(controlPoints[1].x, controlPoints[1].y);
polyline.lineTo(x + pinSpacing * 3, y - pinSpacing);
// cathode
if (directlyHeated) {
polyline.moveTo(controlPoints[2].x, controlPoints[2].y);
polyline.lineTo(controlPoints[2].x, controlPoints[2].y - pinSpacing);
polyline.moveTo(controlPoints[4].x, controlPoints[4].y);
polyline.lineTo(controlPoints[4].x, controlPoints[4].y - pinSpacing);
} else {
polyline.moveTo(controlPoints[2].x, controlPoints[2].y);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing);
if (showHeaters) {
polyline.moveTo(controlPoints[3].x, controlPoints[3].y);
polyline.lineTo(controlPoints[3].x, controlPoints[3].y - pinSpacing);
polyline.lineTo(controlPoints[3].x + pinSpacing / 2, controlPoints[3].y - 3 * pinSpacing / 2);
polyline.moveTo(controlPoints[4].x, controlPoints[4].y);
polyline.lineTo(controlPoints[4].x, controlPoints[4].y - pinSpacing);
polyline.lineTo(controlPoints[4].x - pinSpacing / 2, controlPoints[4].y - 3 * pinSpacing / 2);
}
}
body[1] = polyline;
// bulb
body[2] = new Ellipse2D.Double(x + pinSpacing / 2, y - pinSpacing * 5 / 2, pinSpacing * 5, pinSpacing * 5);
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawLine(width / 4, height / 4, width * 3 / 4, height / 4);
g2d.drawLine(width / 2, height / 4, width / 2, 0);
g2d.drawLine(width / 4 + 2 * width / 32, height * 3 / 4, width * 3 / 4 - 4 * width / 32, height * 3 / 4);
g2d.drawLine(width / 4 + 2 * width / 32, height * 3 / 4, width / 4 + 2 * width / 32, height - 1);
g2d.drawOval(1, 1, width - 1 - 2 * width / 32, height - 1 - 2 * width / 32);
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
protected 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 * 3;
controlPoints[1].y = y - pinSpacing * 3;
controlPoints[2].x = x + pinSpacing * 2;
controlPoints[2].y = y + pinSpacing * 3;
controlPoints[3].x = x + pinSpacing * 3;
controlPoints[3].y = y + pinSpacing * 3;
controlPoints[4].x = x + pinSpacing * 4;
controlPoints[4].y = y + pinSpacing * 3;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
// Invalidate body
body = null;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
if (directlyHeated) {
return index > 0 && index != 3 ? VisibilityPolicy.WHEN_SELECTED : VisibilityPolicy.NEVER;
} else if (showHeaters) {
return index > 0 ? VisibilityPolicy.WHEN_SELECTED : VisibilityPolicy.NEVER;
} else {
return index < 3 && index > 0 ? VisibilityPolicy.WHEN_SELECTED : VisibilityPolicy.NEVER;
}
}
@Override
public boolean isControlPointSticky(int index) {
if (directlyHeated)
return index > 0 && index != 3;
else if (showHeaters) {
return index > 0;
} else {
return index > 0 && index < 3;
}
}
@Override
protected Point getTextLocation() {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
return new Point(controlPoints[0].x + pinSpacing * 5, controlPoints[0].y + pinSpacing * 2);
}
@EditableProperty(name = "Directly heated")
public boolean getDirectlyHeated() {
return directlyHeated;
}
public void setDirectlyHeated(boolean directlyHeated) {
this.directlyHeated = directlyHeated;
// Invalidate body
body = null;
}
public class HeaterValidator implements IPropertyValidator {
@Override
public void validate(Object value) throws ValidationException {
if (value != null && value instanceof Boolean) {
boolean b = (Boolean) value;
if (!b && getDirectlyHeated()) {
throw new ValidationException("Must show heaters for directly heated tubes.");
}
}
}
}
}
@@ -0,0 +1,234 @@
package org.diylc.components.tube;
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import org.diylc.common.ObjectCache;
import org.diylc.core.IDIYComponent;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "Pentode Symbol", author = "Branislav Stojkovic", category = "Schematics",
instanceNamePrefix = "V", description = "Pentode tube symbol", stretchable = false,
zOrder = IDIYComponent.COMPONENT, rotatable = false)
public class PentodeSymbol extends AbstractTubeSymbol {
private static final long serialVersionUID = 1L;
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), new Point(0, 0), new Point(0, 0)};
protected boolean exposeSuppressorGrid = true;
public PentodeSymbol() {
super();
updateControlPoints();
}
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();
// electrodes
GeneralPath polyline = new GeneralPath();
// grid 1
polyline.moveTo(x + pinSpacing * 5 / 4, y - pinSpacing * 3 / 8);
polyline.lineTo(x + pinSpacing * 7 / 4, y - pinSpacing * 3 / 8);
polyline.moveTo(x + pinSpacing * 9 / 4, y - pinSpacing * 3 / 8);
polyline.lineTo(x + pinSpacing * 11 / 4, y - pinSpacing * 3 / 8);
polyline.moveTo(x + pinSpacing * 13 / 4, y - pinSpacing * 3 / 8);
polyline.lineTo(x + pinSpacing * 15 / 4, y - pinSpacing * 3 / 8);
polyline.moveTo(x + pinSpacing * 17 / 4, y - pinSpacing * 3 / 8);
polyline.lineTo(x + pinSpacing * 19 / 4, y - pinSpacing * 3 / 8);
// grid 2
polyline.moveTo(x + pinSpacing * 5 / 4, y - pinSpacing);
polyline.lineTo(x + pinSpacing * 7 / 4, y - pinSpacing);
polyline.moveTo(x + pinSpacing * 9 / 4, y - pinSpacing);
polyline.lineTo(x + pinSpacing * 11 / 4, y - pinSpacing);
polyline.moveTo(x + pinSpacing * 13 / 4, y - pinSpacing);
polyline.lineTo(x + pinSpacing * 15 / 4, y - pinSpacing);
polyline.moveTo(x + pinSpacing * 17 / 4, y - pinSpacing);
polyline.lineTo(x + pinSpacing * 19 / 4, y - pinSpacing);
// grid 3
polyline.moveTo(x + pinSpacing * 5 / 4, y - pinSpacing - pinSpacing * 5 / 8);
polyline.lineTo(x + pinSpacing * 7 / 4, y - pinSpacing - pinSpacing * 5 / 8);
polyline.moveTo(x + pinSpacing * 9 / 4, y - pinSpacing - pinSpacing * 5 / 8);
polyline.lineTo(x + pinSpacing * 11 / 4, y - pinSpacing - pinSpacing * 5 / 8);
polyline.moveTo(x + pinSpacing * 13 / 4, y - pinSpacing - pinSpacing * 5 / 8);
polyline.lineTo(x + pinSpacing * 15 / 4, y - pinSpacing - pinSpacing * 5 / 8);
polyline.moveTo(x + pinSpacing * 17 / 4, y - pinSpacing - pinSpacing * 5 / 8);
polyline.lineTo(x + pinSpacing * 19 / 4, y - pinSpacing - pinSpacing * 5 / 8);
// plate
polyline.moveTo(x + pinSpacing * 3 / 2, y - pinSpacing * 9 / 4);
polyline.lineTo(x + pinSpacing * 9 / 2, y - pinSpacing * 9 / 4);
// cathode
polyline.moveTo(x + pinSpacing * 2, y + pinSpacing * 3 / 8);
polyline.lineTo(x + pinSpacing * 4, y + pinSpacing * 3 / 8);
body[0] = polyline;
// connectors
polyline = new GeneralPath();
// grid1
polyline.moveTo(x, y);
polyline.lineTo(x + pinSpacing, y);
polyline.lineTo(x + pinSpacing * 5 / 4, y - pinSpacing * 3 / 8);
// grid2
polyline.moveTo(controlPoints[3].x, controlPoints[3].y);
polyline.lineTo(x + pinSpacing * 19 / 4, y - pinSpacing);
// grid3
if (exposeSuppressorGrid) {
polyline.moveTo(controlPoints[4].x, controlPoints[4].y);
polyline.lineTo(x + pinSpacing, controlPoints[4].y);
polyline.lineTo(x + pinSpacing * 5 / 4, y - pinSpacing - pinSpacing * 5 / 8);
} else {
polyline.moveTo(x + pinSpacing * 19 / 4, y - pinSpacing - pinSpacing * 5 / 8);
polyline.lineTo(x + pinSpacing * 5, y - pinSpacing - pinSpacing * 5 / 8);
polyline.lineTo(x + pinSpacing * 5, y - pinSpacing * 5 / 4);
polyline.curveTo(x + pinSpacing * 21 / 4, y - pinSpacing * 5 / 4, x + pinSpacing * 21 / 4, y - pinSpacing * 3
/ 4, x + pinSpacing * 5, y - pinSpacing * 3 / 4);
polyline.moveTo(x + pinSpacing * 5, y - pinSpacing * 3 / 4);
polyline.lineTo(x + pinSpacing * 5, y + pinSpacing * 3 / 8);
polyline.lineTo(x + pinSpacing * 4, y + pinSpacing * 3 / 8);
}
// plate
polyline.moveTo(controlPoints[1].x, controlPoints[1].y);
polyline.lineTo(x + pinSpacing * 3, y - pinSpacing * 9 / 4);
// cathode
polyline.moveTo(controlPoints[2].x, controlPoints[2].y);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing * 3 / 8);
if (showHeaters) {
polyline.moveTo(controlPoints[5].x, controlPoints[5].y);
polyline.lineTo(controlPoints[5].x, controlPoints[5].y - pinSpacing * 6 / 8);
polyline.lineTo(controlPoints[5].x + pinSpacing / 2, controlPoints[5].y - pinSpacing * 10 / 8);
polyline.moveTo(controlPoints[6].x, controlPoints[6].y);
polyline.lineTo(controlPoints[6].x, controlPoints[6].y - pinSpacing * 6 / 8);
polyline.lineTo(controlPoints[6].x - pinSpacing / 2, controlPoints[6].y - pinSpacing * 10 / 8);
}
body[1] = polyline;
// bulb
body[2] = new Ellipse2D.Double(x + pinSpacing / 2, y - pinSpacing * 7 / 2, pinSpacing * 5, pinSpacing * 5);
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawLine(width / 4, height / 4, width * 3 / 4, height / 4);
g2d.drawLine(width / 2, height / 4, width / 2, 0);
g2d.drawLine(width / 4 + 2 * width / 32, height * 3 / 4, width * 3 / 4 - 4 * width / 32, height * 3 / 4);
g2d.drawLine(width / 4 + 2 * width / 32, height * 3 / 4, width / 4 + 2 * width / 32, height - 1);
g2d.drawOval(1, 1, width - 1 - 2 * width / 32, height - 1 - 2 * width / 32);
g2d.drawLine(0, height / 2, width / 8, height / 2);
g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 0, new float[] {3f}, 6f));
g2d.drawLine(width / 8, height / 2, width * 7 / 8, height / 2);
g2d.drawLine(width / 8, height * 3 / 8, width * 7 / 8, height * 3 / 8);
g2d.drawLine(width / 8, height * 5 / 8, width * 7 / 8, height * 5 / 8);
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
protected 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 * 3;
controlPoints[1].y = y - pinSpacing * 4;
controlPoints[2].x = x + pinSpacing * 2;
controlPoints[2].y = y + pinSpacing * 2;
controlPoints[3].x = x + pinSpacing * 6;
controlPoints[3].y = y - pinSpacing;
controlPoints[4].x = x;
controlPoints[4].y = y - pinSpacing * 2;
controlPoints[5].x = x + pinSpacing * 3;
controlPoints[5].y = y + pinSpacing * 2;
controlPoints[6].x = x + pinSpacing * 4;
controlPoints[6].y = y + pinSpacing * 2;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
// Invalidate body
body = null;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
if (showHeaters) {
return !exposeSuppressorGrid && index == 4 ? VisibilityPolicy.NEVER : VisibilityPolicy.WHEN_SELECTED;
} else {
return index >= 5 || (!exposeSuppressorGrid && index == 4) ? VisibilityPolicy.NEVER
: VisibilityPolicy.WHEN_SELECTED;
}
}
@Override
public boolean isControlPointSticky(int index) {
if (showHeaters) {
return exposeSuppressorGrid ? true : index != 4;
} else {
return exposeSuppressorGrid ? index < 5 : index < 4;
}
}
@Override
protected Point getTextLocation() {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
return new Point(controlPoints[0].x + pinSpacing * 5, controlPoints[0].y + pinSpacing);
}
@EditableProperty(name = "Suppressor grid")
public boolean getExposeSuppressorGrid() {
return exposeSuppressorGrid;
}
public void setExposeSuppressorGrid(boolean exposeSuppressorGrid) {
this.exposeSuppressorGrid = exposeSuppressorGrid;
this.body = null;
}
}
@@ -0,0 +1,203 @@
package org.diylc.components.tube;
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import org.diylc.common.ObjectCache;
import org.diylc.core.IDIYComponent;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "Triode Symbol", author = "Branislav Stojkovic", category = "Schematics",
instanceNamePrefix = "V", description = "Triode tube symbol", stretchable = false,
zOrder = IDIYComponent.COMPONENT, rotatable = false)
public class TriodeSymbol extends AbstractTubeSymbol {
private static final long serialVersionUID = 1L;
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 boolean directlyHeated = false;
public TriodeSymbol() {
super();
updateControlPoints();
}
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();
// electrodes
GeneralPath polyline = new GeneralPath();
// grid
polyline.moveTo(x + pinSpacing * 5 / 4, y);
polyline.lineTo(x + pinSpacing * 7 / 4, y);
polyline.moveTo(x + pinSpacing * 9 / 4, y);
polyline.lineTo(x + pinSpacing * 11 / 4, y);
polyline.moveTo(x + pinSpacing * 13 / 4, y);
polyline.lineTo(x + pinSpacing * 15 / 4, y);
polyline.moveTo(x + pinSpacing * 17 / 4, y);
polyline.lineTo(x + pinSpacing * 19 / 4, y);
// plate
polyline.moveTo(x + pinSpacing * 3 / 2, y - pinSpacing);
polyline.lineTo(x + pinSpacing * 9 / 2, y - pinSpacing);
// cathode
if (directlyHeated) {
polyline.moveTo(controlPoints[2].x, controlPoints[2].y - pinSpacing);
polyline.lineTo(controlPoints[2].x + pinSpacing, controlPoints[2].y - pinSpacing * 2);
polyline.lineTo(controlPoints[4].x, controlPoints[4].y - pinSpacing);
} else {
polyline.moveTo(x + pinSpacing * 2, y + pinSpacing);
polyline.lineTo(x + pinSpacing * 4, y + pinSpacing);
}
body[0] = polyline;
// connectors
polyline = new GeneralPath();
// grid
polyline.moveTo(x, y);
polyline.lineTo(x + pinSpacing, y);
// plate
polyline.moveTo(controlPoints[1].x, controlPoints[1].y);
polyline.lineTo(x + pinSpacing * 3, y - pinSpacing);
// cathode
if (directlyHeated) {
polyline.moveTo(controlPoints[2].x, controlPoints[2].y);
polyline.lineTo(controlPoints[2].x, controlPoints[2].y - pinSpacing);
polyline.moveTo(controlPoints[4].x, controlPoints[4].y);
polyline.lineTo(controlPoints[4].x, controlPoints[4].y - pinSpacing);
} else {
polyline.moveTo(controlPoints[2].x, controlPoints[2].y);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing);
if (showHeaters) {
polyline.moveTo(controlPoints[3].x, controlPoints[3].y);
polyline.lineTo(controlPoints[3].x, controlPoints[3].y - pinSpacing);
polyline.lineTo(controlPoints[3].x + pinSpacing / 2, controlPoints[3].y - 3 * pinSpacing / 2);
polyline.moveTo(controlPoints[4].x, controlPoints[4].y);
polyline.lineTo(controlPoints[4].x, controlPoints[4].y - pinSpacing);
polyline.lineTo(controlPoints[4].x - pinSpacing / 2, controlPoints[4].y - 3 * pinSpacing / 2);
}
}
body[1] = polyline;
// bulb
body[2] = new Ellipse2D.Double(x + pinSpacing / 2, y - pinSpacing * 5 / 2, pinSpacing * 5, pinSpacing * 5);
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawLine(width / 4, height / 4, width * 3 / 4, height / 4);
g2d.drawLine(width / 2, height / 4, width / 2, 0);
g2d.drawLine(width / 4 + 2 * width / 32, height * 3 / 4, width * 3 / 4 - 4 * width / 32, height * 3 / 4);
g2d.drawLine(width / 4 + 2 * width / 32, height * 3 / 4, width / 4 + 2 * width / 32, height - 1);
g2d.drawOval(1, 1, width - 1 - 2 * width / 32, height - 1 - 2 * width / 32);
g2d.drawLine(0, height / 2, width / 8, height / 2);
g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 0, new float[] {3f}, 6f));
g2d.drawLine(width / 8, height / 2, width * 7 / 8, height / 2);
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
protected 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 * 3;
controlPoints[1].y = y - pinSpacing * 3;
controlPoints[2].x = x + pinSpacing * 2;
controlPoints[2].y = y + pinSpacing * 3;
controlPoints[3].x = x + pinSpacing * 3;
controlPoints[3].y = y + pinSpacing * 3;
controlPoints[4].x = x + pinSpacing * 4;
controlPoints[4].y = y + pinSpacing * 3;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
// Invalidate body
body = null;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
if (directlyHeated) {
return index != 3 ? VisibilityPolicy.WHEN_SELECTED : VisibilityPolicy.NEVER;
} else if (showHeaters) {
return VisibilityPolicy.WHEN_SELECTED;
} else {
return index < 3 ? VisibilityPolicy.WHEN_SELECTED : VisibilityPolicy.NEVER;
}
}
@Override
public boolean isControlPointSticky(int index) {
if (directlyHeated) {
return index != 3;
} else if (showHeaters) {
return true;
} else {
return index < 3;
}
}
@Override
protected Point getTextLocation() {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
return new Point(controlPoints[0].x + pinSpacing * 5, controlPoints[0].y + pinSpacing * 2);
}
@EditableProperty(name = "Directly heated")
public boolean getDirectlyHeated() {
return directlyHeated;
}
public void setDirectlyHeated(boolean directlyHeated) {
this.directlyHeated = directlyHeated;
// Invalidate body
body = null;
}
}
@@ -0,0 +1,328 @@
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.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
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.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 = "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<String> {
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(21d, 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, boolean outlineMode, 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));
}
if (componentState != ComponentState.DRAGGING) {
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BODY_COLOR);
g2d.fill(body);
}
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);
// Draw pins
if (!outlineMode) {
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;
}
}
}