Compare commits

..

26 Commits

Author SHA1 Message Date
bancika ca492354ab 2011-01-30 18:47:44 +00:00
bancika 629fb5fff7 2011-01-30 18:46:38 +00:00
bancika bc154608f4 allow property edit validation 2011-01-30 17:21:42 +00:00
bancika a8cc661d09 better error handling when drawing 2011-01-30 14:10:38 +00:00
bancika 0b10f0bfe3 V1 file importer can recognize hookup wire and transistors 2011-01-30 12:02:29 +00:00
bancika f435571aae added keyboard shortcuts to some menu options 2011-01-30 11:43:54 +00:00
bancika 6bb248032f added square pad 2011-01-30 11:32:55 +00:00
bancika 1b04023a93 added axial electrolytic 2011-01-29 22:38:46 +00:00
bancika a32c8c4c8d added axial electrolytic 2011-01-29 22:35:09 +00:00
bancika 4a89159c80 reset component selection when switching tabs 2011-01-29 22:00:33 +00:00
bancika e5113e110e reset component selection when switching tabs 2011-01-29 22:00:01 +00:00
bancika c2051fcea2 improved electrolytic cap and resistor 2011-01-29 21:56:43 +00:00
bancika a42592410e improved electrolytic cap and resistor 2011-01-29 21:55:51 +00:00
bancika 22185a2d14 Potentiometer misdraw at 180 degrees 2011-01-29 18:31:25 +00:00
bancika ac6aaf4e06 added LED 2011-01-29 13:47:00 +00:00
bancika 1be52c1dfa improved zooming 2011-01-29 09:49:28 +00:00
bancika 328d09123b removed sysout 2011-01-29 09:02:19 +00:00
bancika 04cd80b561 added TO220 transistor
improved status text
2011-01-29 08:59:53 +00:00
bancika 3a419ba3bc added transistor 2011-01-28 20:05:37 +00:00
bancika 971ceb7160 added template support 2011-01-28 19:21:35 +00:00
bancika e0d8990954 added template support 2011-01-28 19:19:05 +00:00
bancika a70ec95822 added template support 2011-01-28 19:13:49 +00:00
bancika 8aacf915e3 added template support 2011-01-28 18:57:21 +00:00
bancika 777d3f6deb added template support 2011-01-28 18:55:40 +00:00
bancika 7de327b9bd fixed point visibility on curved trace
added option to hide color bands on the resistor
2011-01-28 17:48:46 +00:00
bancika 11b7756a59 added resistor color codes
fixed double value parsing
2011-01-27 22:34:41 +00:00
53 changed files with 1908 additions and 294 deletions
+10 -11
View File
@@ -1,23 +1,22 @@
<map>
<entry>
<string>metric</string>
<boolean>true</boolean>
<string>lastPath</string>
<string>C:\Documents and Settings\Branislav Stojkovic\Desktop\oldFiles</string>
</entry>
<entry>
<string>zoom</string>
<double>1.0</double>
</entry>
<entry>
<string>lastPath</string>
<string>C:\Documents and Settings\Branislav Stojkovic\Desktop</string>
<string>metric</string>
<boolean>true</boolean>
</entry>
<entry>
<string>default.org.diylc.components.misc.Label:Color</string>
<awt-color>
<red>255</red>
<green>0</green>
<blue>0</blue>
<alpha>255</alpha>
</awt-color>
<string>showTemplatesAtStartup</string>
<boolean>false</boolean>
</entry>
<entry>
<string>default.org.diylc.components.semiconductors.TransistorTO92:Orientation</string>
<org.diylc.common.Orientation>DEFAULT</org.diylc.common.Orientation>
</entry>
</map>
Binary file not shown.
Binary file not shown.
+13 -3
View File
@@ -10,7 +10,9 @@ import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.diylc.presenter.Presenter;
import org.diylc.swing.gui.MainFrame;
import org.diylc.swing.gui.TemplateDialog;
import com.diyfever.gui.miscutils.ConfigurationManager;
import com.diyfever.gui.miscutils.PropertyInjector;
/**
@@ -37,7 +39,7 @@ public class DIYLCStarter {
} catch (Exception e) {
LOG.error("Could not initialize log4j configuration", e);
}
LOG.info("Starting DIYLC with working directory " + System.getProperty("user.dir"));
try {
@@ -49,7 +51,16 @@ public class DIYLCStarter {
MainFrame mainFrame = new MainFrame();
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
boolean showTemplates = ConfigurationManager.getInstance().readBoolean(
TemplateDialog.SHOW_TEMPLATES_KEY, true);
if (showTemplates) {
TemplateDialog templateDialog = new TemplateDialog(mainFrame, mainFrame.getPresenter());
if (!templateDialog.getFiles().isEmpty()) {
templateDialog.setVisible(true);
}
}
url = DIYLCStarter.class.getResource("/config.properties");
properties = new Properties();
try {
@@ -59,6 +70,5 @@ public class DIYLCStarter {
} catch (Exception e) {
LOG.error("Could not read config.properties file", e);
}
}
}
+8 -2
View File
@@ -72,6 +72,12 @@ public enum EventType {
* current cursor location (not taking zoom into account).
*/
MOUSE_MOVED,
LAYER_STATE_CHANGED;
;
/**
* Called when a layer status is changed. The first parameter is a set of indices of locked layers. All layers not included are considered unlocked.
*/
LAYER_STATE_CHANGED,
/**
* Called to update the status message. New status message is passed as a first parameter.
*/
STATUS_MESSAGE_CHANGED;
}
+5
View File
@@ -0,0 +1,5 @@
package org.diylc.common;
public enum Power {
}
@@ -3,6 +3,8 @@ package org.diylc.common;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.diylc.core.IPropertyValidator;
/**
* Entity class for editable properties extracted from component objects.
* Represents a single editable property together with it's current value.
@@ -17,19 +19,21 @@ public class PropertyWrapper implements Cloneable {
private Method setter;
private Method getter;
private boolean defaultable;
private IPropertyValidator validator;
public PropertyWrapper(String name, Class<?> type, Method getter, Method setter,
boolean defaultable) {
boolean defaultable, IPropertyValidator validator) {
super();
this.name = name;
this.type = type;
this.getter = getter;
this.setter = setter;
this.defaultable = defaultable;
this.validator = validator;
}
public void readFrom(Object object) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
public void readFrom(Object object) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
this.value = getter.invoke(object);
}
@@ -42,8 +46,8 @@ public class PropertyWrapper implements Cloneable {
// }
// }
public void writeTo(Object object) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
public void writeTo(Object object) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
setter.invoke(object, value);
}
@@ -67,8 +71,8 @@ public class PropertyWrapper implements Cloneable {
return defaultable;
}
public void setDefaultable(boolean defaultable) {
this.defaultable = defaultable;
public IPropertyValidator getValidator() {
return validator;
}
// @Override
@@ -0,0 +1,14 @@
package org.diylc.common;
public enum ResistorColorCode {
NONE, _4_BAND, _5_BAND;
@Override
public String toString() {
if (name().startsWith("_")) {
return name().substring(1).replace("_", " ").toLowerCase();
}
return name().substring(0, 1).toUpperCase() + name().substring(1).toLowerCase();
}
}
@@ -35,21 +35,21 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
public static Size LEAD_THICKNESS = new Size(0.6d, SizeUnit.mm);
public static Size DEFAULT_SIZE = new Size(1d, SizeUnit.in);
protected Size length;
protected Size width;
protected Size height;
protected Point[] points = new Point[] {
new Point((int) (-DEFAULT_SIZE.convertToPixels() / 2), 0),
new Point(DEFAULT_SIZE.convertToPixels() / 2, 0) };
protected Color bodyColor = getDefaultBodyColor();
protected Color borderColor = getDefaultBorderColor();
protected Color bodyColor = Color.white;
protected Color borderColor = Color.black;
protected Color labelColor = LABEL_COLOR;
protected Display display = Display.NAME;
protected AbstractLeadedComponent() {
super();
try {
this.length = getDefaultLength().clone();
this.width = getDefaultWidth().clone();
this.height = getDefaultHeight().clone();
} catch (CloneNotSupportedException e) {
// This should never happen because Size supports cloning.
} catch (NullPointerException e) {
@@ -145,16 +145,16 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
}
/**
* @return default component width.
* @return default component length.
*/
protected abstract Size getDefaultWidth();
protected abstract Size getDefaultLength();
/**
* Returns default component height.
* Returns default component width.
*
* @return
*/
protected abstract Size getDefaultHeight();
protected abstract Size getDefaultWidth();
/**
* @return shape that represents component body. Shape should not be
@@ -162,16 +162,6 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
*/
protected abstract Shape getBodyShape();
/**
* @return default component body color.
*/
protected abstract Color getDefaultBodyColor();
/**
* @return default component border color.
*/
protected abstract Color getDefaultBorderColor();
/**
* @return default lead thickness. Override this method to change it.
*/
@@ -230,7 +220,16 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
this.borderColor = borderColor;
}
@EditableProperty(defaultable = true)
@EditableProperty(name = "Length", defaultable = true)
public Size getLength() {
return length;
}
public void setLength(Size length) {
this.length = length;
}
@EditableProperty(name = "Width", defaultable = true)
public Size getWidth() {
return width;
}
@@ -239,15 +238,6 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
this.width = width;
}
@EditableProperty(defaultable = true)
public Size getHeight() {
return height;
}
public void setHeight(Size height) {
this.height = height;
}
@EditableProperty
public Display getDisplay() {
return display;
@@ -0,0 +1,13 @@
package org.diylc.core;
/**
* Validator that allows all values.
*
* @author Branislav Stojkovic
*/
public class AllowAllValidator implements IPropertyValidator {
@Override
public void validate(Object value) throws ValidationException {
}
}
@@ -0,0 +1,16 @@
package org.diylc.core;
/**
* Interface for validating property value changes.
*
* @author Branislav Stojkovic
*/
public interface IPropertyValidator {
/**
* @param value
* @throws ValidationException
* if validation fails. Message will contain the reason.
*/
void validate(Object value) throws ValidationException;
}
+19 -3
View File
@@ -7,6 +7,7 @@ import java.util.List;
import java.util.Set;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.PositiveMeasureValidator;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@@ -92,7 +93,7 @@ public class Project implements Serializable {
this.height = height;
}
@EditableProperty(name = "Grid spacing")
@EditableProperty(name = "Grid spacing", validatorClass = SpacingValidator.class)
public Size getGridSpacing() {
return gridSpacing;
}
@@ -118,7 +119,7 @@ public class Project implements Serializable {
public Set<Set<IDIYComponent<?>>> getGroups() {
return groups;
}
public Set<Integer> getLockedLayers() {
return lockedLayers;
}
@@ -177,12 +178,27 @@ public class Project implements Serializable {
return false;
return true;
}
@Override
public String toString() {
return title;
}
public static class SpacingValidator extends PositiveMeasureValidator {
@Override
public void validate(Object value) throws ValidationException {
super.validate(value);
Size size = (Size) value;
if (size.compareTo(new Size(1d, SizeUnit.mm)) < 0) {
throw new ValidationException("must be greater than 1mm");
}
if (size.compareTo(new Size(1d, SizeUnit.in)) > 0) {
throw new ValidationException("must be less than 1in");
}
}
}
// @Override
// public Project clone() throws CloneNotSupportedException {
// List<IDIYComponent> clonedComponents = new
@@ -0,0 +1,11 @@
package org.diylc.core;
public class ValidationException extends Exception {
private static final long serialVersionUID = 1L;
public ValidationException(String message) {
super(message);
}
}
@@ -3,6 +3,9 @@ package org.diylc.core.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.diylc.core.AllowAllValidator;
import org.diylc.core.IPropertyValidator;
/**
* Used to annotate editable component property. Editable property XYZ must have
* both getter and setter named <code>getXYZ</code> and <code>setXYZ</code>
@@ -30,4 +33,10 @@ public @interface EditableProperty {
* @return
*/
boolean defaultable() default true;
/**
* Class of validator to use to
* @return
*/
Class<? extends IPropertyValidator> validatorClass() default AllowAllValidator.class;
}
@@ -0,0 +1,20 @@
package org.diylc.core.annotations;
import org.diylc.core.IPropertyValidator;
import org.diylc.core.ValidationException;
import org.diylc.core.measures.AbstractMeasure;
public class PositiveMeasureValidator implements IPropertyValidator {
@Override
public void validate(Object value) throws ValidationException {
if (value instanceof AbstractMeasure) {
AbstractMeasure measure = (AbstractMeasure) value;
if (measure.getValue() <= 0) {
throw new ValidationException("must be greater than zero.");
}
} else {
throw new ValidationException("wrong data type, measure expected.");
}
}
}
@@ -1,9 +1,20 @@
package org.diylc.core.measures;
import java.awt.Color;
import org.diylc.common.ResistorColorCode;
public class Resistance extends AbstractMeasure<ResistanceUnit> {
private static final long serialVersionUID = 1L;
private static final Color[] COLOR_DIGITS = new Color[] { Color.black, Color.decode("#8B4513"),
Color.red, Color.orange, Color.yellow, Color.decode("#76EE00"), Color.blue,
Color.decode("#91219E"), Color.lightGray, Color.white };
private static final Color[] COLOR_MULTIPLIER = new Color[] { Color.lightGray.brighter(),
Color.decode("#FFB90F"), Color.black, Color.decode("#8B4513"), Color.red, Color.orange,
Color.yellow, Color.decode("#76EE00"), Color.blue };
public Resistance() {
super();
// TODO Auto-generated constructor stub
@@ -19,6 +30,42 @@ public class Resistance extends AbstractMeasure<ResistanceUnit> {
return new Resistance(value, unit);
}
public Color[] getColorCode(ResistorColorCode resistorColorCode) {
Color[] bands;
double base = getValue() * getUnit().getFactor();
int multiplier = 0;
while (base > (resistorColorCode == ResistorColorCode._4_BAND ? 99 : 999)) {
multiplier += 1;
base /= 10;
}
while (base < (resistorColorCode == ResistorColorCode._4_BAND ? 10 : 100)) {
multiplier -= 1;
base *= 10;
}
if (multiplier > 6 || multiplier < -2) {
// Out of range.
return new Color[] {};
}
switch (resistorColorCode) {
case _4_BAND:
bands = new Color[3];
bands[0] = COLOR_DIGITS[(int) Math.round(base / 10)];
bands[1] = COLOR_DIGITS[(int) Math.round(base % 10)];
bands[2] = COLOR_MULTIPLIER[multiplier + 2];
break;
case _5_BAND:
bands = new Color[4];
bands[0] = COLOR_DIGITS[(int) Math.round(base / 100)];
bands[1] = COLOR_DIGITS[(int) Math.round(base / 10 % 10)];
bands[2] = COLOR_DIGITS[(int) Math.round(base % 10)];
bands[3] = COLOR_MULTIPLIER[multiplier + 2];
break;
default:
bands = new Color[] {};
}
return bands;
}
public static Resistance parseResistance(String value) {
for (ResistanceUnit unit : ResistanceUnit.values()) {
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
+6 -1
View File
@@ -2,7 +2,7 @@ package org.diylc.core.measures;
import org.diylc.utils.Constants;
public class Size extends AbstractMeasure<SizeUnit> {
public class Size extends AbstractMeasure<SizeUnit> implements Comparable<Size> {
private static final long serialVersionUID = 1L;
@@ -39,4 +39,9 @@ public class Size extends AbstractMeasure<SizeUnit> {
}
throw new IllegalArgumentException("Could not parse size: " + value);
}
@Override
public int compareTo(Size o) {
return new Double(value * unit.getFactor()).compareTo(o.getValue() * o.getUnit().getFactor());
}
}
@@ -19,6 +19,7 @@ import org.diylc.common.ComponentType;
import org.diylc.common.PropertyWrapper;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IPropertyValidator;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@@ -35,7 +36,8 @@ public class ComponentProcessor {
private static ComponentProcessor instance;
private Map<Class<?>, List<PropertyWrapper>> propertyCache;
private Map<String, List<PropertyWrapper>> propertyCache;
private Map<String, IPropertyValidator> propertyValidatorCache;
private Map<String, ComponentType> componentTypeMap;
private Cloner cloner;
@@ -50,8 +52,9 @@ public class ComponentProcessor {
private ComponentProcessor() {
super();
this.cloner = new Cloner();
this.propertyCache = new HashMap<Class<?>, List<PropertyWrapper>>();
this.propertyCache = new HashMap<String, List<PropertyWrapper>>();
this.componentTypeMap = new HashMap<String, ComponentType>();
this.propertyValidatorCache = new HashMap<String, IPropertyValidator>();
}
public ComponentType extractComponentTypeFrom(Class<? extends IDIYComponent<?>> clazz) {
@@ -117,8 +120,8 @@ public class ComponentProcessor {
* @return
*/
public List<PropertyWrapper> extractProperties(Class<?> clazz) {
if (propertyCache.containsKey(clazz)) {
return cloner.deepClone(propertyCache.get(clazz));
if (propertyCache.containsKey(clazz.getName())) {
return cloner.deepClone(propertyCache.get(clazz.getName()));
}
List<PropertyWrapper> properties = new ArrayList<PropertyWrapper>();
for (Method method : clazz.getMethods()) {
@@ -133,10 +136,13 @@ public class ComponentProcessor {
} else {
name = annotation.name();
}
IPropertyValidator validator = getPropertyValidator(annotation
.validatorClass());
Method setter = clazz.getMethod("set" + method.getName().substring(3),
method.getReturnType());
PropertyWrapper property = new PropertyWrapper(name,
method.getReturnType(), method, setter, annotation.defaultable());
method.getReturnType(), method, setter, annotation.defaultable(),
validator);
properties.add(property);
}
} catch (NoSuchMethodException e) {
@@ -146,7 +152,7 @@ public class ComponentProcessor {
}
}
propertyCache.put(clazz, properties);
propertyCache.put(clazz.getName(), properties);
return cloner.deepClone(properties);
}
@@ -187,4 +193,19 @@ public class ComponentProcessor {
Collections.sort(properties, ComparatorFactory.getInstance().getPropertyNameComparator());
return properties;
}
private IPropertyValidator getPropertyValidator(Class<? extends IPropertyValidator> clazz) {
if (propertyValidatorCache.containsKey(clazz.getName())) {
return propertyValidatorCache.get(clazz.getName());
}
IPropertyValidator validator;
try {
validator = clazz.newInstance();
} catch (Exception e) {
LOG.error("Could not instantiate validator for " + clazz.getName(), e);
return null;
}
propertyValidatorCache.put(clazz.getName(), validator);
return validator;
}
}
@@ -16,6 +16,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.diylc.common.DrawOption;
import org.diylc.common.EventType;
import org.diylc.common.GridType;
@@ -38,6 +39,8 @@ import com.diyfever.gui.simplemq.MessageDispatcher;
*/
public class DrawingManager {
private static final Logger LOG = Logger.getLogger(DrawingManager.class);
public static int CONTROL_POINT_SIZE = 7;
public static final String ANTIALIASING_KEY = "anti-aliasing";
@@ -56,6 +59,7 @@ public class DrawingManager {
private Composite slotComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
private Composite lockedComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
private List<IDIYComponent<?>> failedComponents = new ArrayList<IDIYComponent<?>>();
private double zoomLevel = 1d;// ConfigurationManager.getInstance().readDouble(ZOOM_KEY,
// 1d);
@@ -69,12 +73,31 @@ public class DrawingManager {
lastDrawnStateMap = new HashMap<IDIYComponent<?>, ComponentState>();
}
public void drawProject(Graphics2D g2d, Project project, Set<DrawOption> drawOptions,
IComponentFiler filter, Rectangle selectionRect, List<IDIYComponent<?>> selectedComponents,
Set<IDIYComponent<?>> lockedComponents, Set<IDIYComponent<?>> groupedComponents,
List<Point> controlPointSlot, IDIYComponent<?> componentSlot, boolean dragInProgress) {
/**
* Paints the project onto the canvas and returns the list of components
* that failed to draw.
*
* @param g2d
* @param project
* @param drawOptions
* @param filter
* @param selectionRect
* @param selectedComponents
* @param lockedComponents
* @param groupedComponents
* @param controlPointSlot
* @param componentSlot
* @param dragInProgress
* @return
*/
public List<IDIYComponent<?>> drawProject(Graphics2D g2d, Project project,
Set<DrawOption> drawOptions, IComponentFiler filter, Rectangle selectionRect,
List<IDIYComponent<?>> selectedComponents, Set<IDIYComponent<?>> lockedComponents,
Set<IDIYComponent<?>> groupedComponents, List<Point> controlPointSlot,
IDIYComponent<?> componentSlot, boolean dragInProgress) {
failedComponents.clear();
if (project == null) {
return;
return failedComponents;
}
G2DWrapper g2dWrapper = new G2DWrapper(g2d);
@@ -158,7 +181,12 @@ public class DrawingManager {
g2d.setComposite(lockedComposite);
}
// Draw the component through the g2dWrapper.
component.draw(g2dWrapper, state, project, g2dWrapper);
try {
component.draw(g2dWrapper, state, project, g2dWrapper);
} catch (Exception e) {
LOG.error("Error drawing " + component.getName(), e);
failedComponents.add(component);
}
Area area = g2dWrapper.finishedDrawingComponent();
if (trackArea) {
componentAreaMap.put(component, area);
@@ -214,7 +242,12 @@ public class DrawingManager {
if (componentSlot != null) {
g2dWrapper.startedDrawingComponent();
g2dWrapper.setComposite(slotComposite);
componentSlot.draw(g2dWrapper, ComponentState.NORMAL, project, g2dWrapper);
try {
componentSlot.draw(g2dWrapper, ComponentState.NORMAL, project, g2dWrapper);
} catch (Exception e) {
LOG.error("Error drawing " + componentSlot.getName(), e);
failedComponents.add(componentSlot);
}
g2dWrapper.finishedDrawingComponent();
}
@@ -258,6 +291,8 @@ public class DrawingManager {
g2d.draw(area);
}
}
return failedComponents;
}
public double getZoomLevel() {
+20 -6
View File
@@ -50,7 +50,7 @@ public class Presenter implements IPlugInPort {
private static final Logger LOG = Logger.getLogger(Presenter.class);
public static final VersionNumber CURRENT_VERSION = new VersionNumber(3, 0, 4);
public static final VersionNumber CURRENT_VERSION = new VersionNumber(3, 0, 5);
public static final String DEFAULTS_KEY_PREFIX = "default.";
public static final String METRIC_KEY = "metric";
@@ -299,7 +299,8 @@ public class Presenter implements IPlugInPort {
groupedComponents.add(component);
}
}
// Don't draw the component in the slot if both control points match.
// Don't draw the component in the slot if both control points
// match.
IDIYComponent<?> componentSlotToDraw;
if (instantiationManager.getFirstControlPoint() != null
&& instantiationManager.getPotentialControlPoint() != null
@@ -309,10 +310,23 @@ public class Presenter implements IPlugInPort {
} else {
componentSlotToDraw = instantiationManager.getComponentSlot();
}
drawingManager.drawProject(g2d, currentProject, drawOptions, filter, selectionRect,
selectedComponents, getLockedComponents(), groupedComponents, Arrays.asList(
instantiationManager.getFirstControlPoint(), instantiationManager
.getPotentialControlPoint()), componentSlotToDraw, dragInProgress);
List<IDIYComponent<?>> failedComponents = drawingManager.drawProject(g2d, currentProject,
drawOptions, filter, selectionRect, selectedComponents, getLockedComponents(),
groupedComponents, Arrays.asList(instantiationManager.getFirstControlPoint(),
instantiationManager.getPotentialControlPoint()), componentSlotToDraw,
dragInProgress);
List<String> failedComponentNames = new ArrayList<String>();
for (IDIYComponent<?> component : failedComponents) {
failedComponentNames.add(component.getName());
}
Collections.sort(failedComponentNames);
if (!failedComponentNames.isEmpty()) {
messageDispatcher.dispatchMessage(EventType.STATUS_MESSAGE_CHANGED,
"<html><font color='red'>Failed to draw components: "
+ Utils.toCommaString(failedComponentNames) + "</font></html>");
} else {
messageDispatcher.dispatchMessage(EventType.STATUS_MESSAGE_CHANGED, "");
}
}
/**
@@ -23,6 +23,7 @@ import org.diylc.components.boards.BlankBoard;
import org.diylc.components.boards.PerfBoard;
import org.diylc.components.boards.VeroBoard;
import org.diylc.components.connectivity.CopperTrace;
import org.diylc.components.connectivity.HookupWire;
import org.diylc.components.connectivity.Jumper;
import org.diylc.components.connectivity.SolderPad;
import org.diylc.components.misc.Label;
@@ -31,6 +32,7 @@ import org.diylc.components.passive.RadialFilmCapacitor;
import org.diylc.components.passive.Resistor;
import org.diylc.components.semiconductors.DIL_IC;
import org.diylc.components.semiconductors.DiodePlastic;
import org.diylc.components.semiconductors.TransistorTO92;
import org.diylc.core.IDIYComponent;
import org.diylc.core.Project;
import org.diylc.core.measures.Capacitance;
@@ -77,7 +79,7 @@ public class ProjectFileManager {
xStream.autodetectAnnotations(true);
this.messageDispatcher = messageDispatcher;
}
public void startNewFile() {
currentFileName = null;
modified = false;
@@ -251,6 +253,16 @@ public class ProjectFileManager {
jumper.setControlPoint(point1, 0);
jumper.setControlPoint(point2, 1);
component = jumper;
} else if (nodeName.equalsIgnoreCase("wire")) {
LOG.debug("Recognized " + nodeName);
HookupWire wire = new HookupWire();
Point midPoint = new Point((point1.x + point2.x) / 2, (point1.y + point2.y) / 2);
wire.setName(nameAttr);
wire.setControlPoint(point1, 0);
wire.setControlPoint(midPoint, 1);
wire.setControlPoint(midPoint, 2);
wire.setControlPoint(point2, 3);
component = wire;
} else if (nodeName.equalsIgnoreCase("resistor")) {
LOG.debug("Recognized " + nodeName);
Resistor resistor = new Resistor();
@@ -260,8 +272,8 @@ public class ProjectFileManager {
} catch (Exception e) {
LOG.debug("Could not set value of " + nameAttr);
}
resistor.setWidth(new Size(6d, SizeUnit.mm));
resistor.setHeight(new Size(2d, SizeUnit.mm));
resistor.setLength(new Size(6d, SizeUnit.mm));
resistor.setWidth(new Size(2d, SizeUnit.mm));
resistor.setControlPoint(point1, 0);
resistor.setControlPoint(point2, 1);
component = resistor;
@@ -274,8 +286,8 @@ public class ProjectFileManager {
} catch (Exception e) {
LOG.debug("Could not set value of " + nameAttr);
}
capacitor.setWidth(new Size(6d, SizeUnit.mm));
capacitor.setHeight(new Size(2d, SizeUnit.mm));
capacitor.setLength(new Size(6d, SizeUnit.mm));
capacitor.setWidth(new Size(2d, SizeUnit.mm));
capacitor.setControlPoint(point1, 0);
capacitor.setControlPoint(point2, 1);
component = capacitor;
@@ -290,13 +302,13 @@ public class ProjectFileManager {
}
String sizeAttr = node.getAttributes().getNamedItem("Size").getNodeValue();
if (sizeAttr.equalsIgnoreCase("small")) {
capacitor.setWidth(new Size(3d, SizeUnit.mm));
capacitor.setLength(new Size(3d, SizeUnit.mm));
} else if (sizeAttr.equalsIgnoreCase("medium")) {
capacitor.setWidth(new Size(5d, SizeUnit.mm));
capacitor.setLength(new Size(5d, SizeUnit.mm));
} else if (sizeAttr.equalsIgnoreCase("large")) {
capacitor.setWidth(new Size(7d, SizeUnit.mm));
capacitor.setLength(new Size(7d, SizeUnit.mm));
} else {
capacitor.setWidth(new Size(4d, SizeUnit.mm));
capacitor.setLength(new Size(4d, SizeUnit.mm));
}
capacitor.setControlPoint(point1, 0);
capacitor.setControlPoint(point2, 1);
@@ -310,11 +322,32 @@ public class ProjectFileManager {
} catch (Exception e) {
LOG.debug("Could not set value of " + nameAttr);
}
capacitor.setWidth(new Size(6d, SizeUnit.mm));
capacitor.setHeight(new Size(2d, SizeUnit.mm));
capacitor.setLength(new Size(6d, SizeUnit.mm));
capacitor.setWidth(new Size(2d, SizeUnit.mm));
capacitor.setControlPoint(point1, 0);
capacitor.setControlPoint(point2, 1);
component = capacitor;
} else if (nodeName.equalsIgnoreCase("transistor")) {
LOG.debug("Recognized " + nodeName);
TransistorTO92 transistor = new TransistorTO92();
transistor.setName(nameAttr);
try {
transistor.setValue(valueAttr);
} catch (Exception e) {
LOG.debug("Could not set value of " + nameAttr);
}
transistor.setControlPoint(point1, 0);
if (point1.y > point2.y) {
transistor.setOrientation(Orientation._180);
} else if (point1.y < point2.y) {
transistor.setOrientation(Orientation.DEFAULT);
} else if (point1.x < point2.x) {
transistor.setOrientation(Orientation._270);
} else if (point1.x > point2.x) {
transistor.setOrientation(Orientation._90);
}
// capacitor.setControlPoint(point2, 1);
component = transistor;
} else if (nodeName.equalsIgnoreCase("ic")) {
LOG.debug("Recognized " + nodeName);
DIL_IC ic = new DIL_IC();
+14 -6
View File
@@ -124,11 +124,11 @@ public class ActionFactory {
public DeleteSelectionAction createDeleteSelectionAction(IPlugInPort plugInPort) {
return new DeleteSelectionAction(plugInPort);
}
public SendToBackAction createSendToBackAction(IPlugInPort plugInPort) {
return new SendToBackAction(plugInPort);
}
public BringToFrontAction createBringToFrontAction(IPlugInPort plugInPort) {
return new BringToFrontAction(plugInPort);
}
@@ -145,6 +145,8 @@ public class ActionFactory {
super();
this.plugInPort = plugInPort;
putValue(AbstractAction.NAME, "New");
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N,
ActionEvent.CTRL_MASK));
putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentPlainYellow.getIcon());
}
@@ -184,6 +186,8 @@ public class ActionFactory {
this.plugInPort = plugInPort;
this.swingUI = swingUI;
putValue(AbstractAction.NAME, "Open");
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O,
ActionEvent.CTRL_MASK));
putValue(AbstractAction.SMALL_ICON, IconLoader.FolderOut.getIcon());
}
@@ -232,6 +236,8 @@ public class ActionFactory {
this.plugInPort = plugInPort;
this.swingUI = swingUI;
putValue(AbstractAction.NAME, "Save");
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S,
ActionEvent.CTRL_MASK));
putValue(AbstractAction.SMALL_ICON, IconLoader.DiskBlue.getIcon());
}
@@ -299,6 +305,8 @@ public class ActionFactory {
this.plugInPort = plugInPort;
this.swingUI = swingUI;
putValue(AbstractAction.NAME, "Save As");
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S,
ActionEvent.CTRL_MASK | ActionEvent.SHIFT_MASK));
putValue(AbstractAction.SMALL_ICON, IconLoader.DiskBlue.getIcon());
}
@@ -457,6 +465,8 @@ public class ActionFactory {
super();
this.drawingProvider = drawingProvider;
putValue(AbstractAction.NAME, "Print...");
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_P,
ActionEvent.CTRL_MASK));
putValue(AbstractAction.SMALL_ICON, IconLoader.Print.getIcon());
}
@@ -657,8 +667,6 @@ public class ActionFactory {
super();
this.plugInPort = plugInPort;
putValue(AbstractAction.NAME, "Edit Project");
putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E,
ActionEvent.CTRL_MASK));
putValue(AbstractAction.SMALL_ICON, IconLoader.DocumentEdit.getIcon());
}
@@ -741,7 +749,7 @@ public class ActionFactory {
plugInPort.deleteSelectedComponents();
}
}
public static class SendToBackAction extends AbstractAction {
private static final long serialVersionUID = 1L;
@@ -761,7 +769,7 @@ public class ActionFactory {
plugInPort.sendSelectionToBack();
}
}
public static class BringToFrontAction extends AbstractAction {
private static final long serialVersionUID = 1L;
+5 -3
View File
@@ -12,7 +12,6 @@ import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import javax.swing.Action;
import javax.swing.BoxLayout;
@@ -34,7 +33,6 @@ import org.diylc.common.EventType;
import org.diylc.common.IPlugIn;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ITask;
import org.diylc.core.IView;
import org.diylc.images.IconLoader;
import org.diylc.presenter.Presenter;
import org.diylc.swing.ISwingUI;
@@ -115,6 +113,10 @@ public class MainFrame extends JFrame implements ISwingUI {
// setGlassPane(new CustomGlassPane());
// getGlassPane().setVisible(true);
}
public Presenter getPresenter() {
return presenter;
}
@Override
public void setVisible(boolean b) {
@@ -299,7 +301,7 @@ public class MainFrame extends JFrame implements ISwingUI {
fileName = "Untitled";
}
String modified = (Boolean) params[1] ? " (modified)" : "";
setTitle(String.format("DIYLC %s alpha - %s %s", plugInPort
setTitle(String.format("DIYLC %s beta - %s %s", plugInPort
.getCurrentVersionNumber(), fileName, modified));
}
}
@@ -0,0 +1,278 @@
package org.diylc.swing.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.apache.log4j.Logger;
import org.diylc.common.DrawOption;
import org.diylc.common.IPlugInPort;
import org.diylc.core.IView;
import org.diylc.presenter.Presenter;
import com.diyfever.gui.miscutils.ConfigurationManager;
public class TemplateDialog extends JDialog {
private static final long serialVersionUID = 1L;
private static final Logger LOG = Logger.getLogger(TemplateDialog.class);
private static final Dimension panelSize = new Dimension(400, 300);
public static final String SHOW_TEMPLATES_KEY = "showTemplatesAtStartup";
private IPlugInPort plugInPort;
private JList fileList;
private JPanel canvasPanel;
private Presenter presenter;
private List<File> files;
private JCheckBox showTemplatesBox;
private JPanel mainPanel;
private JButton loadButton;
private JPanel infoPanel;
public TemplateDialog(JFrame owner, IPlugInPort plugInPort) {
super(owner, "Templates");
setModal(true);
setResizable(false);
this.plugInPort = plugInPort;
this.presenter = new Presenter(new IView() {
@Override
public int showConfirmDialog(String message, String title, int optionType,
int messageType) {
return JOptionPane.showConfirmDialog(TemplateDialog.this, message, title,
optionType, messageType);
}
@Override
public void showMessage(String message, String title, int messageType) {
JOptionPane.showMessageDialog(TemplateDialog.this, message, title, messageType);
}
});
// this.presenter.installPlugin(new IPlugIn() {
//
// @Override
// public void connect(IPlugInPort plugInPort) {
// }
//
// @Override
// public EnumSet<EventType> getSubscribedEventTypes() {
// return EnumSet.of(EventType.REPAINT);
// }
//
// @Override
// public void processMessage(EventType eventType, Object... params) {
// if (eventType == EventType.REPAINT) {
// getCanvasPanel().repaint();
// }
// }
// });
setContentPane(getMainPanel());
pack();
setLocationRelativeTo(owner);
}
public JPanel getMainPanel() {
if (mainPanel == null) {
mainPanel = new JPanel(new GridBagLayout());
mainPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.weightx = 0;
c.weighty = 1;
c.weightx = 1;
c.gridwidth = 2;
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(0, 0, 4, 0);
mainPanel.add(getInfoPanel(), c);
c.gridy = 1;
c.weightx = 0;
c.gridwidth = 1;
c.insets = new Insets(0, 0, 0, 0);
JScrollPane scrollPane = new JScrollPane(getFileList());
mainPanel.add(scrollPane, c);
c.gridx = 1;
c.weightx = 1;
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(scrollPane.getBorder());
panel.add(getCanvasPanel(), BorderLayout.CENTER);
mainPanel.add(panel, c);
c.gridx = 0;
c.gridy = 2;
c.weightx = 0;
c.weighty = 0;
c.anchor = GridBagConstraints.LAST_LINE_START;
c.fill = GridBagConstraints.NONE;
mainPanel.add(getShowTemplatesBox(), c);
c.gridx = 1;
c.anchor = GridBagConstraints.LAST_LINE_END;
c.insets = new Insets(4, 0, 0, 0);
mainPanel.add(getLoadButton(), c);
}
return mainPanel;
}
public JButton getLoadButton() {
if (loadButton == null) {
loadButton = new JButton("Load Template");
loadButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
plugInPort.loadProject(presenter.getCurrentProject(), true);
dispose();
}
});
}
return loadButton;
}
public JPanel getInfoPanel() {
if (infoPanel == null) {
infoPanel = new JPanel();
infoPanel.setBackground(Color.decode("#FFFFCC"));
infoPanel.setBorder(new JTextField().getBorder());
JLabel infoLabel = new JLabel(
"<html>Templates are semi-product layouts that are used as a starting point for your projects.<br>"
+ "Pick a templete in the left list and click \"Load Template\" to load it or close this dialog to continue.<br>"
+ "You can create your own templates by placing a DIY file into <b>diylc/templates</b> directory.</html>");
infoLabel.setOpaque(false);
infoPanel.add(infoLabel);
}
return infoPanel;
}
public JList getFileList() {
if (fileList == null) {
fileList = new JList(getFiles().toArray());
fileList.setPreferredSize(new Dimension(128, -1));
fileList.setCellRenderer(new DefaultListCellRenderer() {
private static final long serialVersionUID = 1L;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
if (value instanceof File) {
label.setText(((File) value).getName());
}
return label;
}
});
fileList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
File file = (File) fileList.getSelectedValue();
if (file != null) {
presenter.loadProjectFromFile(file.getAbsolutePath());
Dimension dim = presenter.getCanvasDimensions(true);
double xFactor = panelSize.getWidth() / dim.getWidth();
double yFactor = panelSize.getHeight() / dim.getHeight();
presenter.setZoomLevel(Math.min(xFactor, yFactor));
getCanvasPanel().repaint();
}
}
});
fileList.setSelectedIndex(0);
}
return fileList;
}
public JCheckBox getShowTemplatesBox() {
if (showTemplatesBox == null) {
showTemplatesBox = new JCheckBox("Show this dialog at startup");
showTemplatesBox.setSelected(true);
showTemplatesBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ConfigurationManager.getInstance().writeValue(SHOW_TEMPLATES_KEY,
showTemplatesBox.isSelected());
}
});
}
return showTemplatesBox;
}
public List<File> getFiles() {
if (files == null) {
files = new ArrayList<File>();
File dir = new File("templates");
if (dir.exists()) {
for (File f : dir.listFiles()) {
if (f.isFile() && f.getName().toLowerCase().endsWith(".diy")) {
files.add(f);
}
}
}
LOG.debug("Found " + files.size() + " templates");
}
return files;
}
public JPanel getCanvasPanel() {
if (canvasPanel == null) {
canvasPanel = new JPanel() {
private static final long serialVersionUID = 1L;
@Override
public void paint(Graphics g) {
super.paint(g);
// Graphics2D g2d = (Graphics2D) g;
// AffineTransform transform = g2d.getTransform();
presenter.draw((Graphics2D) g, EnumSet.of(DrawOption.ZOOM,
DrawOption.ANTIALIASING), null);
// g2d.setTransform(transform);
// Rectangle rect = canvasPanel.getBounds();
// BorderFactory.createEtchedBorder().paintBorder(canvasPanel,
// g, 0, 0,
// (int) rect.getWidth(), (int) rect.getHeight());
}
};
canvasPanel.setBackground(Color.white);
canvasPanel.setPreferredSize(panelSize);
}
return canvasPanel;
}
}
@@ -0,0 +1,26 @@
package org.diylc.swing.gui.editor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import org.diylc.common.PropertyWrapper;
public class BooleanEditor extends JCheckBox {
private static final long serialVersionUID = 1L;
public BooleanEditor(final PropertyWrapper property) {
super();
setSelected((Boolean) property.getValue());
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
property.setValue(isSelected());
}
});
}
}
@@ -37,8 +37,13 @@ public class FieldEditorFactory {
}
if (Byte.class.isAssignableFrom(property.getType())
|| byte.class.isAssignableFrom(property.getType())) {
ByteEditor byteEditor = new ByteEditor(property);
return byteEditor;
ByteEditor editor = new ByteEditor(property);
return editor;
}
if (Boolean.class.isAssignableFrom(property.getType())
|| boolean.class.isAssignableFrom(property.getType())) {
BooleanEditor editor = new BooleanEditor(property);
return editor;
}
LOG.error("Unrecognized parameter type: " + property.getType().getName());
return new JLabel("Unrecognized");
@@ -18,10 +18,12 @@ import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import org.diylc.common.PropertyWrapper;
import org.diylc.core.ValidationException;
import com.diyfever.gui.ButtonDialog;
@@ -65,6 +67,23 @@ public class PropertyEditorDialog extends ButtonDialog {
// setLocationRelativeTo(owner);
}
@Override
protected boolean validateInput(String button) {
if (button.equals(ButtonDialog.OK)) {
for (PropertyWrapper property : properties) {
try {
property.getValidator().validate(property.getValue());
} catch (ValidationException ve) {
JOptionPane.showMessageDialog(PropertyEditorDialog.this, "Input error for \""
+ property.getName() + "\": " + ve.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
return false;
}
}
}
return true;
}
private JPanel createEditorFields() {
JPanel editorPanel = new JPanel(new GridBagLayout());
editorPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
@@ -57,6 +57,8 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
private Clipboard clipboard;
private double zoomLevel = 1;
public CanvasPlugin(ISwingUI swingUI) {
this.swingUI = swingUI;
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
@@ -201,7 +203,8 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
public ActionFactory.DeleteSelectionAction getDeleteSelectionAction() {
if (deleteSelectionAction == null) {
deleteSelectionAction = ActionFactory.getInstance().createDeleteSelectionAction(plugInPort);
deleteSelectionAction = ActionFactory.getInstance().createDeleteSelectionAction(
plugInPort);
}
return deleteSelectionAction;
}
@@ -219,14 +222,14 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
}
return ungroupAction;
}
public ActionFactory.SendToBackAction getSendToBackAction() {
if (sendToBackAction == null) {
sendToBackAction = ActionFactory.getInstance().createSendToBackAction(plugInPort);
}
return sendToBackAction;
}
public ActionFactory.BringToFrontAction getBringToFrontAction() {
if (bringToFrontAction == null) {
bringToFrontAction = ActionFactory.getInstance().createBringToFrontAction(plugInPort);
@@ -257,11 +260,19 @@ public class CanvasPlugin implements IPlugIn, ClipboardOwner {
canvasPanel.scrollRectToVisible(visibleRect);
canvasPanel.revalidate();
}
// canvasPanel.validate();
// canvasPanel.repaint();
break;
case ZOOM_CHANGED:
Rectangle visibleRect = canvasPanel.getVisibleRect();
refreshSize();
// Try to set the visible area to be centered with the previous
// one.
double zoomFactor = (Double) params[0] / zoomLevel;
visibleRect.setBounds((int) (visibleRect.x * zoomFactor),
(int) (visibleRect.y * zoomFactor), visibleRect.width, visibleRect.height);
canvasPanel.scrollRectToVisible(visibleRect);
canvasPanel.revalidate();
zoomLevel = (Double) params[0];
break;
case REPAINT:
canvasPanel.repaint();
@@ -66,6 +66,7 @@ public class StatusBar extends JPanel implements IPlugIn {
private List<String> componentNamesUnderCursor;
private List<String> selectedComponentNames;
private List<String> stuckComponentNames;
private String statusMessage;
public StatusBar(ISwingUI swingUI) {
super();
@@ -196,7 +197,8 @@ public class StatusBar extends JPanel implements IPlugIn {
@Override
public EnumSet<EventType> getSubscribedEventTypes() {
return EnumSet.of(EventType.ZOOM_CHANGED, EventType.SLOT_CHANGED,
EventType.AVAILABLE_CTRL_POINTS_CHANGED, EventType.SELECTION_CHANGED);
EventType.AVAILABLE_CTRL_POINTS_CHANGED, EventType.SELECTION_CHANGED,
EventType.STATUS_MESSAGE_CHANGED);
}
@SuppressWarnings("unchecked")
@@ -247,11 +249,13 @@ public class StatusBar extends JPanel implements IPlugIn {
Collections.sort(componentNamesUnderCursor);
refreshStatusText();
break;
case STATUS_MESSAGE_CHANGED:
statusMessage = (String) params[0];
}
}
private void refreshStatusText() {
String statusText = "";
String statusText = this.statusMessage;
if (componentSlot == null) {
if (componentNamesUnderCursor != null && !componentNamesUnderCursor.isEmpty()) {
String formattedNames = Utils.toCommaString(componentNamesUnderCursor);
@@ -265,8 +269,6 @@ public class StatusBar extends JPanel implements IPlugIn {
builder.append(")");
}
statusText = "<html>Selection: " + builder.toString() + "</html>";
} else {
statusText = "";
}
} else {
switch (componentSlot.getCreationMethod()) {
@@ -277,12 +279,13 @@ public class StatusBar extends JPanel implements IPlugIn {
} else {
count = "second";
}
statusText = "Click on the canvas to set the " + count + " control point of a new "
+ componentSlot.getName() + " or press Esc to cancel";
statusText = "<html>Click on the canvas to set the " + count
+ " control point of a new <font color='blue'>" + componentSlot.getName()
+ "</font> or press <b>Esc</b> to cancel</html>";
break;
case SINGLE_CLICK:
statusText = "Click on the canvas to create a new " + componentSlot.getName()
+ " or press Esc to cancel";
statusText = "<html>Click on the canvas to create a new <font color='blue'>"
+ componentSlot.getName() + "</font> or press <b>Esc</b> to cancel</html>";
break;
}
}
@@ -11,9 +11,9 @@ import java.util.Map;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.diylc.common.ComponentType;
import org.diylc.common.IPlugInPort;
@@ -42,6 +42,13 @@ class ComponentTabbedPane extends JTabbedPane {
JPanel panel = createTab((componentTypes.get(category)));
addTab(category, panel);
}
addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
ComponentTabbedPane.this.plugInPort.setNewComponentTypeSlot(null);
}
});
}
private JPanel createTab(List<ComponentType> componentTypes) {
@@ -87,13 +94,13 @@ class ComponentTabbedPane extends JTabbedPane {
return panel;
}
private JScrollPane createComponentScrollBar(List<ComponentType> componentTypes) {
JScrollPane scrollPane = new JScrollPane(createComponentPanel(componentTypes));
scrollPane.setOpaque(false);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
return scrollPane;
}
// private JScrollPane createComponentScrollBar(List<ComponentType> componentTypes) {
// JScrollPane scrollPane = new JScrollPane(createComponentPanel(componentTypes));
// scrollPane.setOpaque(false);
// scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
// scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
// return scrollPane;
// }
private Component createComponentPanel(List<ComponentType> componentTypes) {
Container toolbar = new Container();
@@ -18,6 +18,9 @@ public class ToolBox implements IPlugIn {
private static final Logger LOG = Logger.getLogger(StatusBar.class);
private ISwingUI swingUI;
private IPlugInPort plugInPort;
private ComponentTabbedPane componentTabbedPane;
public ToolBox(ISwingUI swingUI) {
this.swingUI = swingUI;
@@ -25,12 +28,20 @@ public class ToolBox implements IPlugIn {
@Override
public void connect(IPlugInPort plugInPort) {
this.plugInPort = plugInPort;
try {
swingUI.injectGUIComponent(new ComponentTabbedPane(plugInPort), SwingConstants.TOP);
swingUI.injectGUIComponent(getComponentTabbedPane(), SwingConstants.TOP);
} catch (BadPositionException e) {
LOG.error("Could not install the toolbox", e);
}
}
public ComponentTabbedPane getComponentTabbedPane() {
if (componentTabbedPane == null) {
componentTabbedPane = new ComponentTabbedPane(plugInPort);
}
return componentTabbedPane;
}
@Override
public EnumSet<EventType> getSubscribedEventTypes() {
+65
View File
@@ -0,0 +1,65 @@
<org.diylc.core.Project>
<title>New Project</title>
<author>Branislav Stojkovic</author>
<width>
<value>29.0</value>
<unit class="org.diylc.core.measures.SizeUnit">cm</unit>
</width>
<height>
<value>21.0</value>
<unit class="org.diylc.core.measures.SizeUnit">cm</unit>
</height>
<gridSpacing>
<value>0.1</value>
<unit class="org.diylc.core.measures.SizeUnit">in</unit>
</gridSpacing>
<components>
<org.diylc.components.boards.EyeletBoard>
<name>Board1</name>
<alpha>127</alpha>
<value></value>
<controlPoints>
<java.awt.Point>
<x>555</x>
<y>450</y>
</java.awt.Point>
<java.awt.Point>
<x>1140</x>
<y>795</y>
</java.awt.Point>
</controlPoints>
<firstPoint>
<x>555</x>
<y>450</y>
</firstPoint>
<secondPoint>
<x>1140</x>
<y>795</y>
</secondPoint>
<boardColor>
<red>248</red>
<green>235</green>
<blue>179</blue>
<alpha>255</alpha>
</boardColor>
<borderColor>
<red>173</red>
<green>164</green>
<blue>125</blue>
<alpha>255</alpha>
</borderColor>
<spacing>
<value>0.3</value>
<unit class="org.diylc.core.measures.SizeUnit">in</unit>
</spacing>
<eyeletColor>
<red>195</red>
<green>228</green>
<blue>237</blue>
<alpha>255</alpha>
</eyeletColor>
</org.diylc.components.boards.EyeletBoard>
</components>
<groups/>
<lockedLayers/>
</org.diylc.core.Project>
+65
View File
@@ -0,0 +1,65 @@
<org.diylc.core.Project>
<title>New Project</title>
<author>Branislav Stojkovic</author>
<width>
<value>29.0</value>
<unit class="org.diylc.core.measures.SizeUnit">cm</unit>
</width>
<height>
<value>21.0</value>
<unit class="org.diylc.core.measures.SizeUnit">cm</unit>
</height>
<gridSpacing>
<value>0.1</value>
<unit class="org.diylc.core.measures.SizeUnit">in</unit>
</gridSpacing>
<components>
<org.diylc.components.boards.PerfBoard>
<name>Board1</name>
<alpha>127</alpha>
<value></value>
<controlPoints>
<java.awt.Point>
<x>585</x>
<y>450</y>
</java.awt.Point>
<java.awt.Point>
<x>1050</x>
<y>690</y>
</java.awt.Point>
</controlPoints>
<firstPoint>
<x>585</x>
<y>450</y>
</firstPoint>
<secondPoint>
<x>1050</x>
<y>690</y>
</secondPoint>
<boardColor>
<red>248</red>
<green>235</green>
<blue>179</blue>
<alpha>255</alpha>
</boardColor>
<borderColor>
<red>173</red>
<green>164</green>
<blue>125</blue>
<alpha>255</alpha>
</borderColor>
<spacing>
<value>0.1</value>
<unit class="org.diylc.core.measures.SizeUnit">in</unit>
</spacing>
<padColor>
<red>218</red>
<green>138</green>
<blue>103</blue>
<alpha>255</alpha>
</padColor>
</org.diylc.components.boards.PerfBoard>
</components>
<groups/>
<lockedLayers/>
</org.diylc.core.Project>
+73 -17
View File
@@ -11,23 +11,19 @@
<changes>
<com.diyfever.gui.update.Change>
<changeType>BUG_FIX</changeType>
<description>Copy/paste between two instances of the
application</description>
<description>Copy/paste between two instances of the application</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>BUG_FIX</changeType>
<description>Parsing numerical values in countries that use
comma as decimal separator</description>
<description>Parsing numerical values in countries that use comma as decimal separator</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>BUG_FIX</changeType>
<description>Dragging sticky points affects selectability
of objects</description>
<description>Dragging sticky points affects selectability of objects</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>BUG_FIX</changeType>
<description>Click is sometimes not registered while adding a
new component</description>
<description>Click is sometimes not registered while adding a new component</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>BUG_FIX</changeType>
@@ -35,8 +31,7 @@
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Allow shape control points of curves to overlap
</description>
<description>Allow shape control points of curves to overlap</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
@@ -44,8 +39,7 @@
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Added transparency to the potentiometer
</description>
<description>Added transparency to the potentiometer</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
@@ -53,14 +47,11 @@
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Import from v1 files can now read label and
electrolytic capacitor components and trace/pad colors
</description>
<description>Import from v1 files can now read label and electrolytic capacitor components and trace/pad colors</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Added worker thread for longer file operation, so
GUI doesn't freeze</description>
<description>Added worker thread for longer file operation, so GUI doesn't freeze</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>NEW_FEATURE</changeType>
@@ -82,5 +73,70 @@
<url>http://code.google.com/p/diy-layout-creator/downloads/list
</url>
</com.diyfever.gui.update.Version>
<com.diyfever.gui.update.Version>
<versionNumber>
<major>3</major>
<minor>0</minor>
<build>5</build>
</versionNumber>
<releaseDate>2011-01-30 20:00:00.000 CET</releaseDate>
<name></name>
<changes>
<com.diyfever.gui.update.Change>
<changeType>BUG_FIX</changeType>
<description>Curved trace does not show control points</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>BUG_FIX</changeType>
<description>Potentiometer draws wrong at 180 degrees</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Reset component selection when tab is changed</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Resistor can show color bands</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Electrolytic capacitor has a new icon and new looks</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Solder pad can be square</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Added keyboard shortcuts to some menu options</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>V1 file importer can recognize hookup wire and transistors</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added support for creating and loading templates</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added TO-92 transistor</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added TO-220 transistor</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added LED</description>
</com.diyfever.gui.update.Change>
<com.diyfever.gui.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Added axial electrolytic capacitor</description>
</com.diyfever.gui.update.Change>
</changes>
<url>http://code.google.com/p/diy-layout-creator/downloads/list
</url>
</com.diyfever.gui.update.Version>
</a>
</java.util.Arrays_-ArrayList>
Binary file not shown.
@@ -15,7 +15,7 @@ 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 = "", zOrder = IDIYComponent.TRACE)
@ComponentDescriptor(name = "Copper Trace", author = "Branislav Stojkovic", category = "Connectivity", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "Trace", description = "Straight copper trace", zOrder = IDIYComponent.TRACE)
public class CopperTrace extends AbstractLeadedComponent<Void> {
private static final long serialVersionUID = 1L;
@@ -88,14 +88,14 @@ public class CopperTrace extends AbstractLeadedComponent<Void> {
@Deprecated
@Override
public Size getWidth() {
return super.getWidth();
public Size getLength() {
return super.getLength();
}
@Deprecated
@Override
public Size getHeight() {
return super.getHeight();
public Size getWidth() {
return super.getWidth();
}
@Deprecated
@@ -109,28 +109,18 @@ public class CopperTrace extends AbstractLeadedComponent<Void> {
public void setValue(Void value) {
}
@Override
protected Color getDefaultBodyColor() {
return null;
}
@Override
protected Color getDefaultBorderColor() {
return null;
}
@Override
protected Shape getBodyShape() {
return null;
}
@Override
protected Size getDefaultHeight() {
return null;
}
@Override
protected Size getDefaultWidth() {
return null;
}
@Override
protected Size getDefaultLength() {
return null;
}
}
@@ -8,7 +8,6 @@ import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractCurvedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
@@ -38,11 +37,6 @@ public class CurvedTrace extends AbstractCurvedComponent<Void> {
g2d.draw(curve);
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@EditableProperty(name = "Width")
public Size getSize() {
return size;
@@ -53,14 +53,14 @@ public class Jumper extends AbstractLeadedComponent<Void> {
@Deprecated
@Override
public Size getWidth() {
return super.getWidth();
public Size getLength() {
return super.getLength();
}
@Deprecated
@Override
public Size getHeight() {
return super.getHeight();
public Size getWidth() {
return super.getWidth();
}
@Deprecated
@@ -74,28 +74,18 @@ public class Jumper extends AbstractLeadedComponent<Void> {
public void setValue(Void value) {
}
@Override
protected Color getDefaultBodyColor() {
return null;
}
@Override
protected Color getDefaultBorderColor() {
return null;
}
@Override
protected Shape getBodyShape() {
return null;
}
@Override
protected Size getDefaultHeight() {
return null;
}
@Override
protected Size getDefaultWidth() {
return null;
}
@Override
protected Size getDefaultLength() {
return null;
}
}
@@ -28,6 +28,7 @@ public class SolderPad extends AbstractComponent<Void> {
private Size size = SIZE;
private Color color = COLOR;
private Point point = new Point(0, 0);
private Type type = Type.ROUND;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, Project project,
@@ -36,7 +37,11 @@ public class SolderPad extends AbstractComponent<Void> {
int holeDiameter = getClosestOdd(HOLE_SIZE.convertToPixels());
g2d.setColor(componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : color);
g2d.fillOval(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter);
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);
}
g2d.setColor(Constants.CANVAS_COLOR);
g2d.fillOval(point.x - holeDiameter / 2, point.y - holeDiameter / 2, holeDiameter,
holeDiameter);
@@ -102,6 +107,15 @@ public class SolderPad extends AbstractComponent<Void> {
this.color = color;
}
@EditableProperty
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
@Deprecated
@Override
public Void getValue() {
@@ -111,4 +125,13 @@ public class SolderPad extends AbstractComponent<Void> {
@Override
public void setValue(Void value) {
}
static enum Type {
ROUND, SQUARE;
@Override
public String toString() {
return name().substring(0, 1) + name().substring(1).toLowerCase();
}
}
}
@@ -16,7 +16,7 @@ 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 = "test", instanceNamePrefix = "Cut", stretchable = false, zOrder = IDIYComponent.BOARD + 1)
@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)
public class TraceCut extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L;
@@ -20,7 +20,7 @@ import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Mini Toggle Switch", category = "Electromechanical", author = "Branislav Stojkovic", description = "", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "SW")
@ComponentDescriptor(name = "Mini Toggle Switch", category = "Electromechanical", author = "Branislav Stojkovic", description = "Panel mounted mini toggle switch", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "SW")
public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchType> {
private static final long serialVersionUID = 1L;
@@ -0,0 +1,123 @@
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.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.Capacitance;
import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@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 = new Capacitance(1d, CapacitanceUnit.uF);
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
public Capacitance getValue() {
return value;
}
public void setValue(Capacitance 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);
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) {
if (polarized) {
int markerLength = (int) (getLength().convertToPixels() * 0.2);
g2d.setColor(markerColor);
int width = getClosestOdd(getWidth().convertToPixels());
g2d.fillRect(getLength().convertToPixels() - markerLength, 0, markerLength, width);
g2d.setColor(tickColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.drawLine(getLength().convertToPixels() - markerLength / 2,
(int) (width / 2 - width * 0.15), getLength().convertToPixels() - markerLength
/ 2, (int) (width / 2 + width * 0.15));
}
}
}
@@ -29,6 +29,8 @@ public class AxialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
public AxialFilmCapacitor() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty
@@ -51,28 +53,18 @@ public class AxialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
}
@Override
protected Size getDefaultHeight() {
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultWidth() {
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@Override
protected Color getDefaultBodyColor() {
return BODY_COLOR;
}
@Override
protected Color getDefaultBorderColor() {
return BORDER_COLOR;
}
@Override
protected Shape getBodyShape() {
return new Rectangle2D.Double(0f, 0f, getWidth().convertToPixels(),
getClosestOdd(getHeight().convertToPixels()));
return new Rectangle2D.Double(0f, 0f, getLength().convertToPixels(),
getClosestOdd(getWidth().convertToPixels()));
}
}
@@ -3,8 +3,11 @@ 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 org.diylc.common.ObjectCache;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
@@ -15,20 +18,27 @@ import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Electrolytic Capacitor", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C", description = "test", zOrder = IDIYComponent.COMPONENT)
@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 ElectrolyticRadial extends AbstractLeadedComponent<Capacitance> {
private static final long serialVersionUID = 1L;
public static Size DEFAULT_SIZE = new Size(1d / 2, SizeUnit.in);
public static Color BODY_COLOR = Color.decode("#27408B");
public static Color BODY_COLOR = Color.decode("#EAADEA");
public static Color BORDER_COLOR = BODY_COLOR.darker();
public static Color COVER_COLOR = Color.decode("#C3E4ED");
public static Color MARKER_COLOR = Color.gray;
public static Color TICK_COLOR = Color.white;
private Capacitance value = new Capacitance(1d, CapacitanceUnit.uF);
private Color markerColor = MARKER_COLOR;
private Color tickColor = TICK_COLOR;
private boolean polarized = true;
public ElectrolyticRadial() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty
@@ -42,61 +52,110 @@ public class ElectrolyticRadial extends AbstractLeadedComponent<Capacitance> {
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(BODY_COLOR);
g2d.fillOval(6, 6, width - 12, width - 12);
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.drawOval(6, 6, width - 12, width - 12);
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) {
int totalDiameter = getClosestOdd(getWidth().convertToPixels());
int coverDiameter = getClosestOdd(totalDiameter * 3 / 4);
g2d.setColor(COVER_COLOR);
int position = (totalDiameter - coverDiameter) / 2;
g2d.fillOval(position, position, coverDiameter, coverDiameter);
g2d.setColor(COVER_COLOR.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 getDefaultHeight() {
return null;
}
@Deprecated
@Override
public Size getHeight() {
return super.getHeight();
if (polarized) {
int totalDiameter = getClosestOdd(getLength().convertToPixels());
Area area = new Area(getBodyShape());
area
.subtract(new Area(new Rectangle2D.Double(0, 0, totalDiameter * 0.8,
totalDiameter)));
g2d.setColor(markerColor);
g2d.fill(area);
g2d.setColor(tickColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.drawLine((int) (totalDiameter * 0.9), totalDiameter / 2
- (int) (totalDiameter * 0.05), (int) (totalDiameter * 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() {
// We'll reuse width property to set the diameter.
return DEFAULT_SIZE;
return null;
}
@EditableProperty(name = "Diameter")
@Deprecated
@Override
public Size getWidth() {
return super.getWidth();
}
@Override
protected Color getDefaultBodyColor() {
return BODY_COLOR;
protected Size getDefaultLength() {
// We'll reuse width property to set the diameter.
return DEFAULT_SIZE;
}
@EditableProperty(name = "Diameter")
@Override
protected Color getDefaultBorderColor() {
return BORDER_COLOR;
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;
}
@Override
protected Shape getBodyShape() {
return new Ellipse2D.Double(0f, 0f, getClosestOdd(getWidth().convertToPixels()),
getClosestOdd(getWidth().convertToPixels()));
return new Ellipse2D.Double(0f, 0f, getClosestOdd(getLength().convertToPixels()),
getClosestOdd(getLength().convertToPixels()));
}
}
@@ -108,7 +108,7 @@ public class PotentiometerPanel extends AbstractPotentiometer {
break;
case _180:
body[3] = new Area(new Ellipse2D.Double(
controlPoints[0].x + spacing - diameter / 2, controlPoints[0].y + spacing
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(
@@ -212,7 +212,7 @@ public class PotentiometerPanel extends AbstractPotentiometer {
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int margin = 4 * width / 32;
int spacing = width / 3;
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);
@@ -29,6 +29,8 @@ public class RadialCeramicDiskCapacitor extends AbstractLeadedComponent<Capacita
public RadialCeramicDiskCapacitor() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty
@@ -51,28 +53,18 @@ public class RadialCeramicDiskCapacitor extends AbstractLeadedComponent<Capacita
}
@Override
protected Size getDefaultHeight() {
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultWidth() {
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@Override
protected Color getDefaultBodyColor() {
return BODY_COLOR;
}
@Override
protected Color getDefaultBorderColor() {
return BORDER_COLOR;
}
@Override
protected Shape getBodyShape() {
return new Ellipse2D.Double(0f, 0f, getWidth().convertToPixels(), getClosestOdd(getHeight()
return new Ellipse2D.Double(0f, 0f, getLength().convertToPixels(), getClosestOdd(getWidth()
.convertToPixels()));
}
}
@@ -29,6 +29,8 @@ public class RadialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
public RadialFilmCapacitor() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty
@@ -51,29 +53,19 @@ public class RadialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
}
@Override
protected Size getDefaultHeight() {
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultWidth() {
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@Override
protected Color getDefaultBodyColor() {
return BODY_COLOR;
}
@Override
protected Color getDefaultBorderColor() {
return BORDER_COLOR;
}
@Override
protected Shape getBodyShape() {
double radius = getHeight().convertToPixels() * 0.7;
return new RoundRectangle2D.Double(0f, 0f, getWidth().convertToPixels(),
getClosestOdd(getHeight().convertToPixels()), radius, radius);
double radius = getWidth().convertToPixels() * 0.7;
return new RoundRectangle2D.Double(0f, 0f, getLength().convertToPixels(),
getClosestOdd(getWidth().convertToPixels()), radius, radius);
}
}
@@ -5,11 +5,14 @@ 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.ResistanceUnit;
import org.diylc.core.measures.Size;
@@ -26,12 +29,15 @@ public class Resistor extends AbstractLeadedComponent<Resistance> {
public static Color BORDER_COLOR = BODY_COLOR.darker();
private Resistance value = new Resistance(123d, ResistanceUnit.K);
private ResistorColorCode colorCode = ResistorColorCode._5_BAND;
public Resistor() {
super();
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@EditableProperty
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
public Resistance getValue() {
return value;
}
@@ -46,33 +52,55 @@ public class Resistor extends AbstractLeadedComponent<Resistance> {
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 getDefaultHeight() {
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultWidth() {
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@Override
protected Color getDefaultBodyColor() {
return BODY_COLOR;
@EditableProperty(name = "Color code")
public ResistorColorCode getColorCode() {
return colorCode;
}
@Override
protected Color getDefaultBorderColor() {
return BORDER_COLOR;
public void setColorCode(ResistorColorCode colorCode) {
this.colorCode = colorCode;
}
@Override
protected Shape getBodyShape() {
return new Rectangle2D.Double(0f, 0f, getWidth().convertToPixels(),
getClosestOdd(getHeight().convertToPixels()));
return new Rectangle2D.Double(0f, 0f, getLength().convertToPixels(),
getClosestOdd(getWidth().convertToPixels()));
}
@Override
protected void decorateComponentBody(Graphics2D g2d) {
// int width = getWidth().convertToPixels();
if (colorCode == ResistorColorCode.NONE) {
return;
}
int height = getClosestOdd(getWidth().convertToPixels());
Color[] bands = value.getColorCode(colorCode);
int x = 4;
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 += 5;
}
}
}
@@ -25,7 +25,7 @@ import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "DIL IC", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "IC", description = "test", stretchable = false, zOrder = IDIYComponent.COMPONENT)
@ComponentDescriptor(name = "DIL IC", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "IC", description = "IC with rectangular housing and two parallel rows of pins", stretchable = false, zOrder = IDIYComponent.COMPONENT)
public class DIL_IC extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
@@ -13,7 +13,7 @@ import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Diode (plastic)", author = "Branislav Stojkovic", category = "Semiconductors", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "D", description = "test", zOrder = IDIYComponent.COMPONENT)
@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;
@@ -27,10 +27,13 @@ public class DiodePlastic extends AbstractLeadedComponent<String> {
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;
}
@EditableProperty
@@ -56,37 +59,36 @@ public class DiodePlastic extends AbstractLeadedComponent<String> {
}
@Override
protected Size getDefaultHeight() {
protected Size getDefaultWidth() {
return DEFAULT_HEIGHT;
}
@Override
protected Size getDefaultWidth() {
protected Size getDefaultLength() {
return DEFAULT_WIDTH;
}
@Override
protected Color getDefaultBodyColor() {
return BODY_COLOR;
}
@Override
protected Color getDefaultBorderColor() {
return BORDER_COLOR;
}
@Override
protected Shape getBodyShape() {
return new Rectangle2D.Double(0f, 0f, getWidth().convertToPixels(),
getClosestOdd(getHeight().convertToPixels()));
return new Rectangle2D.Double(0f, 0f, getLength().convertToPixels(),
getClosestOdd(getWidth().convertToPixels()));
}
@Override
protected void decorateComponentBody(Graphics2D g2d) {
g2d.setColor(MARKER_COLOR);
int width = getWidth().convertToPixels();
g2d.setColor(markerColor);
int width = getLength().convertToPixels();
int markerWidth = MARKER_WIDTH.convertToPixels();
g2d.fillRect(width - markerWidth, 0, markerWidth, getClosestOdd(getHeight().convertToPixels()));
super.decorateComponentBody(g2d);
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,104 @@
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);
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) {
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,265 @@
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.Rectangle2D;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "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_HEIGHT = new Size(4.5d, SizeUnit.mm);
public static Size TAB_THICKNESS = new Size(0.05d, 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) };
private Shape[] body;
private Color bodyColor = BODY_COLOR;
private Color borderColor = BORDER_COLOR;
private Color tabColor = TAB_COLOR;
private Color tabBorderColor = TAB_BORDER_COLOR;
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 = 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 = PIN_SPACING.convertToPixels();
int bodyWidth = getClosestOdd(BODY_WIDTH.convertToPixels());
int bodyHeight = getClosestOdd(BODY_HEIGHT.convertToPixels());
int tabThickness = TAB_THICKNESS.convertToPixels();
switch (orientation) {
case DEFAULT:
body[0] = new Rectangle2D.Double(x - bodyHeight / 2,
y + pinSpacing - bodyWidth / 2, bodyHeight, bodyWidth);
body[1] = new Rectangle2D.Double(x + bodyHeight / 2 - tabThickness, y + pinSpacing
- bodyWidth / 2, tabThickness, bodyWidth);
break;
case _90:
body[0] = new Rectangle2D.Double(x - pinSpacing - bodyWidth / 2,
y - bodyHeight / 2, bodyWidth, bodyHeight);
body[1] = new Rectangle2D.Double(x - pinSpacing - bodyWidth / 2, y + bodyHeight / 2
- tabThickness, bodyWidth, tabThickness);
break;
case _180:
body[0] = new Rectangle2D.Double(x - bodyHeight / 2,
y - pinSpacing - bodyWidth / 2, bodyHeight, bodyWidth);
body[1] = new Rectangle2D.Double(x - bodyHeight / 2,
y - pinSpacing - bodyWidth / 2, tabThickness, bodyWidth);
break;
case _270:
body[0] = new Rectangle2D.Double(x + pinSpacing - bodyWidth / 2,
y - bodyHeight / 2, bodyWidth, bodyHeight);
body[1] = new Rectangle2D.Double(x + pinSpacing - bodyWidth / 2,
y - bodyHeight / 2, bodyWidth, tabThickness);
break;
default:
throw new RuntimeException("Unexpected orientation: " + orientation);
}
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, Project project,
IDrawingObserver drawingObserver) {
int pinSize = 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(bodyColor);
g2d.fill(mainArea);
g2d.setColor(tabColor);
g2d.fill(tabArea);
g2d.setComposite(oldComposite);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.setColor(tabBorderColor);
g2d.draw(tabArea);
g2d.setColor(componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : borderColor);
g2d.draw(mainArea);
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);
g2d.setColor(LABEL_COLOR);
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
Rectangle2D rect = fontMetrics.getStringBounds(getName(), g2d);
int textHeight = (int) (rect.getHeight());
int textWidth = (int) (rect.getWidth());
// Center text horizontally and vertically
Rectangle bounds = mainArea.getBounds();
int x = bounds.x + (bounds.width - textWidth) / 2;
int y = bounds.y + (bounds.height - textHeight) / 2 + fontMetrics.getAscent();
g2d.drawString(getName(), x, y);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(BODY_COLOR);
int margin = 2 * width / 32;
int thickness = 7 * width / 32;
g2d.fillRect(margin, (height - thickness) / 2, width - margin * 2, thickness);
g2d.setColor(TAB_COLOR);
g2d.fillRect(margin, (height + thickness) / 2 - margin - 1, width - margin * 2, margin);
g2d.setColor(BORDER_COLOR);
g2d.drawRect(margin, (height - thickness) / 2, width - margin * 2, thickness);
}
@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(name = "Tab border")
public Color getTabBorderColor() {
return tabBorderColor;
}
public void setTabBorderColor(Color tabBorderColor) {
this.tabBorderColor = tabBorderColor;
}
}
@@ -0,0 +1,236 @@
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.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "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.1d, 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) };
private Area body;
private Color bodyColor = BODY_COLOR;
private Color borderColor = BORDER_COLOR;
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;
}
@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 = 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 Area getBody() {
if (body == null) {
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int pinSpacing = PIN_SPACING.convertToPixels();
int bodyDiameter = getClosestOdd(BODY_DIAMETER.convertToPixels());
switch (orientation) {
case DEFAULT:
body = new Area(new Ellipse2D.Double(x - bodyDiameter / 2, y + pinSpacing
- bodyDiameter / 2, bodyDiameter, bodyDiameter));
body.subtract(new Area(new Rectangle2D.Double(x - bodyDiameter, y + pinSpacing
- bodyDiameter / 2, 3 * bodyDiameter / 4, bodyDiameter)));
break;
case _90:
body = new Area(new Ellipse2D.Double(x - pinSpacing - bodyDiameter / 2, y
- bodyDiameter / 2, bodyDiameter, bodyDiameter));
body.subtract(new Area(new Rectangle2D.Double(x - pinSpacing - bodyDiameter / 2, y
- bodyDiameter, bodyDiameter, 3 * bodyDiameter / 4)));
break;
case _180:
body = new Area(new Ellipse2D.Double(x - bodyDiameter / 2, y - pinSpacing
- bodyDiameter / 2, bodyDiameter, bodyDiameter));
body.subtract(new Area(new Rectangle2D.Double(x + bodyDiameter / 4, y - pinSpacing
- bodyDiameter / 2, 3 * bodyDiameter / 4, bodyDiameter)));
break;
case _270:
body = new Area(new Ellipse2D.Double(x + pinSpacing - bodyDiameter / 2, y
- bodyDiameter / 2, bodyDiameter, bodyDiameter));
body.subtract(new Area(new Rectangle2D.Double(x + pinSpacing - 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, Project project,
IDrawingObserver drawingObserver) {
int pinSize = 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(bodyColor);
g2d.fill(mainArea);
g2d.setComposite(oldComposite);
g2d.setColor(componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : borderColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.draw(mainArea);
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);
g2d.setColor(LABEL_COLOR);
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
Rectangle2D rect = fontMetrics.getStringBounds(getName(), g2d);
int textHeight = (int) (rect.getHeight());
int textWidth = (int) (rect.getWidth());
// Center text horizontally and vertically
Rectangle bounds = mainArea.getBounds();
int x = bounds.x + (bounds.width - textWidth) / 2;
int y = bounds.y + (bounds.height - textHeight) / 2 + fontMetrics.getAscent();
g2d.drawString(getName(), x, y);
}
@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);
}
@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;
}
}