Compare commits

..

123 Commits

Author SHA1 Message Date
bancika 934b510fbc 2012-08-21 20:04:28 +00:00
bancika 385612bc74 2012-08-21 20:03:42 +00:00
bancika ae3694c70d 2012-08-21 20:02:54 +00:00
bancika 56fef06b22 removed unused libs 2012-08-21 15:30:40 +00:00
bancika 4897b803b6 2012-08-21 14:43:10 +00:00
bancika 6c698e935e Replaced deep cloning library with manual implementation 2012-08-21 14:16:19 +00:00
bancika 1645eae18d Replaced deep cloning library with manual implementation 2012-08-21 14:16:07 +00:00
bancika 5adbc2c6ca Some components can be placed in any layer using Send to Back/Bring to Front 2012-08-21 11:06:19 +00:00
bancika e3b1f0d4e6 Some components can be placed in any layer using Send to Back/Bring to Front 2012-08-21 11:06:08 +00:00
bancika bc88253c70 Some components can be placed in any layer using Send to Back/Bring to Front 2012-08-21 11:05:59 +00:00
bancika 1d45bf345c 2012-08-21 08:58:36 +00:00
bancika c61ec71ee1 2012-08-21 08:58:19 +00:00
bancika 35272c1339 check if the app is run from Jar directly 2012-08-21 08:53:41 +00:00
bancika 93e057dfb2 [Improvement] Improved overall performance
[Bug Fix] Should be more stable under OSX and not crash unexpectedly
2012-08-21 08:32:18 +00:00
bancika aef5c88a3f [Improvement] Improved overall performance
[Bug Fix] Should be more stable under OSX and not crash unexpectedly
2012-08-21 08:32:11 +00:00
bancika 591bdd313c [Improvement] Improved overall performance
[Bug Fix] Should be more stable under OSX and not crash unexpectedly
2012-08-21 08:32:04 +00:00
bancika 3f9caf9918 [Improvement] Improved overall performance
[Bug Fix] Should be more stable under OSX and not crash unexpectedly
2012-08-21 08:29:27 +00:00
bancika 246decdf7c [Improvement] Improved overall performance
[Bug Fix] Should be more stable under OSX and not crash unexpectedly
2012-08-21 08:29:17 +00:00
bancika 0bc8141dc7 [Improvement] Improved overall performance
[Bug Fix] Should be more stable under OSX and not crash unexpectedly
2012-08-21 08:28:55 +00:00
bancika 6e8e8b9d49 release build 2012-08-20 09:49:51 +00:00
bancika c8ff6afe6e release build 2012-08-20 09:33:54 +00:00
bancika 714740da28 release build 2012-08-20 09:33:44 +00:00
bancika 45b759fa75 2012-08-17 15:56:41 +00:00
bancika 2445f05767 2012-08-17 15:39:49 +00:00
bancika 22578a4e3f 2012-08-17 14:57:22 +00:00
bancika 10a42b7fcf Better unsaved warning message 2012-08-17 14:51:14 +00:00
bancika 0498eb2c51 Better unsaved warning message 2012-08-17 14:51:05 +00:00
bancika d384711759 UNICODE font export to PDF files 2012-08-17 14:26:22 +00:00
bancika 5e0c422c30 UNICODE font export to PDF files 2012-08-17 14:26:06 +00:00
bancika 73cc182dad UNICODE font export to PDF files 2012-08-17 14:25:55 +00:00
bancika 7932657fb2 Transistors can show name or value 2012-08-17 13:28:07 +00:00
bancika 50bacee70a Transistors can show name or value 2012-08-17 13:27:59 +00:00
bancika 1c0219f4bf 2012-08-17 13:07:55 +00:00
bancika 4522d9aeb5 Faster component placement, auto-focus on "Value" box 2012-08-17 12:56:35 +00:00
bancika a25d43b710 Default resistor value to 100k 2012-08-17 12:55:36 +00:00
bancika 18261eab69 Control number of "Recently Used" items from config.properties 2012-08-17 12:35:15 +00:00
bancika 3b984d0850 Control number of "Recently Used" items from config.properties 2012-08-17 12:35:11 +00:00
bancika d72d898f3f Control number of "Recently Used" items from config.properties 2012-08-17 12:31:03 +00:00
bancika 03bc58eb96 Control number of "Recently Used" items from config.properties 2012-08-17 12:30:55 +00:00
bancika 17427a0071 2012-08-17 12:17:19 +00:00
bancika 39704e3625 Improved "Recently Used" toolbox, doesn't jump as you click 2012-08-17 11:38:01 +00:00
bancika 6ef7459d46 Move selected components with arrow keys (and ctrl/shift) 2012-08-17 10:41:31 +00:00
bancika a6448676f7 Move selected components with arrow keys (and ctrl/shift) 2012-08-17 10:41:19 +00:00
bancika 4cf6f9f4a5 Remove junk from BOM (eyelets, wires, traces) 2012-08-16 15:56:58 +00:00
bancika 162b67bf25 Remove junk from BOM (eyelets, wires, traces) 2012-08-16 15:51:21 +00:00
bancika ccc90dd3a6 Remove junk from BOM (eyelets, wires, traces) 2012-08-16 15:50:59 +00:00
bancika 237639b9a1 Remove junk from BOM (eyelets, wires, traces) 2012-08-16 15:50:46 +00:00
bancika 37b89fe3a2 2012-08-16 14:40:10 +00:00
bancika 860bb0071b improved toolbar click reliability 2012-08-16 14:32:37 +00:00
bancika 56fd800e77 added .diy associations 2012-08-16 11:03:46 +00:00
bancika 1a95e43f9f added .diy associations 2012-08-16 11:02:26 +00:00
bancika 9817aa549e added .diy associations 2012-08-16 10:58:53 +00:00
bancika c38bd87a7d Right click rotates component while laying out on the canvas 2012-08-16 10:24:00 +00:00
bancika 21e46b3835 Right click rotates component while laying out on the canvas 2012-08-16 10:23:51 +00:00
bancika 6a4508b4a9 2012-08-16 09:28:01 +00:00
bancika 33d3e03ffb minor changes 2012-08-16 09:27:05 +00:00
bancika 98c3804529 minor changes 2012-08-16 09:26:55 +00:00
bancika 4f88bb988a copy-paste performance improvement 2012-08-15 21:18:31 +00:00
bancika 5a4eeb2de2 graphics fix 2012-08-15 21:18:14 +00:00
bancika abf99285cf switch terminal size improvement 2012-03-31 17:12:13 +00:00
bancika e83a2bd5f8 removed beta 2012-03-30 01:58:24 +00:00
bancika 445a56f563 improved bring to front/back 2012-03-29 02:36:34 +00:00
bancika aa434048f3 9v battery snap 2012-03-28 02:04:08 +00:00
bancika 1b043abfe5 description update 2012-03-28 01:50:01 +00:00
bancika b08395ee27 lever guitar switch 2012-03-27 02:36:31 +00:00
bancika a23342f682 2012-03-22 01:05:20 +00:00
bancika 93a4978e68 single coil pickup 2012-03-21 02:42:12 +00:00
bancika 0d845677c4 added humbucker pickup 2012-03-19 00:33:47 +00:00
bancika ab10103e41 added humbucker pickup 2012-03-19 00:15:56 +00:00
bancika 0d17046170 add OS version to log 2012-03-18 13:39:10 +00:00
bancika 880e618e30 Fonts are exported to PDF 2012-03-18 02:16:20 +00:00
bancika 176abc2428 Plastic DC jack 2012-03-17 23:47:15 +00:00
bancika 061bc520c6 Plastic DC jack 2012-03-17 02:21:26 +00:00
bancika 9c9d6ecd70 Plastic DC jack 2012-03-17 02:15:24 +00:00
bancika d9f5e2e42b Plastic DC jack 2012-03-17 02:02:53 +00:00
bancika 0c1659cde0 added closed jack 2012-03-17 00:29:28 +00:00
bancika 53feb60b63 added closed jack 2012-03-17 00:17:22 +00:00
bancika 8c2700b92c added closed jack 2012-03-17 00:17:06 +00:00
bancika 298d575696 added cliff style jack 2012-03-15 01:58:41 +00:00
bancika 931138083f added cliff style jack 2012-03-15 01:19:28 +00:00
bancika f2a814e41c added cliff style jack 2012-03-15 00:56:20 +00:00
bancika d07965a3c0 added ground symbol 2012-03-11 17:15:27 +00:00
bancika 9e1f5c3ac8 added ground symbol 2012-03-11 17:11:51 +00:00
bancika 569a50e97a utf-8 2012-03-10 13:28:07 +00:00
bancika 80e7e3a487 2012-03-10 13:27:42 +00:00
bancika 5d73617af3 2012-03-10 04:09:25 +00:00
bancika 8169e3a6ba BJT symbol 2012-03-10 04:03:44 +00:00
bancika a7b48f4f52 BJT symbol 2012-03-10 03:47:30 +00:00
bancika 89bf22bcf8 UTF-8 2012-03-10 02:58:49 +00:00
bancika ae99ce2702 use UTF-8 2012-03-10 01:14:01 +00:00
bancika 61937d6d42 Add IC symbol 2012-03-05 03:11:45 +00:00
bancika e618a1e1ad Add IC symbol 2012-03-04 23:22:47 +00:00
bancika 513a229e64 Added MOSFET Symbol 2012-03-04 23:16:44 +00:00
bancika f834aa6d0b Added JFET Symbol 2012-03-04 23:03:41 +00:00
bancika 35d8b13d41 Added MOSFET Symbol 2012-03-04 22:42:33 +00:00
bancika 989e0a03e4 Added MOSFET Symbol 2012-03-04 22:41:37 +00:00
bancika c6cb77f4ef Added MOSFET Symbol 2012-03-04 22:37:05 +00:00
bancika af1a11e848 Added MOSFET Symbol 2012-03-04 22:32:42 +00:00
bancika 4bcff4a574 2012-03-04 18:43:36 +00:00
bancika 36f65423e0 Add IC symbol 2012-03-04 18:35:00 +00:00
bancika ef11c931a7 2012-03-04 16:28:54 +00:00
bancika 732a9954b7 Add IC symbol 2012-03-04 15:09:53 +00:00
bancika 2b5b904d8d IC component can display name or value 2012-03-04 15:09:43 +00:00
bancika 6ca16d07e6 Application breaks when resistance is set to 0 ohms 2012-03-04 15:09:12 +00:00
bancika 4f113f032d fixed out of bounds exc 2012-03-04 14:27:10 +00:00
bancika e572412f1e fixed to use new file paths 2012-02-26 13:40:03 +00:00
bancika dd9e9f054c Expand selection feature, useful for debugging
Limit length of text in the status bar using "and X more" suffix
2012-02-26 03:54:12 +00:00
bancika 4ee7381959 2012-02-20 03:22:01 +00:00
bancika d11a8b906a Do not hard-code voltage and power ratings 2012-02-12 18:45:34 +00:00
bancika 9fdd96c889 R instead of omega for resistance 2012-02-12 18:13:32 +00:00
bancika d776a3df32 2012-02-12 15:26:30 +00:00
bancika ebf06841a0 Select components from context menu even when they are under other components 2012-02-12 14:36:18 +00:00
bancika 616b09b4b2 2012-02-12 05:21:57 +00:00
bancika dccd91e56b Imperial ruler is divided to .1" instead of 1/4" 2012-02-12 05:17:08 +00:00
bancika 59c543da34 2012-02-12 03:54:24 +00:00
bancika 7c933fa0f3 v1 import improvements 2012-02-12 03:53:50 +00:00
bancika 8294caa8ba Smarter resistor labels; try not to overlap label with bands 2012-02-11 14:07:05 +00:00
bancika a7637767cd 2012-02-10 04:24:53 +00:00
bancika 2dccd41f41 do not put space between value and multiplier K, M, etc 2012-02-10 04:23:10 +00:00
bancika 2dfec28dc9 perfboards can show coordinates 2012-02-10 03:17:42 +00:00
bancika fe527eece2 2012-02-08 05:02:10 +00:00
bancika d459ea898c ctrl+shift toggles snap to grid 2012-02-08 04:48:31 +00:00
bancika 19cfca3df8 2012-02-08 04:48:08 +00:00
135 changed files with 6204 additions and 1178 deletions
+2 -6
View File
@@ -6,12 +6,8 @@
<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="lib/xstream-1.3.1.jar"/>
<classpathentry kind="lib" path="lib/junit-4.7.jar"/>
<classpathentry kind="lib" path="lib/iText-2.1.7.jar"/>
<classpathentry kind="lib" path="lib/cloning-1.5.jar"/>
<classpathentry kind="lib" path="lib/objenesis-1.1.jar"/>
<classpathentry kind="lib" path="lib/jettison-1.0.1.jar"/>
<classpathentry kind="lib" path="lib/poi-3.5-FINAL-20090928.jar"/>
<classpathentry kind="lib" path="library/main.jar"/>
<classpathentry kind="lib" path="lib/app-framework.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/app-framework"/>
<classpathentry kind="lib" path="lib/jettison-1.0.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
+6
View File
@@ -62,6 +62,12 @@
<attribute name="Class-Path" value="${manifest.class.path}" />
</manifest>
</jar>
<copy todir="../diylc-swing/lib" overwrite="true">
<fileset dir="${jar.dir}" includes="${ant.project.name}.jar" />
</copy>
<copy todir="../diylc-library/lib" overwrite="true">
<fileset dir="${jar.dir}" includes="${ant.project.name}.jar" />
</copy>
</target>
<target name="javadoc">
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,6 +4,7 @@ import javax.swing.Icon;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.BomPolicy;
/**
* Entity class used to describe a component type.
@@ -23,11 +24,14 @@ public class ComponentType {
private Icon icon;
private Class<? extends IDIYComponent<?>> instanceClass;
private double zOrder;
private boolean flexibleZOrder;
private boolean stretchable;
private BomPolicy bomPolicy;
public ComponentType(String name, String description, CreationMethod creationMethod,
String category, String namePrefix, String author, Icon icon,
Class<? extends IDIYComponent<?>> instanceClass, double zOrder, boolean stretchable) {
Class<? extends IDIYComponent<?>> instanceClass, double zOrder, boolean flexibleZOrder,
boolean stretchable, BomPolicy bomPolicy) {
super();
this.name = name;
this.description = description;
@@ -38,7 +42,9 @@ public class ComponentType {
this.icon = icon;
this.instanceClass = instanceClass;
this.zOrder = zOrder;
this.flexibleZOrder = flexibleZOrder;
this.stretchable = stretchable;
this.bomPolicy = bomPolicy;
}
public String getName() {
@@ -76,10 +82,18 @@ public class ComponentType {
public double getZOrder() {
return zOrder;
}
public boolean isFlexibleZOrder() {
return flexibleZOrder;
}
public boolean isStretchable() {
return stretchable;
}
public BomPolicy getBomPolicy() {
return bomPolicy;
}
@Override
public String toString() {
@@ -0,0 +1,5 @@
package org.diylc.common;
public enum HorizontalAlignment {
LEFT, CENTER, RIGHT
}
@@ -0,0 +1,22 @@
package org.diylc.common;
public interface IKeyProcessor {
public static final int VK_LEFT = 0x25;
public static final int VK_UP = 0x26;
public static final int VK_RIGHT = 0x27;
public static final int VK_DOWN = 0x28;
/**
* Notifies the presenter that a key hes been pressed on the canvas.
*
* @param key
* @param ctrlDown
* @param shiftDown
* @param altDown
*
* @return true if the event should be consumed
*/
boolean keyPressed(int key, boolean ctrlDown, boolean shiftDown,
boolean altDown);
}
@@ -0,0 +1,69 @@
package org.diylc.common;
import java.awt.Point;
public interface IMouseProcessor {
/**
* Notifies the presenter that mouse is clicked.
*
* Note: point coordinates are display based, i.e. scaled for zoom factor.
*
* @param point
* @param button
* @param ctrlDown
* @param shiftDown
* @param altDown
* @param clickCount
*/
void mouseClicked(Point point, int button, boolean ctrlDown, boolean shiftDown, boolean altDown,
int clickCount);
/**
* Notifies the presenter that mouse is moved.
*
* Note: point coordinates are display based, i.e. scaled for zoom factor.
*
* @param point
* @param ctrlDown
* @param shiftDown
* @param altDown
*/
void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown);
/**
* Notification that drag has been started from the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
* @param dragAction
*/
void dragStarted(Point point, int dragAction);
/**
* Checks if it's possible to drop over the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
* @return
*/
boolean dragOver(Point point);
/**
* Changes the current drag action during the dragging.
*
* @param dragAction
*/
void dragActionChanged(int dragAction);
/**
* Notification that drag has been ended in the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
*/
void dragEnded(Point point);
}
@@ -28,7 +28,7 @@ import org.diylc.core.Theme;
* @see IMessageListener
* @see EventType
*/
public interface IPlugInPort {
public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyProcessor {
public static final String ANTI_ALIASING_KEY = "antiAliasing";
public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender";
@@ -45,6 +45,17 @@ public interface IPlugInPort {
public static final String THEME_KEY = "theme";
public static final String RECENT_COMPONENTS_KEY = "recentComponents";
public static final int DND_TOGGLE_STICKY = 0x1;
public static final int DND_TOGGLE_SNAP = 0x40000000;
/**
* Mouse button constants.
*/
public static final int NOBUTTON = 0;
public static final int BUTTON1 = 1;
public static final int BUTTON2 = 2;
public static final int BUTTON3 = 3;
/**
* Returns size of the canvas that takes project dimensions into account as
* well as zoom level. Each dimension is calculated as the product of the
@@ -159,84 +170,6 @@ public interface IPlugInPort {
*/
void setZoomLevel(double zoomLevel);
/**
* Notifies the presenter that mouse is clicked.
*
* Note: point coordinates are display based, i.e. scaled for zoom factor.
*
* @param point
* @param ctrlDown
* @param shiftDown
* @param altDown
* @param clickCount
*/
void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown,
int clickCount);
/**
* Notifies the presenter that mouse is moved.
*
* Note: point coordinates are display based, i.e. scaled for zoom factor.
*
* @param point
* @param ctrlDown
* @param shiftDown
* @param altDown
*/
void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown);
/**
* Returns the current {@link ComponentTransferable}.
*
* @return
*/
List<IDIYComponent<?>> getSelectedComponents();
/**
* Updates the selection with the specified list of component. Also, updates
* control point map with all components that are stuck to the newly
* selected components.
*
* @param newSelection
*/
void updateSelection(List<IDIYComponent<?>> newSelection);
/**
* Selects all components in the project.
*/
void selectAll();
/**
* Notification that drag has been started from the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
* @param ctrlDown
* @param shiftDown
* @param altDown
*/
void dragStarted(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown);
/**
* Checks if it's possible to drop over the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
* @return
*/
boolean dragOver(Point point);
/**
* Notification that drag has been ended in the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
*/
void dragEnded(Point point);
/**
* Returns current version number.
*
@@ -298,6 +231,11 @@ public interface IPlugInPort {
* @param properties
*/
void applyPropertiesToProject(List<PropertyWrapper> properties);
/**
* Gets the current new component slot.
*/
ComponentType getNewComponentTypeSlot();
/**
* Sets the new component slot. Specified component type will be used to
@@ -0,0 +1,48 @@
package org.diylc.common;
import java.awt.Point;
import java.util.List;
import org.diylc.core.ExpansionMode;
import org.diylc.core.IDIYComponent;
public interface ISelectionProcessor {
/**
* Returns the current {@link ComponentTransferable}.
*
* @return
*/
List<IDIYComponent<?>> getSelectedComponents();
/**
* Updates the selection with the specified list of component. Also, updates
* control point map with all components that are stuck to the newly
* selected components.
*
* @param newSelection
*/
void updateSelection(List<IDIYComponent<?>> newSelection);
/**
* Finds all components at the specified location, sorted by z-index from
* top to bottom.
*
* @param point
* @return
*/
List<IDIYComponent<?>> findComponentsAt(Point point);
/**
* Expands the current selection to include surrounding components.
* Options are controlled with <code>expansionMode</code> flag.
*
* @param expansionMode
*/
void expandSelection(ExpansionMode expansionMode);
/**
* Selects all components in the project.
*/
void selectAll();
}
@@ -22,8 +22,8 @@ public class PropertyWrapper implements Cloneable {
private boolean unique = true;
private boolean changed = false;
public PropertyWrapper(String name, Class<?> type, String getter, String setter,
boolean defaultable, IPropertyValidator validator) {
public PropertyWrapper(String name, Class<?> type, String getter,
String setter, boolean defaultable, IPropertyValidator validator) {
super();
this.name = name;
this.type = type;
@@ -33,8 +33,9 @@ public class PropertyWrapper implements Cloneable {
this.validator = validator;
}
public void readFrom(Object object) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException, SecurityException, NoSuchMethodException {
public void readFrom(Object object) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException,
SecurityException, NoSuchMethodException {
this.value = object.getClass().getMethod(getter).invoke(object);
}
@@ -47,8 +48,9 @@ public class PropertyWrapper implements Cloneable {
// }
// }
public void writeTo(Object object) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException, SecurityException, NoSuchMethodException {
public void writeTo(Object object) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException,
SecurityException, NoSuchMethodException {
object.getClass().getMethod(setter, type).invoke(object, this.value);
}
@@ -75,19 +77,19 @@ public class PropertyWrapper implements Cloneable {
public IPropertyValidator getValidator() {
return validator;
}
public boolean isUnique() {
return unique;
}
public void setUnique(boolean unique) {
this.unique = unique;
}
public boolean isChanged() {
return changed;
}
public void setChanged(boolean changed) {
this.changed = changed;
}
@@ -102,6 +104,15 @@ public class PropertyWrapper implements Cloneable {
// }
// return new Property(name, type, value);
// }
@Override
public Object clone() throws CloneNotSupportedException {
PropertyWrapper clone = new PropertyWrapper(this.name, this.type, this.getter,
this.setter, this.defaultable, this.validator);
clone.value = this.value;
clone.changed = this.changed;
clone.unique = this.unique;
return clone;
}
@Override
public int hashCode() {
@@ -0,0 +1,5 @@
package org.diylc.common;
public enum VerticalAlignment {
TOP, CENTER, BOTTOM
}
@@ -2,8 +2,19 @@ package org.diylc.components;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.VerticalAlignment;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.EditableProperty;
@@ -11,6 +22,10 @@ import org.diylc.core.annotations.EditableProperty;
* Abstract implementation of {@link IDIYComponent} that contains component name
* and toString.
*
* IMPORTANT: to improve performance, all fields except for <code>Point</code>
* and <code>Point</code> arrays should be immutable. Failing to comply with
* this can result in annoying and hard to trace bugs.
*
* @author Branislav Stojkovic
*
* @param <T>
@@ -25,6 +40,7 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
public static Color LABEL_COLOR = Color.black;
public static Color LABEL_COLOR_SELECTED = Color.red;
public static Font LABEL_FONT = new Font("Tahoma", Font.PLAIN, 14);
public static Color METAL_COLOR = Color.decode("#236B8E");
@EditableProperty(defaultable = false)
@Override
@@ -70,4 +86,96 @@ public abstract class AbstractComponent<T> implements IDIYComponent<T> {
}
return true;
}
protected void drawCenteredText(Graphics2D g2d, String text, int x, int y,
HorizontalAlignment horizontalAlignment,
VerticalAlignment verticalAlignment) {
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle stringBounds = fontMetrics.getStringBounds(text, g2d)
.getBounds();
Font font = g2d.getFont();
FontRenderContext renderContext = g2d.getFontRenderContext();
GlyphVector glyphVector = font.createGlyphVector(renderContext, text);
Rectangle visualBounds = glyphVector.getVisualBounds().getBounds();
int textX = 0;
switch (horizontalAlignment) {
case CENTER:
textX = x - stringBounds.width / 2;
break;
case LEFT:
textX = x;
break;
case RIGHT:
textX = x - stringBounds.width;
break;
}
int textY = 0;
switch (verticalAlignment) {
case TOP:
textY = y + stringBounds.height;
break;
case CENTER:
textY = y - visualBounds.height / 2 - visualBounds.y;
break;
case BOTTOM:
textY = y - visualBounds.y;
break;
}
g2d.drawString(text, textX, textY);
}
@SuppressWarnings("unchecked")
public IDIYComponent<T> clone() throws CloneNotSupportedException {
try {
// Instantiate object of the same type
AbstractComponent<T> newInstance = (AbstractComponent<T>) this
.getClass().getConstructors()[0].newInstance();
Class<?> clazz = this.getClass();
while (AbstractComponent.class.isAssignableFrom(clazz)) {
Field[] fields = clazz.getDeclaredFields();
clazz = clazz.getSuperclass();
// fields = this.getClass().getDeclaredFields();
// Copy over all non-static, non-final fields that are declared
// in
// AbstractComponent or one of it's child classes
for (Field field : fields) {
if (!Modifier.isStatic(field.getModifiers())
&& !Modifier.isFinal(field.getModifiers())) {
field.setAccessible(true);
Object value = field.get(this);
// Deep copy point arrays.
// TODO: something nicer
if (value != null
&& value.getClass().isArray()
&& value.getClass().getComponentType()
.isAssignableFrom(Point.class)) {
Object newArray = Array.newInstance(value
.getClass().getComponentType(), Array
.getLength(value));
for (int i = 0; i < Array.getLength(value); i++) {
Point p = (Point) Array.get(value, i);
Array.set(newArray, i, new Point(p));
}
value = newArray;
}
// Deep copy points.
// TODO: something nicer
if (value != null && value instanceof Point) {
value = new Point((Point) value);
}
field.set(newInstance, value);
}
}
}
return newInstance;
} catch (Exception e) {
throw new CloneNotSupportedException("Could not clone the component. Reason: " + e.getMessage());
}
}
}
@@ -195,13 +195,16 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
g2d.setColor(finalLabelColor);
FontMetrics fontMetrics = g2d.getFontMetrics();
String label = display == Display.NAME ? getName() : getValue().toString();
Rectangle2D textRect = fontMetrics.getStringBounds(label, g2d);
// Don't offset in outline mode.
int offset = outlineMode ? 0 : getLabelOffset((int) shapeRect.getWidth(), (int) textRect.getWidth());
// Adjust label angle if needed to make sure that it's readable.
if ((theta >= Math.PI / 2 && theta <= Math.PI)
|| (theta < -Math.PI / 2 && theta > -Math.PI)) {
g2d.rotate(Math.PI, shapeRect.width / 2, shapeRect.height / 2);
}
Rectangle2D textRect = fontMetrics.getStringBounds(label, g2d);
g2d.drawString(label, (int) (shapeRect.width - textRect.getWidth()) / 2,
offset = -offset;
}
g2d.drawString(label, (int) (shapeRect.width - textRect.getWidth()) / 2 + offset,
calculateLabelYCoordinate(shapeRect, textRect, fontMetrics));
g2d.setTransform(oldTransform);
}
@@ -237,6 +240,10 @@ public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComp
protected boolean supportsStandingMode() {
return false;
}
protected int getLabelOffset(int bodyWidth, int labelWidth) {
return 0;
}
/**
* @return default component length.
@@ -0,0 +1,8 @@
package org.diylc.core;
public enum ExpansionMode {
ALL,
SAME_TYPE,
IMMEDIATE,
}
@@ -107,7 +107,8 @@ public interface IDIYComponent<T> extends Serializable {
* @param project
* @param drawingObserver
*/
void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
void draw(Graphics2D g2d, ComponentState componentState,
boolean outlineMode, Project project,
IDrawingObserver drawingObserver);
/**
@@ -119,4 +120,11 @@ public interface IDIYComponent<T> extends Serializable {
* @param height
*/
void drawIcon(Graphics2D g2d, int width, int height);
/**
* Clones the component.
*
* @return
*/
IDIYComponent<T> clone() throws CloneNotSupportedException;
}
+3
View File
@@ -1,5 +1,6 @@
package org.diylc.core;
import java.io.File;
import java.util.List;
import java.util.Set;
@@ -35,4 +36,6 @@ public interface IView {
int showConfirmDialog(String message, String title, int optionType, int messageType);
boolean editProperties(List<PropertyWrapper> properties, Set<PropertyWrapper> defaultedProperties);
File promptFileSave();
}
+37 -13
View File
@@ -2,8 +2,10 @@ package org.diylc.core;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.diylc.appframework.update.VersionNumber;
@@ -201,8 +203,8 @@ public class Project implements Serializable {
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(0.5d, SizeUnit.mm)) < 0) {
throw new ValidationException("must be at least 0.5mm");
}
if (size.compareTo(new Size(1d, SizeUnit.in)) > 0) {
throw new ValidationException("must be less than 1in");
@@ -210,15 +212,37 @@ public class Project implements Serializable {
}
}
// @Override
// public Project clone() throws CloneNotSupportedException {
// List<IDIYComponent> clonedComponents = new
// ArrayList<IDIYComponent>();
// for (IDIYComponent component : components) {
// clonedComponents.add(component.clone());
// }
// Project project = new Project(title, author, description,
// width.clone(), height.clone(), clonedComponents);
// return project;
// }
@Override
public Project clone() {
Project project = new Project();
project.setTitle(this.getTitle());
project.setAuthor(this.getAuthor());
project.setDescription(this.getDescription());
project.setFileVersion(this.getFileVersion());
project.setGridSpacing(this.getGridSpacing());
project.setHeight(this.getHeight());
project.setWidth(this.getWidth());
project.getLockedLayers().addAll(this.getLockedLayers());
Map<IDIYComponent<?>, IDIYComponent<?>> cloneMap = new HashMap<IDIYComponent<?>, IDIYComponent<?>>();
for (IDIYComponent<?> component : this.components) {
try {
IDIYComponent<?> clone = component.clone();
project.getComponents().add(clone);
cloneMap.put(component, clone);
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
for (Set<IDIYComponent<?>> group : this.groups) {
Set<IDIYComponent<?>> cloneGroup = new HashSet<IDIYComponent<?>>();
for (IDIYComponent<?> component : group) {
cloneGroup.add(cloneMap.get(component));
}
project.groups.add(cloneGroup);
}
return project;
}
}
@@ -0,0 +1,7 @@
package org.diylc.core.annotations;
public enum BomPolicy {
SHOW_ALL_NAMES,
SHOW_ONLY_TYPE_NAME,
NEVER_SHOW,
}
@@ -53,10 +53,22 @@ public @interface ComponentDescriptor {
*/
double zOrder();
/**
* @return true if the component may go beyond it's predefined layer. In
* that case, <code>zOrder</code> is used as initial z order of the
* component.
*/
boolean flexibleZOrder() default false;
/**
* @return when false, moving one control point will cause all the others to
* move together with it.
*/
boolean stretchable() default true;
/**
* @return controls what should be shown the BOM
*/
BomPolicy bomPolicy() default BomPolicy.SHOW_ALL_NAMES;
}
@@ -4,6 +4,13 @@ import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.Format;
/***
* Immutable measure class.
*
* @author bancika
*
* @param <T>
*/
public class AbstractMeasure<T extends Enum<? extends Unit>> implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
@@ -13,8 +20,8 @@ public class AbstractMeasure<T extends Enum<? extends Unit>> implements Serializ
protected Double value;
protected T unit;
public AbstractMeasure() {
}
// public AbstractMeasure() {
// }
public AbstractMeasure(Double value, T unit) {
super();
@@ -26,22 +33,22 @@ public class AbstractMeasure<T extends Enum<? extends Unit>> implements Serializ
return value;
}
public void setValue(Double value) {
this.value = value;
}
// public void setValue(Double value) {
// this.value = value;
// }
public T getUnit() {
return unit;
}
public void setUnit(T multiplier) {
this.unit = multiplier;
}
// public void setUnit(T multiplier) {
// this.unit = multiplier;
// }
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
// @Override
// public Object clone() throws CloneNotSupportedException {
// return super.clone();
// }
@Override
public int hashCode() {
@@ -76,6 +83,6 @@ public class AbstractMeasure<T extends Enum<? extends Unit>> implements Serializ
@Override
public String toString() {
return format.format(value) + " " + unit;
return format.format(value) + unit;
}
}
@@ -4,10 +4,10 @@ public class Capacitance extends AbstractMeasure<CapacitanceUnit> {
private static final long serialVersionUID = 1L;
public Capacitance() {
super();
// TODO Auto-generated constructor stub
}
// public Capacitance() {
// super();
// // TODO Auto-generated constructor stub
// }
public Capacitance(Double value, CapacitanceUnit unit) {
super(value, unit);
@@ -4,10 +4,10 @@ public class Inductance extends AbstractMeasure<InductanceUnit> {
private static final long serialVersionUID = 1L;
public Inductance() {
super();
// TODO Auto-generated constructor stub
}
// public Inductance() {
// super();
// // TODO Auto-generated constructor stub
// }
public Inductance(Double value, InductanceUnit unit) {
super(value, unit);
@@ -0,0 +1,31 @@
package org.diylc.core.measures;
public class Power extends AbstractMeasure<PowerUnit> {
private static final long serialVersionUID = 1L;
// public Power() {
// super();
// // TODO Auto-generated constructor stub
// }
public Power(Double value, PowerUnit unit) {
super(value, unit);
// TODO Auto-generated constructor stub
}
@Override
public Power clone() throws CloneNotSupportedException {
return new Power(value, unit);
}
public static Power parseCapacitance(String value) {
for (PowerUnit unit : PowerUnit.values()) {
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
return new Power(Double.parseDouble(value), unit);
}
}
throw new IllegalArgumentException("Could not parse power: " + value);
}
}
@@ -0,0 +1,24 @@
package org.diylc.core.measures;
public enum PowerUnit implements Unit {
MW(1e-1, "mW"), W(1, "W"), KW(1e3, "KW");
double factor;
String display;
private PowerUnit(double factor, String display) {
this.factor = factor;
this.display = display;
}
@Override
public double getFactor() {
return factor;
}
@Override
public String toString() {
return display;
}
}
@@ -15,10 +15,10 @@ public class Resistance extends AbstractMeasure<ResistanceUnit> {
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
}
// public Resistance() {
// super();
// // TODO Auto-generated constructor stub
// }
public Resistance(Double value, ResistanceUnit multiplier) {
super(value, multiplier);
@@ -32,36 +32,56 @@ public class Resistance extends AbstractMeasure<ResistanceUnit> {
public Color[] getColorCode(ResistorColorCode resistorColorCode) {
Color[] bands;
double base = getValue() * getUnit().getFactor();
int multiplier = 0;
while (base > (resistorColorCode == ResistorColorCode._4_BAND ? 99 : 999)) {
multiplier += 1;
base /= 10;
}
while (base < (resistorColorCode == ResistorColorCode._4_BAND ? 10 : 100)) {
multiplier -= 1;
base *= 10;
}
if (multiplier > 6 || multiplier < -2) {
// Out of range.
return new Color[] {};
}
switch (resistorColorCode) {
case _4_BAND:
bands = new Color[3];
bands[0] = COLOR_DIGITS[(int) (base / 10)];
bands[1] = COLOR_DIGITS[(int) (base % 10)];
bands[2] = COLOR_MULTIPLIER[multiplier + 2];
break;
case _5_BAND:
bands = new Color[4];
bands[0] = COLOR_DIGITS[(int) (base / 100)];
bands[1] = COLOR_DIGITS[(int) (base / 10 % 10)];
bands[2] = COLOR_DIGITS[(int) (base % 10)];
bands[3] = COLOR_MULTIPLIER[multiplier + 2];
break;
default:
bands = new Color[] {};
if (getValue() == 0) {
switch (resistorColorCode) {
case _4_BAND:
bands = new Color[3];
bands[0] = COLOR_DIGITS[0];
bands[1] = COLOR_DIGITS[0];
bands[2] = COLOR_MULTIPLIER[2];
break;
case _5_BAND:
bands = new Color[4];
bands[0] = COLOR_DIGITS[0];
bands[1] = COLOR_DIGITS[0];
bands[2] = COLOR_DIGITS[0];
bands[3] = COLOR_MULTIPLIER[2];
break;
default:
bands = new Color[] {};
}
} else {
double base = getValue() * getUnit().getFactor();
int multiplier = 0;
while (base > (resistorColorCode == ResistorColorCode._4_BAND ? 99 : 999)) {
multiplier += 1;
base /= 10;
}
while (base < (resistorColorCode == ResistorColorCode._4_BAND ? 10 : 100)) {
multiplier -= 1;
base *= 10;
}
if (multiplier > 6 || multiplier < -2) {
// Out of range.
return new Color[] {};
}
switch (resistorColorCode) {
case _4_BAND:
bands = new Color[3];
bands[0] = COLOR_DIGITS[(int) (base / 10)];
bands[1] = COLOR_DIGITS[(int) (base % 10)];
bands[2] = COLOR_MULTIPLIER[multiplier + 2];
break;
case _5_BAND:
bands = new Color[4];
bands[0] = COLOR_DIGITS[(int) (base / 100)];
bands[1] = COLOR_DIGITS[(int) (base / 10 % 10)];
bands[2] = COLOR_DIGITS[(int) (base % 10)];
bands[3] = COLOR_MULTIPLIER[multiplier + 2];
break;
default:
bands = new Color[] {};
}
}
return bands;
}
@@ -69,7 +89,7 @@ public class Resistance extends AbstractMeasure<ResistanceUnit> {
public static Resistance parseResistance(String value) {
for (ResistanceUnit unit : ResistanceUnit.values()) {
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
value = value.substring(0, value.length() - unit.toString().length()).trim();
return new Resistance(Double.parseDouble(value), unit);
}
}
@@ -2,7 +2,7 @@ package org.diylc.core.measures;
public enum ResistanceUnit implements Unit {
R(1, "\u03a9"), K(1e3, "K"), M(1e6, "M");
R(1, "\u2126"), K(1e3, "K"), M(1e6, "M");
double factor;
String display;
@@ -6,10 +6,10 @@ public class Size extends AbstractMeasure<SizeUnit> implements Comparable<Size>
private static final long serialVersionUID = 1L;
public Size() {
super();
// TODO Auto-generated constructor stub
}
// public Size() {
// super();
// // TODO Auto-generated constructor stub
// }
public Size(Double value, SizeUnit unit) {
super(value, unit);
@@ -0,0 +1,31 @@
package org.diylc.core.measures;
public class Voltage extends AbstractMeasure<VoltageUnit> {
private static final long serialVersionUID = 1L;
// public Voltage() {
// super();
// // TODO Auto-generated constructor stub
// }
public Voltage(Double value, VoltageUnit unit) {
super(value, unit);
// TODO Auto-generated constructor stub
}
@Override
public Voltage clone() throws CloneNotSupportedException {
return new Voltage(value, unit);
}
public static Voltage parseCapacitance(String value) {
for (VoltageUnit unit : VoltageUnit.values()) {
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
return new Voltage(Double.parseDouble(value), unit);
}
}
throw new IllegalArgumentException("Could not parse voltage: " + value);
}
}
@@ -0,0 +1,24 @@
package org.diylc.core.measures;
public enum VoltageUnit implements Unit {
MV(1e-1, "mV"), V(1, "V"), KV(1e3, "KV");
double factor;
String display;
private VoltageUnit(double factor, String display) {
this.factor = factor;
this.display = display;
}
@Override
public double getFactor() {
return factor;
}
@Override
public String toString() {
return display;
}
}
@@ -31,7 +31,7 @@ public enum IconLoader {
"donate.png"), Bug("bug.png"), IconLarge("icon_large.png"), IconMedium(
"icon_medium.png"), IconSmall("icon_small.png"), DocumentEdit("document_edit.png"), EditComponent(
"edit_component.png"), Size("size.png"), Front("front.png"), Back("back.png"), Pens(
"pens.png"), Sort("sort.png");
"pens.png"), Sort("sort.png"), ElementsSelection("elements_selection.png");
protected String name;
Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

@@ -20,11 +20,10 @@ 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.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import com.rits.cloning.Cloner;
/**
* Utility class with component processing methods.
*
@@ -32,7 +31,8 @@ import com.rits.cloning.Cloner;
*/
public class ComponentProcessor {
private static final Logger LOG = Logger.getLogger(ComponentProcessor.class);
private static final Logger LOG = Logger
.getLogger(ComponentProcessor.class);
private static ComponentProcessor instance;
@@ -40,8 +40,6 @@ public class ComponentProcessor {
private Map<String, IPropertyValidator> propertyValidatorCache;
private Map<String, ComponentType> componentTypeMap;
private Cloner cloner;
public static ComponentProcessor getInstance() {
if (instance == null) {
instance = new ComponentProcessor();
@@ -51,13 +49,13 @@ public class ComponentProcessor {
private ComponentProcessor() {
super();
this.cloner = new Cloner();
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) {
public ComponentType extractComponentTypeFrom(
Class<? extends IDIYComponent<?>> clazz) {
if (componentTypeMap.containsKey(clazz.getName())) {
return componentTypeMap.get(clazz.getName());
}
@@ -69,9 +67,12 @@ public class ComponentProcessor {
String author;
Icon icon;
double zOrder;
boolean flexibleZOrder;
boolean stretchable;
BomPolicy bomPolicy;
if (clazz.isAnnotationPresent(ComponentDescriptor.class)) {
ComponentDescriptor annotation = clazz.getAnnotation(ComponentDescriptor.class);
ComponentDescriptor annotation = clazz
.getAnnotation(ComponentDescriptor.class);
name = annotation.name();
description = annotation.description();
creationMethod = annotation.creationMethod();
@@ -79,7 +80,9 @@ public class ComponentProcessor {
namePrefix = annotation.instanceNamePrefix();
author = annotation.author();
zOrder = annotation.zOrder();
flexibleZOrder = annotation.flexibleZOrder();
stretchable = annotation.stretchable();
bomPolicy = annotation.bomPolicy();
} else {
name = clazz.getSimpleName();
description = "";
@@ -88,27 +91,30 @@ public class ComponentProcessor {
namePrefix = "Unknown";
author = "Unknown";
zOrder = IDIYComponent.COMPONENT;
flexibleZOrder = false;
stretchable = true;
bomPolicy = BomPolicy.SHOW_ALL_NAMES;
}
icon = null;
// Draw component icon.
try {
IDIYComponent<?> componentInstance = (IDIYComponent<?>) clazz.newInstance();
Image image = new BufferedImage(Presenter.ICON_SIZE, Presenter.ICON_SIZE,
IDIYComponent<?> componentInstance = (IDIYComponent<?>) clazz
.newInstance();
Image image = new BufferedImage(Presenter.ICON_SIZE,
Presenter.ICON_SIZE,
java.awt.image.BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) image.getGraphics();
g2d
.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
componentInstance.drawIcon(g2d, Presenter.ICON_SIZE, Presenter.ICON_SIZE);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
componentInstance.drawIcon(g2d, Presenter.ICON_SIZE,
Presenter.ICON_SIZE);
icon = new ImageIcon(image);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
throw new RuntimeException(e);
}
ComponentType componentType = new ComponentType(name, description, creationMethod,
category, namePrefix, author, icon, clazz, zOrder, stretchable);
ComponentType componentType = new ComponentType(name, description,
creationMethod, category, namePrefix, author, icon, clazz,
zOrder, flexibleZOrder, stretchable, bomPolicy);
componentTypeMap.put(clazz.getName(), componentType);
return componentType;
}
@@ -121,7 +127,7 @@ public class ComponentProcessor {
*/
public List<PropertyWrapper> extractProperties(Class<?> clazz) {
if (propertyCache.containsKey(clazz.getName())) {
return cloner.deepClone(propertyCache.get(clazz.getName()));
return cloneProperties(propertyCache.get(clazz.getName()));
}
List<PropertyWrapper> properties = new ArrayList<PropertyWrapper>();
for (Method method : clazz.getMethods()) {
@@ -129,7 +135,8 @@ public class ComponentProcessor {
try {
if (method.isAnnotationPresent(EditableProperty.class)
&& !method.isAnnotationPresent(Deprecated.class)) {
EditableProperty annotation = method.getAnnotation(EditableProperty.class);
EditableProperty annotation = method
.getAnnotation(EditableProperty.class);
String name;
if (annotation.name().equals("")) {
name = method.getName().substring(3);
@@ -138,22 +145,36 @@ public class ComponentProcessor {
}
IPropertyValidator validator = getPropertyValidator(annotation
.validatorClass());
Method setter = clazz.getMethod("set" + method.getName().substring(3),
method.getReturnType());
Method setter = clazz.getMethod("set"
+ method.getName().substring(3), method
.getReturnType());
PropertyWrapper property = new PropertyWrapper(name,
method.getReturnType(), method.getName(), setter.getName(),
annotation.defaultable(), validator);
method.getReturnType(), method.getName(),
setter.getName(), annotation.defaultable(),
validator);
properties.add(property);
}
} catch (NoSuchMethodException e) {
LOG.debug("No matching setter found for \"" + method.getName()
+ "\". Skipping...");
LOG.debug("No matching setter found for \""
+ method.getName() + "\". Skipping...");
}
}
}
propertyCache.put(clazz.getName(), properties);
return cloner.deepClone(properties);
return cloneProperties(properties);
}
private List<PropertyWrapper> cloneProperties(List<PropertyWrapper> properties) {
List<PropertyWrapper> result = new ArrayList<PropertyWrapper>(properties.size());
for (PropertyWrapper propertyWrapper : properties) {
try {
result.add((PropertyWrapper) propertyWrapper.clone());
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
return result;
}
/**
@@ -177,7 +198,8 @@ public class ComponentProcessor {
}
for (int i = 1; i < selectedComponents.size(); i++) {
IDIYComponent<?> component = selectedComponents.get(i);
List<PropertyWrapper> newProperties = extractProperties(component.getClass());
List<PropertyWrapper> newProperties = extractProperties(component
.getClass());
for (PropertyWrapper property : newProperties) {
property.readFrom(component);
}
@@ -186,11 +208,14 @@ public class ComponentProcessor {
// their values match.
for (PropertyWrapper oldProperty : properties) {
if (newProperties.contains(oldProperty)) {
PropertyWrapper newProperty = newProperties.get(newProperties
.indexOf(oldProperty));
if ((newProperty.getValue() != null && newProperty.getValue() == null)
|| !newProperty.getValue().equals(oldProperty.getValue())) {
// Values don't match, so the property is not unique valued.
PropertyWrapper newProperty = newProperties
.get(newProperties.indexOf(oldProperty));
if ((newProperty.getValue() != null && newProperty
.getValue() == null)
|| !newProperty.getValue().equals(
oldProperty.getValue())) {
// Values don't match, so the property is not unique
// valued.
oldProperty.setUnique(false);
}
}
@@ -204,11 +229,13 @@ public class ComponentProcessor {
// }
// }
}
Collections.sort(properties, ComparatorFactory.getInstance().getPropertyNameComparator());
Collections.sort(properties, ComparatorFactory.getInstance()
.getPropertyNameComparator());
return properties;
}
private IPropertyValidator getPropertyValidator(Class<? extends IPropertyValidator> clazz) {
private IPropertyValidator getPropertyValidator(
Class<? extends IPropertyValidator> clazz) {
if (propertyValidatorCache.containsKey(clazz.getName())) {
return propertyValidatorCache.get(clazz.getName());
}
@@ -216,7 +243,8 @@ public class ComponentProcessor {
try {
validator = clazz.newInstance();
} catch (Exception e) {
LOG.error("Could not instantiate validator for " + clazz.getName(), e);
LOG.error("Could not instantiate validator for " + clazz.getName(),
e);
return null;
}
propertyValidatorCache.put(clazz.getName(), validator);
@@ -362,7 +362,7 @@ public class DrawingManager {
for (int i = 0; i < project.getComponents().size(); i++) {
Area area = componentAreaMap.get(project.getComponents().get(i));
if (area != null && area.contains(point)) {
components.add(project.getComponents().get(i));
components.add(0, project.getComponents().get(i));
}
}
return components;
@@ -3,19 +3,19 @@ package org.diylc.presenter;
import java.awt.Point;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.ComponentType;
import org.diylc.common.IPlugInPort;
import org.diylc.common.Orientation;
import org.diylc.common.PropertyWrapper;
import org.diylc.core.IDIYComponent;
import org.diylc.core.Project;
import org.diylc.core.measures.Size;
import com.rits.cloning.Cloner;
/**
* Manages component instantiation.
*
@@ -23,11 +23,10 @@ import com.rits.cloning.Cloner;
*/
public class InstantiationManager {
private static final Logger LOG = Logger.getLogger(InstantiationManager.class);
private static final Logger LOG = Logger
.getLogger(InstantiationManager.class);
private static final int MAX_RECENT_COMPONENTS = 16;
private Cloner cloner;
public static int MAX_RECENT_COMPONENTS = 16;
private ComponentType componentTypeSlot;
private IDIYComponent<?> componentSlot;
@@ -35,7 +34,6 @@ public class InstantiationManager {
private Point potentialControlPoint;
public InstantiationManager() {
cloner = new Cloner();
}
public ComponentType getComponentTypeSlot() {
@@ -54,8 +52,8 @@ public class InstantiationManager {
return potentialControlPoint;
}
public void setComponentTypeSlot(ComponentType componentTypeSlot, Project currentProject)
throws Exception {
public void setComponentTypeSlot(ComponentType componentTypeSlot,
Project currentProject) throws Exception {
this.componentTypeSlot = componentTypeSlot;
if (componentTypeSlot == null) {
this.componentSlot = null;
@@ -65,8 +63,8 @@ public class InstantiationManager {
this.componentSlot = null;
break;
case SINGLE_CLICK:
this.componentSlot = instantiateComponent(componentTypeSlot, new Point(0, 0),
currentProject);
this.componentSlot = instantiateComponent(componentTypeSlot,
new Point(0, 0), currentProject);
break;
}
}
@@ -74,9 +72,11 @@ public class InstantiationManager {
this.potentialControlPoint = null;
}
public void instatiatePointByPoint(Point scaledPoint, Project currentProject) throws Exception {
public void instatiatePointByPoint(Point scaledPoint, Project currentProject)
throws Exception {
firstControlPoint = scaledPoint;
componentSlot = instantiateComponent(componentTypeSlot, firstControlPoint, currentProject);
componentSlot = instantiateComponent(componentTypeSlot,
firstControlPoint, currentProject);
// Set the other control point to the same location, we'll
// move it later when mouse moves.
@@ -99,7 +99,8 @@ public class InstantiationManager {
return changeMade;
}
public boolean updateSingleClick(Point scaledPoint, boolean snapToGrid, Size gridSpacing) {
public boolean updateSingleClick(Point scaledPoint, boolean snapToGrid,
Size gridSpacing) {
if (potentialControlPoint == null) {
potentialControlPoint = new Point(0, 0);
}
@@ -128,12 +129,14 @@ public class InstantiationManager {
}
@SuppressWarnings("unchecked")
public IDIYComponent<?> instantiateComponent(ComponentType componentType, Point point,
Project currentProject) throws Exception {
LOG.info("Instatiating component of type: " + componentType.getInstanceClass().getName());
public IDIYComponent<?> instantiateComponent(ComponentType componentType,
Point point, Project currentProject) throws Exception {
LOG.info("Instatiating component of type: "
+ componentType.getInstanceClass().getName());
// Instantiate the component.
IDIYComponent<?> component = componentType.getInstanceClass().newInstance();
IDIYComponent<?> component = componentType.getInstanceClass()
.newInstance();
component.setName(createUniqueName(componentType, currentProject));
@@ -150,10 +153,12 @@ public class InstantiationManager {
fillWithDefaultProperties(component);
// Write to recent components
List<String> recentComponentTypes = (List<String>) ConfigurationManager.getInstance()
.readObject(IPlugInPort.RECENT_COMPONENTS_KEY, new ArrayList<ComponentType>());
List<String> recentComponentTypes = (List<String>) ConfigurationManager
.getInstance().readObject(IPlugInPort.RECENT_COMPONENTS_KEY,
new ArrayList<ComponentType>());
String className = componentType.getInstanceClass().getName();
if (recentComponentTypes.size() == 0 || !recentComponentTypes.get(0).equals(className)) {
if (recentComponentTypes.size() == 0
|| !recentComponentTypes.get(0).equals(className)) {
// Remove if it's already somewhere in the list.
recentComponentTypes.remove(className);
// Add to the end of the list.
@@ -162,25 +167,30 @@ public class InstantiationManager {
if (recentComponentTypes.size() > MAX_RECENT_COMPONENTS) {
recentComponentTypes.remove(recentComponentTypes.size() - 1);
}
ConfigurationManager.getInstance().writeValue(IPlugInPort.RECENT_COMPONENTS_KEY,
recentComponentTypes);
ConfigurationManager.getInstance().writeValue(
IPlugInPort.RECENT_COMPONENTS_KEY, recentComponentTypes);
}
return component;
}
public String createUniqueName(ComponentType componentType, Project currentProject) {
public String createUniqueName(ComponentType componentType,
Project currentProject) {
int i = 0;
boolean exists = true;
List<IDIYComponent<?>> components = currentProject.getComponents();
String[] takenNames = new String[components.size()];
for (int j = 0; j < currentProject.getComponents().size(); j++) {
takenNames[j] = components.get(i).getName();
}
Arrays.sort(takenNames);
while (exists) {
i++;
String name = componentType.getNamePrefix() + i;
exists = false;
for (IDIYComponent<?> c : currentProject.getComponents()) {
if (c.getName().equals(name)) {
exists = true;
break;
}
if (Arrays.binarySearch(takenNames, name) >= 0) {
exists = true;
break;
}
}
return componentType.getNamePrefix() + i;
@@ -198,22 +208,55 @@ public class InstantiationManager {
* @throws NoSuchMethodException
* @throws SecurityException
*/
public void fillWithDefaultProperties(Object object) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException, SecurityException,
NoSuchMethodException {
public void fillWithDefaultProperties(Object object)
throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException, SecurityException, NoSuchMethodException {
// Extract properties.
List<PropertyWrapper> properties = ComponentProcessor.getInstance().extractProperties(
object.getClass());
List<PropertyWrapper> properties = ComponentProcessor.getInstance()
.extractProperties(object.getClass());
// Override with default values if available.
for (PropertyWrapper property : properties) {
Object defaultValue = ConfigurationManager.getInstance().readObject(
Presenter.DEFAULTS_KEY_PREFIX + object.getClass().getName() + ":"
+ property.getName(), null);
Object defaultValue = ConfigurationManager.getInstance()
.readObject(
Presenter.DEFAULTS_KEY_PREFIX
+ object.getClass().getName() + ":"
+ property.getName(), null);
if (defaultValue != null) {
property.setValue(cloner.deepClone(defaultValue));
property.setValue(defaultValue);
property.writeTo(object);
}
}
}
public void tryToRotateComponentSlot() {
if (this.componentSlot == null) {
LOG.debug("Component slot is empty, cannot rotate");
return;
}
List<PropertyWrapper> properties = ComponentProcessor.getInstance()
.extractProperties(this.componentTypeSlot.getInstanceClass());
PropertyWrapper angleProperty = null;
for (PropertyWrapper propertyWrapper : properties) {
if (propertyWrapper.getType().getName().equals(
Orientation.class.getName())) {
angleProperty = propertyWrapper;
break;
}
}
if (angleProperty == null) {
LOG
.debug("Component in the slot does not have a property of type Orientation, cannot rotate");
return;
}
try {
angleProperty.readFrom(this.componentSlot);
Orientation value = (Orientation) angleProperty.getValue();
value.ordinal();
angleProperty.setValue(Orientation.values()[(value.ordinal() + 1)
% Orientation.values().length]);
angleProperty.writeTo(this.componentSlot);
} catch (Exception e) {
LOG.warn("Error trying to rotate the component", e);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -6,6 +6,11 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -17,8 +22,11 @@ import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
import org.diylc.appframework.simplemq.MessageDispatcher;
import org.diylc.common.Display;
import org.diylc.common.EventType;
import org.diylc.common.Orientation;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.components.boards.AbstractBoard;
import org.diylc.components.boards.BlankBoard;
import org.diylc.components.boards.PerfBoard;
@@ -28,9 +36,11 @@ import org.diylc.components.connectivity.HookupWire;
import org.diylc.components.connectivity.Jumper;
import org.diylc.components.connectivity.SolderPad;
import org.diylc.components.misc.Label;
import org.diylc.components.passive.PotentiometerPanel;
import org.diylc.components.passive.RadialElectrolytic;
import org.diylc.components.passive.RadialFilmCapacitor;
import org.diylc.components.passive.Resistor;
import org.diylc.components.passive.Taper;
import org.diylc.components.semiconductors.DIL_IC;
import org.diylc.components.semiconductors.DiodePlastic;
import org.diylc.components.semiconductors.LED;
@@ -46,6 +56,7 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.thoughtworks.xstream.XStream;
@@ -73,13 +84,13 @@ public class ProjectFileManager {
private XStream xStreamOld;
private String currentFileName = null;
private boolean modified = false;
private boolean modified = false;
private MessageDispatcher<EventType> messageDispatcher;
public ProjectFileManager(MessageDispatcher<EventType> messageDispatcher) {
super();
this.xStream = new XStream(new DomDriver());
this.xStream = new XStream(new DomDriver("UTF-8"));
xStream.autodetectAnnotations(true);
xStream.registerConverter(new PointConverter());
this.xStreamOld = new XStream(new DomDriver());
@@ -93,14 +104,16 @@ public class ProjectFileManager {
fireFileStatusChanged();
}
public void serializeProjectToFile(Project project, String fileName, boolean isBackup)
public synchronized void serializeProjectToFile(Project project, String fileName, boolean isBackup)
throws IOException {
if (!isBackup) {
LOG.info(String.format("saveProjectToFile(%s)", fileName));
}
FileOutputStream fos;
fos = new FileOutputStream(fileName);
xStream.toXML(project, fos);
Writer writer = new OutputStreamWriter(fos, "UTF-8");
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
xStream.toXML(project, writer);
fos.close();
if (!isBackup) {
this.currentFileName = fileName;
@@ -116,7 +129,7 @@ public class ProjectFileManager {
File file = new File(fileName);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
Document doc = db.parse(new InputSource(new InputStreamReader(new FileInputStream(file))));
doc.getDocumentElement().normalize();
if (doc.getDocumentElement().getNodeName().equalsIgnoreCase(Project.class.getName())) {
project = parseV3File(fileName);
@@ -236,7 +249,7 @@ public class ProjectFileManager {
label.setText(valueAttr);
label.setCenter(false);
label.setControlPoint(convertV1CoordinatesToV3Point(referencePoint, x1Attr,
y1Attr), 0);
y1Attr + 1), 0);
component = label;
} else if (nodeName.equalsIgnoreCase("pad")) {
LOG.debug("Recognized " + nodeName);
@@ -270,6 +283,8 @@ public class ProjectFileManager {
HookupWire wire = new HookupWire();
Point midPoint = new Point((point1.x + point2.x) / 2, (point1.y + point2.y) / 2);
wire.setName(nameAttr);
String colorAttr = node.getAttributes().getNamedItem("Color").getNodeValue();
wire.setColor(parseV1Color(colorAttr));
wire.setControlPoint(point1, 0);
wire.setControlPoint(midPoint, 1);
wire.setControlPoint(midPoint, 2);
@@ -284,8 +299,8 @@ public class ProjectFileManager {
} catch (Exception e) {
LOG.debug("Could not set value of " + nameAttr);
}
resistor.setLength(new Size(6d, SizeUnit.mm));
resistor.setWidth(new Size(2d, SizeUnit.mm));
resistor.setLength(new Size(6.35d, SizeUnit.mm));
resistor.setWidth(new Size(2.2d, SizeUnit.mm));
resistor.setControlPoint(point1, 0);
resistor.setControlPoint(point2, 1);
component = resistor;
@@ -312,15 +327,20 @@ public class ProjectFileManager {
} catch (Exception e) {
LOG.debug("Could not set value of " + nameAttr);
}
String sizeAttr = node.getAttributes().getNamedItem("Size").getNodeValue();
if (sizeAttr.equalsIgnoreCase("small")) {
capacitor.setLength(new Size(3.5d, SizeUnit.mm));
} else if (sizeAttr.equalsIgnoreCase("medium")) {
try {
String sizeAttr = node.getAttributes().getNamedItem("Size").getNodeValue();
if (sizeAttr.equalsIgnoreCase("small")) {
capacitor.setLength(new Size(3.5d, SizeUnit.mm));
} else if (sizeAttr.equalsIgnoreCase("medium")) {
capacitor.setLength(new Size(5d, SizeUnit.mm));
} else if (sizeAttr.equalsIgnoreCase("large")) {
capacitor.setLength(new Size(7d, SizeUnit.mm));
} else {
capacitor.setLength(new Size(4d, SizeUnit.mm));
}
} catch (Exception e) {
capacitor.setLength(new Size(5d, SizeUnit.mm));
} else if (sizeAttr.equalsIgnoreCase("large")) {
capacitor.setLength(new Size(7d, SizeUnit.mm));
} else {
capacitor.setLength(new Size(4d, SizeUnit.mm));
LOG.debug("Could not set size of " + nameAttr);
}
capacitor.setControlPoint(point1, 0);
capacitor.setControlPoint(point2, 1);
@@ -374,18 +394,27 @@ public class ProjectFileManager {
} else if (nodeName.equalsIgnoreCase("ic")) {
LOG.debug("Recognized " + nodeName);
DIL_IC ic = new DIL_IC();
if (x1Attr + 3 == x2Attr) {
if (y1Attr < y2Attr) {
ic
.setPinCount(DIL_IC.PinCount.valueOf("_" + 2
* (y2Attr - y1Attr + 1)));
} else {
ic.setOrientation(Orientation._180);
ic
.setPinCount(DIL_IC.PinCount.valueOf("_" + 2
* (y1Attr - y2Attr + 1)));
}
int pinCount = 8;
int rowSpace = 3;
if (x1Attr < x2Attr && y1Attr < y2Attr) {
pinCount = (y2Attr - y1Attr + 1) * 2;
rowSpace = x2Attr - x1Attr;
ic.setOrientation(Orientation.DEFAULT);
} else if (x1Attr > x2Attr && y1Attr < y2Attr) {
pinCount = (x1Attr - x2Attr + 1) * 2;
rowSpace = y2Attr - y1Attr;
ic.setOrientation(Orientation._90);
} else if (x1Attr > x2Attr && y1Attr > y2Attr) {
rowSpace = x1Attr - x2Attr;
pinCount = (y1Attr - y2Attr + 1) * 2;
ic.setOrientation(Orientation._180);
} else if (x1Attr < x2Attr && y1Attr > y2Attr) {
rowSpace = y1Attr - y2Attr;
pinCount = (x2Attr - x1Attr + 1) * 2;
ic.setOrientation(Orientation._270);
}
ic.setRowSpacing(new Size(0.1 * rowSpace, SizeUnit.in));
ic.setPinCount(DIL_IC.PinCount.valueOf("_" + pinCount));
ic.setName(nameAttr);
// Translate control points.
for (int j = 0; j < ic.getControlPointCount(); j++) {
@@ -395,6 +424,58 @@ public class ProjectFileManager {
}
ic.setValue(valueAttr);
component = ic;
} else if (nodeName.equalsIgnoreCase("pot")) {
LOG.debug("Recognized " + nodeName);
PotentiometerPanel pot = new PotentiometerPanel();
pot.setBodyDiameter(new Size(14d, SizeUnit.mm));
pot.setSpacing(new Size(0.2, SizeUnit.in));
pot.setName(nameAttr);
try {
pot.setResistance(Resistance.parseResistance(valueAttr));
} catch (Exception e) {
LOG.debug("Could not set value of " + nameAttr);
}
String taperAttr = node.getAttributes().getNamedItem("Taper").getNodeValue();
if ("Linear".equals(taperAttr)) {
pot.setTaper(Taper.LIN);
} else if ("Audio".equals(taperAttr)) {
pot.setTaper(Taper.LOG);
} else if ("Reverse Audio".equals(taperAttr)) {
pot.setTaper(Taper.REV_LOG);
}
// Pin spacing, we'll need to move pot around a bit.
int delta = Constants.PIXELS_PER_INCH / 5;
if (x1Attr < x2Attr) {
pot.setOrientation(Orientation.DEFAULT);
for (int j = 0; j < pot.getControlPointCount(); j++) {
Point p = new Point(pot.getControlPoint(j));
p.translate(point1.x - delta, point1.y);
pot.setControlPoint(p, j);
}
} else if (x1Attr > x2Attr) {
pot.setOrientation(Orientation._180);
for (int j = 0; j < pot.getControlPointCount(); j++) {
Point p = new Point(pot.getControlPoint(j));
p.translate(point1.x + delta, point1.y);
pot.setControlPoint(p, j);
}
} else if (y1Attr < y2Attr) {
pot.setOrientation(Orientation._90);
for (int j = 0; j < pot.getControlPointCount(); j++) {
Point p = new Point(pot.getControlPoint(j));
p.translate(point1.x, point1.y - delta);
pot.setControlPoint(p, j);
}
} else if (y1Attr > y2Attr) {
pot.setOrientation(Orientation._270);
for (int j = 0; j < pot.getControlPointCount(); j++) {
Point p = new Point(pot.getControlPoint(j));
p.translate(point1.x, point1.y + delta);
pot.setControlPoint(p, j);
}
;
}
component = pot;
} else {
String message = "Could not recognize component type " + nodeName;
LOG.debug(message);
@@ -403,6 +484,12 @@ public class ProjectFileManager {
}
}
if (component != null) {
if (component instanceof AbstractLeadedComponent<?>) {
((AbstractLeadedComponent<?>) component).setDisplay(Display.NAME);
}
if (component instanceof AbstractTransparentComponent<?>) {
((AbstractTransparentComponent<?>) component).setAlpha((byte) 100);
}
project.getComponents().add(component);
}
}
@@ -419,6 +506,18 @@ public class ProjectFileManager {
return point;
}
private Color parseV1Color(String color) {
if ("brown".equals(color.toLowerCase()))
return new Color(139, 69, 19);
try {
Field field = Color.class.getDeclaredField(color.toLowerCase());
return (Color) field.get(null);
} catch (Exception e) {
LOG.error("Could not parse color \"" + color + "\"", e);
return Color.black;
}
}
private Project parseV2File(Element root) {
Project project = new Project();
String projectName = root.getAttribute("projectName");
@@ -443,7 +542,8 @@ public class ProjectFileManager {
Project project;
FileInputStream fis = new FileInputStream(fileName);
try {
project = (Project) xStream.fromXML(fis);
Reader reader = new InputStreamReader(fis, "UTF-8");
project = (Project) xStream.fromXML(reader);
} catch (Exception e) {
LOG.warn("Could not open with the new xStream, trying the old one");
fis.close();
+13 -1
View File
@@ -2,17 +2,23 @@ package org.diylc.utils;
public class BomEntry {
private String type;
private String name;
private String value;
private Integer quantity;
private String notes;
public BomEntry(String name, String value, int quantity) {
public BomEntry(String type, String name, String value, int quantity) {
super();
this.type = type;
this.name = name;
this.value = value;
this.quantity = quantity;
}
public String getType() {
return type;
}
public String getName() {
return name;
@@ -50,6 +56,7 @@ public class BomEntry {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((notes == null) ? 0 : notes.hashCode());
result = prime * result + quantity;
@@ -66,6 +73,11 @@ public class BomEntry {
if (getClass() != obj.getClass())
return false;
BomEntry other = (BomEntry) obj;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
if (name == null) {
if (other.name != null)
return false;
+18 -3
View File
@@ -7,7 +7,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.diylc.common.ComponentType;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.presenter.ComponentProcessor;
public class BomMaker {
@@ -26,15 +29,27 @@ public class BomMaker {
public List<BomEntry> createBom(List<IDIYComponent<?>> components) {
Map<String, BomEntry> entryMap = new HashMap<String, BomEntry>();
for (IDIYComponent<?> component : components) {
ComponentType type = ComponentProcessor.getInstance()
.extractComponentTypeFrom(
(Class<? extends IDIYComponent<?>>) component
.getClass());
if (type.getBomPolicy() == BomPolicy.NEVER_SHOW)
continue;
String name = component.getName();
String value = component.getValue() == null ? null : component.getValue().toString();
String value = component.getValue() == null ? null : component
.getValue().toString();
if ((name != null) && (value != null)) {
String key = name + "|" + value;
String key = type.getName() + "|" + value;
if (entryMap.containsKey(key)) {
BomEntry entry = entryMap.get(key);
entry.setQuantity(entry.getQuantity() + 1);
if (type.getBomPolicy() == BomPolicy.SHOW_ALL_NAMES) {
entry.setName(entry.getName() + ", " + name);
}
} else {
entryMap.put(key, new BomEntry(name, value, 1));
entryMap.put(key, new BomEntry(type.getName(), type
.getBomPolicy() == BomPolicy.SHOW_ALL_NAMES ? name
: type.getName(), value, 1));
}
}
}
@@ -19,7 +19,7 @@ import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Mock", author = "bancika", category = "Sample", instanceNamePrefix = "M", description = "test", zOrder = IDIYComponent.COMPONENT)
public class MockDIYComponent implements IDIYComponent<Capacitance> {
public class MockDIYComponent extends AbstractComponent<Capacitance> {
private static final long serialVersionUID = 1L;
+1 -1
View File
@@ -4,7 +4,7 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/xstream-1.3.1.jar"/>
<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="lib/app-framework.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/diylc-core"/>
<classpathentry combineaccessrules="false" kind="src" path="/app-framework"/>
<classpathentry kind="output" path="bin"/>
</classpath>
+2 -2
View File
@@ -16,7 +16,7 @@
<target name="compile">
<mkdir dir="${classes.dir}" />
<echo>Compile with JDK ${java.runtime.version}</echo>
<javac encoding="8859_1" srcdir="${basedir}/${src.dir}" destdir="${classes.dir}" classpathref="class.path" />
<javac encoding="8859_1" srcdir="${basedir}/${src.dir}" destdir="${classes.dir}" classpathref="class.path" debug="true" />
</target>
<target name="resource.copy">
@@ -46,7 +46,7 @@
<target name="jar" depends="clean, lib.copy, resource.copy, compile">
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}" />
<copy todir="../DIYLC/library" overwrite="true">
<copy todir="../diylc-swing/library" overwrite="true">
<fileset dir="${jar.dir}" includes="${ant.project.name}.jar" />
</copy>
</target>
Binary file not shown.
Binary file not shown.
@@ -6,7 +6,9 @@ import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDrawingObserver;
@@ -22,6 +24,8 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
public static Color BOARD_COLOR = Color.decode("#F8EBB3");
public static Color BORDER_COLOR = BOARD_COLOR.darker();
public static Color COORDINATE_COLOR = Color.gray.brighter();
public static float COORDINATE_FONT_SIZE = 9f;
public static Size DEFAULT_WIDTH = new Size(1.5d, SizeUnit.in);
public static Size DEFAULT_HEIGHT = new Size(1.2d, SizeUnit.in);
@@ -34,10 +38,12 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
protected Color boardColor = BOARD_COLOR;
protected Color borderColor = BORDER_COLOR;
protected Color coordinateColor = COORDINATE_COLOR;
protected Boolean drawCoordinates = true;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) {
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
@@ -59,6 +65,44 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
drawingObserver.stopTracking();
}
protected void drawCoordinates(Graphics2D g2d, int spacing) {
if (!getDrawCoordinates())
return;
Point p = new Point(firstPoint);
g2d.setColor(coordinateColor);
g2d.setFont(LABEL_FONT.deriveFont(COORDINATE_FONT_SIZE));
int t = 1;
while (p.y < secondPoint.y - spacing) {
p.y += spacing;
super.drawCenteredText(g2d, getCoordinateLabel(t++), p.x + 2, p.y,
HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
}
p = new Point(firstPoint);
t = 1;
while (p.x < secondPoint.x - spacing) {
p.x += spacing;
super.drawCenteredText(g2d, getCoordinateLabel(t++), p.x, p.y - 2,
HorizontalAlignment.CENTER, VerticalAlignment.TOP);
}
}
private String getCoordinateLabel(int coordinate) {
String result = "";
while (coordinate > 0) {
int digit = coordinate % 26;
coordinate /= 26;
if (digit == 0) {
result = 'Z' + result;
coordinate--;
} else {
result = (char) ((int) 'A' + digit - 1) + result;
}
}
return result;
}
@EditableProperty(name = "Color")
public Color getBoardColor() {
return boardColor;
@@ -68,6 +112,16 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
this.boardColor = boardColor;
}
@EditableProperty(name = "Coordinate Color")
public Color getCoordinateColor() {
// Null protection for older files
return coordinateColor == null ? COORDINATE_COLOR : coordinateColor;
}
public void setCoordinateColor(Color coordinateColor) {
this.coordinateColor = coordinateColor;
}
@EditableProperty(name = "Border")
public Color getBorderColor() {
return borderColor;
@@ -77,6 +131,16 @@ public abstract class AbstractBoard extends AbstractTransparentComponent<String>
this.borderColor = borderColor;
}
@EditableProperty(name = "Draw Coordinates")
public boolean getDrawCoordinates() {
// Null protection for older files
return drawCoordinates == null || drawCoordinates;
}
public void setDrawCoordinates(boolean drawCoordinates) {
this.drawCoordinates = drawCoordinates;
}
@Override
public int getControlPointCount() {
return controlPoints.length;
@@ -3,9 +3,10 @@ package org.diylc.components.boards;
import java.awt.Graphics2D;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
@ComponentDescriptor(name = "Blank Board", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Blank circuit board")
@ComponentDescriptor(name = "Blank Board", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Blank circuit board", bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME)
public class BlankBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
@@ -17,4 +18,10 @@ public class BlankBoard extends AbstractBoard {
g2d.setColor(BORDER_COLOR);
g2d.drawRect(2, 2, width - 4, height - 4);
}
@Override
public boolean getDrawCoordinates() {
// Override to prevent editing.
return super.getDrawCoordinates();
}
}
@@ -10,13 +10,14 @@ import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Eyelet Board", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated board with eyelets")
@ComponentDescriptor(name = "Eyelet Board", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated board with eyelets", bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME)
public class EyeletBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
@@ -75,6 +76,7 @@ public class EyeletBoard extends AbstractBoard {
holeDiameter);
}
}
super.drawCoordinates(g2d, spacing);
}
}
@@ -10,13 +10,14 @@ import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Marshall Style Perf Board", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated board as found on some Marshall and Trainwreck amps")
@ComponentDescriptor(name = "Marshall Style Perf Board", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated board as found on some Marshall and Trainwreck amps", bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME)
public class MarshallPerfBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
@@ -66,6 +67,7 @@ public class MarshallPerfBoard extends AbstractBoard {
holeDiameter);
}
}
super.drawCoordinates(g2d, spacing);
}
}
@@ -10,13 +10,14 @@ import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Perf Board w/ Pads", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated board with solder pads")
@ComponentDescriptor(name = "Perf Board w/ Pads", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated board with solder pads", bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME)
public class PerfBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
@@ -67,6 +68,7 @@ public class PerfBoard extends AbstractBoard {
holeDiameter);
}
}
super.drawCoordinates(g2d, spacing);
}
}
@@ -12,13 +12,14 @@ import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Vero Board", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated FR4 board with copper strips connecting all holes in a row")
@ComponentDescriptor(name = "Vero Board", category = "Boards", author = "Branislav Stojkovic", zOrder = IDIYComponent.BOARD, instanceNamePrefix = "Board", description = "Perforated FR4 board with copper strips connecting all holes in a row", bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME)
public class VeroBoard extends AbstractBoard {
private static final long serialVersionUID = 1L;
@@ -92,6 +93,7 @@ public class VeroBoard extends AbstractBoard {
}
}
g2d.setComposite(oldComposite);
super.drawCoordinates(g2d, spacing);
}
}
@@ -10,12 +10,13 @@ import org.diylc.core.ComponentState;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Copper Trace", author = "Branislav Stojkovic", category = "Connectivity", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "Trace", description = "Straight copper trace", zOrder = IDIYComponent.TRACE)
@ComponentDescriptor(name = "Copper Trace", author = "Branislav Stojkovic", category = "Connectivity", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "Trace", description = "Straight copper trace", zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW)
public class CopperTrace extends AbstractLeadedComponent<Void> {
private static final long serialVersionUID = 1L;
@@ -8,12 +8,13 @@ import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractCurvedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Curved Trace", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "Trace", description = "Curved copper trace with two control points", zOrder = IDIYComponent.TRACE)
@ComponentDescriptor(name = "Curved Trace", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "Trace", description = "Curved copper trace with two control points", zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW)
public class CurvedTrace extends AbstractCurvedComponent<Void> {
private static final long serialVersionUID = 1L;
@@ -10,13 +10,14 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Eyelet", category = "Connectivity", author = "Branislav Stojkovic", description = "Eyelet or turret terminal", instanceNamePrefix = "Eyelet", stretchable = false, zOrder = IDIYComponent.TRACE + 0.1)
@ComponentDescriptor(name = "Eyelet", category = "Connectivity", author = "Branislav Stojkovic", description = "Eyelet or turret terminal", instanceNamePrefix = "Eyelet", stretchable = false, zOrder = IDIYComponent.TRACE + 0.1, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME)
public class Eyelet extends AbstractComponent<String> {
private static final long serialVersionUID = 1L;
@@ -8,11 +8,12 @@ import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractCurvedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Hookup Wire", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "W", description = "Flexible wire with two control points", zOrder = IDIYComponent.COMPONENT)
@ComponentDescriptor(name = "Hookup Wire", author = "Branislav Stojkovic", category = "Connectivity", instanceNamePrefix = "W", description = "Flexible wire with two control points", zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.NEVER_SHOW)
public class HookupWire extends AbstractCurvedComponent<Void> {
private static final long serialVersionUID = 1L;
@@ -28,17 +29,21 @@ public class HookupWire extends AbstractCurvedComponent<Void> {
}
@Override
protected void drawCurve(CubicCurve2D curve, Graphics2D g2d, ComponentState componentState) {
int thickness = (int) (Math.pow(Math.E, -1.12436 - 0.11594 * gauge.getValue())
protected void drawCurve(CubicCurve2D curve, Graphics2D g2d,
ComponentState componentState) {
int thickness = (int) (Math.pow(Math.E, -1.12436 - 0.11594
* gauge.getValue())
* Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT));
Color curveColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : color.darker();
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color.darker();
g2d.setColor(curveColor);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness));
g2d.draw(curve);
if (componentState == ComponentState.NORMAL) {
g2d.setColor(color);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness - 2));
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(
thickness - 2));
g2d.draw(curve);
}
}
@@ -9,11 +9,12 @@ import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
@ComponentDescriptor(name = "Jumper", author = "Branislav Stojkovic", category = "Connectivity", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "J", description = "", zOrder = IDIYComponent.COMPONENT)
@ComponentDescriptor(name = "Jumper", author = "Branislav Stojkovic", category = "Connectivity", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "J", description = "", zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.NEVER_SHOW)
public class Jumper extends AbstractLeadedComponent<Void> {
private static final long serialVersionUID = 1L;
@@ -0,0 +1,106 @@
package org.diylc.components.connectivity;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
@ComponentDescriptor(name = "Line", author = "Branislav Stojkovic", category = "Connectivity", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "LN", description = "", zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.NEVER_SHOW)
public class Line extends AbstractLeadedComponent<Void> {
private static final long serialVersionUID = 1L;
public static Color COLOR = Color.black;
private Color color = COLOR;
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.setColor(COLOR);
g2d.drawLine(1, height - 2, width - 2, 1);
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.setColor(color);
g2d.drawLine(getControlPoint(0).x, getControlPoint(0).y, getControlPoint(1).x,
getControlPoint(1).y);
}
@Override
public Color getLeadColor(ComponentState componentState) {
return componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : color;
}
@EditableProperty
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public Color getBodyColor() {
return super.getBodyColor();
}
@Override
public Color getBorderColor() {
return super.getBorderColor();
}
@Override
public Byte getAlpha() {
return super.getAlpha();
}
@Override
public Size getLength() {
return super.getLength();
}
@Override
public Size getWidth() {
return super.getWidth();
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {
}
@Override
protected Shape getBodyShape() {
return null;
}
@Override
protected Size getDefaultWidth() {
return null;
}
@Override
protected Size getDefaultLength() {
return null;
}
}
@@ -10,13 +10,14 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Solder Pad", category = "Connectivity", author = "Branislav Stojkovic", description = "test", instanceNamePrefix = "Pad", stretchable = false, zOrder = IDIYComponent.TRACE + 0.1)
@ComponentDescriptor(name = "Solder Pad", category = "Connectivity", author = "Branislav Stojkovic", description = "test", instanceNamePrefix = "Pad", stretchable = false, zOrder = IDIYComponent.TRACE + 0.1, bomPolicy = BomPolicy.NEVER_SHOW)
public class SolderPad extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L;
@@ -11,12 +11,13 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Trace Cut", category = "Connectivity", author = "Branislav Stojkovic", description = "Designates the place where a trace on the vero board needs to be cut", instanceNamePrefix = "Cut", stretchable = false, zOrder = IDIYComponent.BOARD + 1)
@ComponentDescriptor(name = "Trace Cut", category = "Connectivity", author = "Branislav Stojkovic", description = "Designates the place where a trace on the vero board needs to be cut", instanceNamePrefix = "Cut", stretchable = false, zOrder = IDIYComponent.BOARD + 1, bomPolicy = BomPolicy.NEVER_SHOW)
public class TraceCut extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L;
@@ -0,0 +1,252 @@
package org.diylc.components.electromechanical;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "9V Battery Snap", category = "Electromechanical", author = "Branislav Stojkovic", description = "", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "BTR")
public class BatterySnap9V extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private static Color BODY_COLOR = Color.darkGray;
private static Size WIDTH = new Size(0.5d, SizeUnit.in);
private static Size LENGTH = new Size(0.75d, SizeUnit.in);
private static Size TERMINAL_DIAMETER = new Size(0.3d, SizeUnit.in);
private static Size TERMINAL_SPACING = new Size(0.5d, SizeUnit.in);
private static Size TERMINAL_BORDER = new Size(0.7d, SizeUnit.mm);
private String value = "";
private Point controlPoint = new Point(0, 0);
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private Color color = BODY_COLOR;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
Shape[] body = getBody();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
/ MAX_ALPHA));
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : color);
g2d.fill(body[0]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : METAL_COLOR);
g2d.fill(body[1]);
g2d.fill(body[2]);
g2d.setComposite(oldComposite);
}
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : color
.brighter();
}
g2d.setColor(finalBorderColor);
g2d.draw(body[0]);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(body[1]);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(body[2]);
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[3];
int x = controlPoint.x;
int y = controlPoint.y;
int width = (int) WIDTH.convertToPixels();
int length = (int) LENGTH.convertToPixels();
int totalLength = length + width / 2;
int terminalDiameter = (int) TERMINAL_DIAMETER.convertToPixels();
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
int terminalBorder = (int) TERMINAL_BORDER.convertToPixels();
Area mainArea = new Area(new Rectangle2D.Double(x, y - width / 2, length, width));
mainArea.add(new Area(new Ellipse2D.Double(x + length - width / 2, y - width / 2,
width, width)));
body[0] = mainArea;
Area terminalArea = new Area(new Ellipse2D.Double(x + (totalLength - terminalSpacing)
/ 2 - terminalDiameter / 2, y - terminalDiameter / 2, terminalDiameter,
terminalDiameter));
int centerX = x + (totalLength + terminalSpacing) / 2;
int[] terminalX = new int[6];
int[] terminalY = new int[6];
for (int i = 0; i < 6; i++) {
terminalX[i] = (int) (centerX + Math.cos(Math.PI / 3 * i) * terminalDiameter / 2);
terminalY[i] = (int) (y + Math.sin(Math.PI / 3 * i) * terminalDiameter / 2);
}
terminalArea.add(new Area(new Polygon(terminalX, terminalY, 6)));
body[1] = terminalArea;
terminalArea = new Area(new Ellipse2D.Double(x + (totalLength - terminalSpacing) / 2
- terminalDiameter / 2 + terminalBorder, y - terminalDiameter / 2
+ terminalBorder, terminalDiameter - 2 * terminalBorder, terminalDiameter - 2
* terminalBorder));
for (int i = 0; i < 6; i++) {
terminalX[i] = (int) (centerX + Math.cos(Math.PI / 3 * i)
* (terminalDiameter / 2 + terminalBorder));
terminalY[i] = (int) (y + Math.sin(Math.PI / 3 * i)
* (terminalDiameter / 2 + terminalBorder));
}
terminalArea.add(new Area(new Polygon(terminalX, terminalY, 6)));
body[2] = terminalArea;
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
double theta = 0;
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
for (Shape shape : body) {
Area area = (Area) shape;
area.transform(rotation);
}
}
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(BODY_COLOR);
g2d.fillOval(width / 4, width / 32, width / 2, width / 2);
g2d.setColor(BODY_COLOR.darker());
g2d.drawOval(width / 4, width / 32, width / 2, width / 2);
g2d.setColor(BODY_COLOR);
g2d.fillRect(width / 4, width / 32 + width / 4, width / 2, width * 3 / 4 - 2 * width / 32);
g2d.setColor(BODY_COLOR.darker());
g2d.drawRect(width / 4, width / 32 + width / 4, width / 2, width * 3 / 4 - 2 * width / 32);
g2d.setColor(METAL_COLOR);
g2d.fillOval(width / 4 + 3 * width / 32, width / 32 + 3 * width / 32, width / 2 - 6 * width
/ 32, width / 2 - 6 * width / 32);
int centerX = width / 2;
int centerY = height * 7 / 9;
int terminalDiameter = width / 2 - 4 * width / 32;
int[] terminalX = new int[6];
int[] terminalY = new int[6];
for (int i = 0; i < 6; i++) {
terminalX[i] = (int) (centerX + Math.cos(Math.PI / 3 * i) * terminalDiameter / 2);
terminalY[i] = (int) (centerY + Math.sin(Math.PI / 3 * i) * terminalDiameter / 2);
}
g2d.fillPolygon(terminalX, terminalY, 6);
g2d.setColor(METAL_COLOR.darker());
g2d.drawOval(width / 4 + 3 * width / 32, width / 32 + 3 * width / 32, width / 2 - 6 * width
/ 32, width / 2 - 6 * width / 32);
g2d.drawPolygon(terminalX, terminalY, 6);
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public Point getControlPoint(int index) {
return controlPoint;
}
@Override
public void setControlPoint(Point point, int index) {
this.controlPoint.setLocation(point);
// Invalidate the body
body = null;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
// Invalidate the body
body = null;
}
@EditableProperty
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
@@ -0,0 +1,331 @@
package org.diylc.components.electromechanical;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Cliff 1/4\" Jack", category = "Electromechanical", author = "Branislav Stojkovic", description = "Cliff-style closed panel mount 1/4\" phono jack", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J")
public class CliffJack1_4 extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private static Size SPACING = new Size(0.3d, SizeUnit.in);
private static Size PIN_WIDTH = new Size(0.1d, SizeUnit.in);
private static Size PIN_THICKNESS = new Size(0.02d, SizeUnit.in);
private static Color BODY_COLOR = Color.decode("#666666");
private static Color NUT_COLOR = Color.decode("#999999");
private static Color BORDER_COLOR = Color.black;
private static Color LABEL_COLOR = Color.white;
private static Size BODY_WIDTH = new Size(3/4d, SizeUnit.in);
private static Size BODY_LENGTH = new Size(0.9d, SizeUnit.in);
private static Size TAIL_LENGTH = new Size(0.1d, SizeUnit.in);
private Point[] controlPoints = new Point[] { new Point(0, 0) };
private JackType type = JackType.MONO;
private Orientation orientation = Orientation.DEFAULT;
transient private Shape[] body;
private String value = "";
public CliffJack1_4() {
super();
updateControlPoints();
}
private void updateControlPoints() {
// invalidate body shape
body = null;
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int spacing = (int) SPACING.convertToPixels();
controlPoints = new Point[type == JackType.STEREO ? 6 : 4];
controlPoints[0] = new Point(x, y);
controlPoints[1] = new Point(x, y + 2 * spacing);
controlPoints[2] = new Point(x + 2 * spacing, y);
controlPoints[3] = new Point(x + 2 * spacing, y + 2 * spacing);
if (type == JackType.STEREO) {
controlPoints[4] = new Point(x + spacing, y);
controlPoints[5] = new Point(x + spacing, y + 2 * spacing);
}
// Apply rotation if necessary
double angle = getAngle();
if (angle != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(angle, x, y);
for (int i = 1; i < controlPoints.length; i++) {
rotation.transform(controlPoints[i], controlPoints[i]);
}
}
}
private double getAngle() {
// Apply rotation if necessary
double angle;
switch (orientation) {
case _90:
angle = Math.PI / 2;
break;
case _180:
angle = Math.PI;
break;
case _270:
angle = Math.PI * 3 / 2;
break;
default:
angle = 0;
}
return angle;
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[5];
// Create body.
int bodyLength = (int) BODY_LENGTH.convertToPixels();
int bodyWidth = (int) BODY_WIDTH.convertToPixels();
int centerX = (controlPoints[0].x + controlPoints[3].x) / 2;
int centerY = (controlPoints[0].y + controlPoints[3].y) / 2;
body[0] = new Rectangle(centerX - bodyLength / 2, centerY - bodyWidth / 2, bodyLength,
bodyWidth);
int tailLength = (int) TAIL_LENGTH.convertToPixels();
body[1] = new RoundRectangle2D.Double(centerX - bodyLength / 2 - tailLength, centerY
- bodyWidth / 4, tailLength * 2, bodyWidth / 2, tailLength, tailLength);
Area tailArea = new Area(body[1]);
tailArea.subtract(new Area(body[0]));
body[1] = tailArea;
body[2] = new Rectangle(centerX + bodyLength / 2, centerY - bodyWidth / 4, tailLength,
bodyWidth / 2);
body[3] = new Rectangle(centerX + bodyLength / 2 + tailLength, centerY - bodyWidth / 4,
tailLength, bodyWidth / 2);
tailArea = new Area(body[3]);
int radius = bodyLength / 2 + tailLength * 2;
tailArea.intersect(new Area(new Ellipse2D.Double(centerX - radius, centerY - radius,
radius * 2, radius * 2)));
body[3] = tailArea;
// Apply rotation if necessary
double angle = getAngle();
if (angle != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(angle, centerX,
centerY);
for (int i = 0; i < body.length; i++) {
if (body[i] != null) {
Area area = new Area(body[i]);
area.transform(rotation);
body[i] = area;
}
}
}
// Create pins.
Area pins = new Area();
int pinWidth = (int) PIN_WIDTH.convertToPixels();
int pinThickness = (int) PIN_THICKNESS.convertToPixels();
for (int i = 0; i < getControlPointCount(); i++) {
Point point = getControlPoint(i);
Rectangle pin;
if (orientation == Orientation.DEFAULT || orientation == Orientation._180) {
pin = new Rectangle(point.x - pinWidth / 2, point.y - pinThickness / 2,
pinWidth, pinThickness);
} else {
pin = new Rectangle(point.x - pinThickness / 2, point.y - pinWidth / 2,
pinThickness, pinWidth);
}
pins.add(new Area(pin));
}
body[4] = pins;
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
Shape[] body = getBody();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
/ MAX_ALPHA));
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BODY_COLOR);
for (int i = 0; i < body.length - 1; i++) {
// Nut is brighter colored.
if (i == body.length - 2)
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : NUT_COLOR);
g2d.fill(body[i]);
}
g2d.setComposite(oldComposite);
}
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: BORDER_COLOR;
}
g2d.setColor(finalBorderColor);
for (int i = 0; i < body.length - 1; i++) {
g2d.draw(body[i]);
}
// Pins are the last piece.
Shape pins = body[body.length - 1];
g2d.setColor(METAL_COLOR);
g2d.fill(pins);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(pins);
Color finalLabelColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
.getOutlineColor();
} else {
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
g2d.setFont(LABEL_FONT);
int centerX = (controlPoints[0].x + controlPoints[3].x) / 2;
int centerY = (controlPoints[0].y + controlPoints[3].y) / 2;
drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int bodyWidth = getClosestOdd(width * 3 / 5);
int tailWidth = getClosestOdd(width * 3 / 9);
g2d.setColor(BODY_COLOR);
g2d.fillRoundRect((width - tailWidth) / 2, height / 2, tailWidth, height / 2 - 2 * 32
/ height, 4 * 32 / width, 4 * 32 / width);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect((width - tailWidth) / 2, height / 2, tailWidth, height / 2 - 2 * 32
/ height, 4 * 32 / width, 4 * 32 / width);
g2d.setColor(NUT_COLOR);
g2d.fillRoundRect((width - tailWidth) / 2, 2 * 32 / height, tailWidth, height / 2,
4 * 32 / width, 4 * 32 / width);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect((width - tailWidth) / 2, 2 * 32 / height, tailWidth, height / 2,
4 * 32 / width, 4 * 32 / width);
g2d.setColor(BODY_COLOR);
g2d.fillRect((width - bodyWidth) / 2, height / 7 + 1, bodyWidth, height * 5 / 7);
g2d.setColor(BORDER_COLOR);
g2d.drawRect((width - bodyWidth) / 2, height / 7 + 1, bodyWidth, height * 5 / 7);
g2d.setColor(METAL_COLOR);
int pinX1 = getClosestOdd((width - bodyWidth * 3 / 4) / 2);
int pinX2 = getClosestOdd((width + bodyWidth * 3 / 4) / 2) - 1;
g2d.drawLine(pinX1, width * 2 / 8, pinX1, width * 3 / 8);
g2d.drawLine(pinX1, width * 5 / 8, pinX1, width * 6 / 8);
g2d.drawLine(pinX2, width * 2 / 8, pinX2, width * 3 / 8);
g2d.drawLine(pinX2, width * 5 / 8, pinX2, width * 6 / 8);
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@EditableProperty
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public JackType getType() {
return type;
}
public void setType(JackType type) {
this.type = type;
updateControlPoints();
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
}
}
@@ -0,0 +1,338 @@
package org.diylc.components.electromechanical;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Closed 1/4\" Jack", category = "Electromechanical", author = "Branislav Stojkovic", description = "Enclosed panel mount 1/4\" phono jack", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J")
public class ClosedJack1_4 extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private static Size SPACING = new Size(0.1d, SizeUnit.in);
private static Size LUG_WIDTH = new Size(0.1d, SizeUnit.in);
private static Size LUG_LENGTH = new Size(0.12d, SizeUnit.in);
private static Size LUG_HOLE_SIZE = new Size(1d, SizeUnit.mm);
private static Color BODY_COLOR = Color.decode("#666666");
private static Color SHAFT_COLOR = Color.decode("#AAAAAA");
private static Size SHAFT_LENGTH = new Size(0.25d, SizeUnit.in);
private static Size SHAFT_WIDTH = new Size(3d / 8, SizeUnit.in);
private static Color BORDER_COLOR = Color.black;
private static Color LABEL_COLOR = Color.white;
private static Size BODY_WIDTH = new Size(0.65d, SizeUnit.in);
private static Size BODY_LENGTH = new Size(0.8d, SizeUnit.in);
private Point[] controlPoints = new Point[] { new Point(0, 0) };
private JackType type = JackType.MONO;
private Orientation orientation = Orientation.DEFAULT;
transient private Shape[] body;
private String value = "";
public ClosedJack1_4() {
super();
updateControlPoints();
}
private void updateControlPoints() {
// invalidate body shape
body = null;
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int spacing = (int) SPACING.convertToPixels();
int bodyLength = (int) BODY_LENGTH.convertToPixels();
controlPoints = new Point[type == JackType.STEREO ? 3 : 2];
controlPoints[0] = new Point(x, y);
controlPoints[1] = new Point(x + bodyLength, y);
if (type == JackType.STEREO) {
controlPoints[2] = new Point(x, y + 2 * spacing);
}
// Apply rotation if necessary
double angle = getAngle();
if (angle != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(angle, x, y);
for (int i = 1; i < controlPoints.length; i++) {
rotation.transform(controlPoints[i], controlPoints[i]);
}
}
}
private double getAngle() {
// Apply rotation if necessary
double angle;
switch (orientation) {
case _90:
angle = Math.PI / 2;
break;
case _180:
angle = Math.PI;
break;
case _270:
angle = Math.PI * 3 / 2;
break;
default:
angle = 0;
}
return angle;
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[5];
// Create body.
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int lugWidth = (int) LUG_WIDTH.convertToPixels();
int lugLength = (int) LUG_LENGTH.convertToPixels();
int lugHoleSize = (int) LUG_HOLE_SIZE.convertToPixels();
int bodyLength = (int) BODY_LENGTH.convertToPixels();
int bodyWidth = (int) BODY_WIDTH.convertToPixels();
body[0] = new Area(new Rectangle(x + lugLength, y - bodyWidth / 2, bodyLength,
bodyWidth));
int shaftLength = (int) SHAFT_LENGTH.convertToPixels();
int shaftWidth = (int) SHAFT_WIDTH.convertToPixels();
Area shaft = new Area(new Rectangle(x + lugLength + bodyLength, y - shaftWidth / 2,
shaftLength, shaftWidth));
body[1] = shaft;
double angle = getAngle();
AffineTransform rotation = null;
if (angle != 0) {
rotation = AffineTransform.getRotateInstance(angle, x, y);
}
GeneralPath path = new GeneralPath();
int step = 4;
for (int i = x + lugLength + bodyLength + step; i <= x + lugLength + bodyLength
+ shaftLength; i += step) {
Point p = new Point(i, y - shaftWidth / 2 + 1);
if (rotation != null) {
rotation.transform(p, p);
}
path.moveTo(p.x, p.y);
p = new Point(i - step, y + shaftWidth / 2 - 1);
if (rotation != null) {
rotation.transform(p, p);
}
path.lineTo(p.x, p.y);
}
Area pathArea = new Area(path);
pathArea.intersect(shaft);
body[2] = path;
// Create lugs.
Area lugs = new Area();
int spacing = (int) SPACING.convertToPixels();
Point[] untransformedControlPoints = new Point[type == JackType.STEREO ? 3 : 2];
untransformedControlPoints[0] = new Point(x, y);
untransformedControlPoints[1] = new Point(x + bodyLength, y);
if (type == JackType.STEREO) {
untransformedControlPoints[2] = new Point(x, y + 2 * spacing);
}
for (int i = 0; i < untransformedControlPoints.length; i++) {
Point point = untransformedControlPoints[i];
Area lug = new Area(new Ellipse2D.Double(point.x - lugWidth / 2, point.y - lugWidth
/ 2, lugWidth, lugWidth));
lug.add(new Area(
new Rectangle(point.x, point.y - lugWidth / 2, lugLength, lugWidth)));
lug.subtract(new Area(new Ellipse2D.Double(point.x - lugHoleSize / 2, point.y
- lugHoleSize / 2, lugHoleSize, lugHoleSize)));
lugs.add(lug);
}
body[3] = lugs;
// Rotate everything that's of Area type, e.g. everything but lines.
if (rotation != null) {
for (Shape shape : body) {
if (shape instanceof Area) {
Area area = (Area) shape;
area.transform(rotation);
}
}
}
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
Shape[] body = getBody();
// Rectangle bounds = body.getBounds();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
/ MAX_ALPHA));
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BODY_COLOR);
g2d.fill(body[0]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : SHAFT_COLOR);
g2d.fill(body[1]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : METAL_COLOR);
g2d.fill(body[3]);
g2d.setComposite(oldComposite);
}
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : BORDER_COLOR;
}
g2d.setColor(finalBorderColor);
g2d.draw(body[0]);
g2d.draw(body[1]);
if (!outlineMode) {
g2d.setColor(SHAFT_COLOR.darker());
g2d.fill(body[2]);
g2d.draw(body[2]);
}
// Pins are the last piece.
g2d.setColor(outlineMode ? finalBorderColor : METAL_COLOR.darker());
g2d.draw(body[3]);
Color finalLabelColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
.getOutlineColor();
} else {
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
g2d.setFont(LABEL_FONT);
Rectangle bounds = body[0].getBounds();
int centerX = bounds.x + bounds.width / 2;
int centerY = bounds.y + bounds.height / 2;
drawCenteredText(g2d, name, centerX, centerY, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int bodyWidth = getClosestOdd(width * 3 / 5);
int tailWidth = getClosestOdd(width * 3 / 10);
g2d.setColor(SHAFT_COLOR);
g2d.fillRect((width - tailWidth) / 2, 1, tailWidth, height / 2);
g2d.setColor(BORDER_COLOR);
g2d.drawRect((width - tailWidth) / 2, 1, tailWidth, height / 2);
g2d.setColor(BODY_COLOR);
g2d.fillRect((width - bodyWidth) / 2, height / 7 + 1, bodyWidth, height * 5 / 7);
g2d.setColor(BORDER_COLOR);
g2d.drawRect((width - bodyWidth) / 2, height / 7 + 1, bodyWidth, height * 5 / 7);
g2d.setColor(METAL_COLOR);
g2d.fillRect(width * 7 / 16, height * 6 / 7 + 1, width / 8, height / 7 - 1);
g2d.fillRect(width * 7 / 16, height / 7 + 2, width / 8, height / 7 - 1);
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@EditableProperty
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public JackType getType() {
return type;
}
public void setType(JackType type) {
this.type = type;
updateControlPoints();
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
}
}
@@ -0,0 +1,17 @@
package org.diylc.components.electromechanical;
public enum DCPolarity {
NONE("None"), CENTER_POSITIVE("Center Positive"), CENTER_NEGATIVE("Center Negative");
private String title;
private DCPolarity(String title) {
this.title = title;
}
@Override
public String toString() {
return title;
}
}
@@ -0,0 +1,11 @@
package org.diylc.components.electromechanical;
public enum JackType {
MONO, STEREO;
@Override
public String toString() {
return name().substring(0, 1) + name().substring(1).toLowerCase();
}
}
@@ -33,12 +33,11 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
private static Size MARGIN = new Size(0.08d, SizeUnit.in);
private static Size CIRCLE_SIZE = new Size(0.09d, SizeUnit.in);
private static Size LUG_WIDTH = new Size(0.060d, SizeUnit.in);
private static Size LUG_HEIGHT = new Size(0.03d, SizeUnit.in);
private static Size LUG_THICKNESS = new Size(0.02d, SizeUnit.in);
private static Color BODY_COLOR = Color.decode("#3299CC");
private static Color BORDER_COLOR = BODY_COLOR.darker();
private static Color CIRCLE_COLOR = Color.red;
private static Color LUG_COLOR = Color.decode("#00B2EE");
private static Color CIRCLE_COLOR = Color.decode("#FFFFAA");
protected Point[] controlPoints = new Point[] { new Point(0, 0) };
transient protected RoundRectangle2D body;
@@ -205,17 +204,17 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
// so far.
drawingObserver.stopTracking();
// Draw lugs.
if (!outlineMode) {
int circleDiameter = getClosestOdd((int) CIRCLE_SIZE.convertToPixels());
int lugWidth = getClosestOdd((int) LUG_WIDTH.convertToPixels());
int lugHeight = getClosestOdd((int) LUG_HEIGHT.convertToPixels());
for (Point p : controlPoints) {
int circleDiameter = getClosestOdd((int) CIRCLE_SIZE.convertToPixels());
int lugWidth = getClosestOdd((int) LUG_WIDTH.convertToPixels());
int lugHeight = getClosestOdd((int) LUG_THICKNESS.convertToPixels());
for (Point p : controlPoints) {
if (!outlineMode) {
g2d.setColor(CIRCLE_COLOR);
g2d.fillOval(p.x - circleDiameter / 2, p.y - circleDiameter / 2, circleDiameter,
circleDiameter);
g2d.setColor(LUG_COLOR);
g2d.fillRect(p.x - lugWidth / 2, p.y - lugHeight / 2, lugWidth, lugHeight);
}
g2d.setColor(METAL_COLOR);
g2d.fillRect(p.x - lugWidth / 2, p.y - lugHeight / 2, lugWidth, lugHeight);
}
}
@@ -261,9 +260,12 @@ public class MiniToggleSwitch extends AbstractTransparentComponent<ToggleSwitchT
g2d.fillRoundRect(width / 4, 1, width / 2, height - 2, circleSize, circleSize);
g2d.setColor(BORDER_COLOR);
g2d.drawRoundRect(width / 4, 1, width / 2, height - 2, circleSize, circleSize);
g2d.setColor(CIRCLE_COLOR);
for (int i = 1; i <= 3; i++) {
g2d.setColor(CIRCLE_COLOR);
g2d.fillOval(width / 2 - circleSize / 2, i * height / 4 - 3, circleSize, circleSize);
g2d.setColor(METAL_COLOR);
g2d.drawLine(width / 2 - circleSize / 2 + 1, i * height / 4 - 1, width / 2 + circleSize
/ 2 - 1, i * height / 4 - 1);
}
}
}
@@ -0,0 +1,247 @@
package org.diylc.components.electromechanical;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Plastic DC Jack", category = "Electromechanical", author = "Branislav Stojkovic", description = "Panel mount plastic DC jack", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "J")
public class PlasticDCJack extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private static Size LUG_WIDTH = new Size(0.08d, SizeUnit.in);
private static Size LUG_THICKNESS = new Size(0.02d, SizeUnit.in);
private static Size SPACING = new Size(0.1d, SizeUnit.in);
private static Size DIAMETER = new Size(0.5d, SizeUnit.in);
private static Color BODY_COLOR = Color.decode("#666666");
private static Color PHENOLIC_COLOR = Color.decode("#CD8500");
private static Color BORDER_COLOR = Color.black;
private static Color MARKING_COLOR = Color.lightGray;
private Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0), new Point(0, 0) };
private String value = "";
private DCPolarity polarity = DCPolarity.CENTER_NEGATIVE;
transient private Shape[] body;
public PlasticDCJack() {
updateControlPoints();
}
private void updateControlPoints() {
// invalidate body shape
body = null;
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int spacing = (int) SPACING.convertToPixels();
controlPoints[1] = new Point(x + spacing, y + spacing);
controlPoints[2] = new Point(x - spacing, y + spacing * 2);
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[4];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int spacing = (int) SPACING.convertToPixels();
int diameter = getClosestOdd(DIAMETER.convertToPixels());
body[0] = new Ellipse2D.Double(x - diameter / 2, y + spacing - diameter / 2, diameter,
diameter);
int rectWidth = (int) (diameter / Math.sqrt(2)) - 2;
body[1] = new Rectangle(x - rectWidth / 2, y + spacing - rectWidth / 2, rectWidth,
rectWidth);
int lugWidth = getClosestOdd(LUG_WIDTH.convertToPixels());
int lugThickness = getClosestOdd(LUG_THICKNESS.convertToPixels());
Point groundPoint = controlPoints[controlPoints.length - 1];
Area groundLug = new Area(new Ellipse2D.Double(groundPoint.x + spacing - lugWidth / 2,
groundPoint.y - lugWidth / 2, lugWidth, lugWidth));
groundLug.add(new Area(new Rectangle(groundPoint.x, groundPoint.y - lugWidth / 2,
spacing, lugWidth)));
groundLug.subtract(new Area(new Ellipse2D.Double(
groundPoint.x + spacing - lugWidth / 6, groundPoint.y - lugWidth / 6,
lugWidth / 3, lugWidth / 3)));
body[2] = groundLug;
Area lugArea = new Area();
for (int i = 0; i < controlPoints.length; i++) {
Point point = controlPoints[i];
if (i == getControlPointCount() - 1) {
lugArea.add(new Area(new Rectangle(point.x - lugThickness / 2, point.y
- lugWidth / 2, lugThickness, lugWidth)));
} else {
lugArea.add(new Area(new Rectangle(point.x - lugWidth / 2, point.y
- lugThickness / 2, lugWidth, lugThickness)));
}
}
body[3] = lugArea;
}
return body;
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
Shape[] body = getBody();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
/ MAX_ALPHA));
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BODY_COLOR);
g2d.fill(body[0]);
if (!outlineMode) {
g2d.setColor(PHENOLIC_COLOR);
g2d.fill(body[1]);
}
g2d.setComposite(oldComposite);
}
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : BORDER_COLOR;
}
g2d.setColor(finalBorderColor);
g2d.draw(body[0]);
if (!outlineMode) {
g2d.setColor(PHENOLIC_COLOR.darker());
g2d.draw(body[1]);
g2d.setColor(METAL_COLOR);
g2d.fill(body[2]);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(body[2]);
}
g2d.setColor(METAL_COLOR);
g2d.fill(body[3]);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(body[3]);
if (!outlineMode && getPolarity() != DCPolarity.NONE) {
int spacing = (int) SPACING.convertToPixels();
g2d.setColor(MARKING_COLOR);
g2d.setFont(LABEL_FONT.deriveFont(12f));
drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "+" : "-",
controlPoints[0].x, controlPoints[0].y - spacing * 7 / 16,
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
drawCenteredText(g2d, getPolarity() == DCPolarity.CENTER_NEGATIVE ? "_" : "+",
controlPoints[2].x, controlPoints[2].y - spacing * 3 / 4,
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
}
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int margin = 2 * 32 / width;
int diameter = getClosestOdd(width - margin);
g2d.setColor(BODY_COLOR);
g2d.fillOval((width - diameter) / 2, (height - diameter) / 2, diameter, diameter);
g2d.setColor(BORDER_COLOR);
g2d.drawOval((width - diameter) / 2, (height - diameter) / 2, diameter, diameter);
int rectWidth = getClosestOdd(((width - 2 * margin) / Math.sqrt(2)) - margin / 2);
g2d.setColor(PHENOLIC_COLOR);
g2d.fillRect((width - rectWidth) / 2, (height - rectWidth) / 2, rectWidth, rectWidth);
g2d.setColor(PHENOLIC_COLOR.darker());
g2d.drawRect((width - rectWidth) / 2, (height - rectWidth) / 2, rectWidth, rectWidth);
int lugWidth = 4 * 32 / width;
g2d.setColor(METAL_COLOR);
g2d.drawLine((width - lugWidth) / 2, height / 3, (width + lugWidth) / 2, height / 3);
g2d
.drawLine(width * 2 / 3, (height - lugWidth) / 2, width * 2 / 3,
(height + lugWidth) / 2);
g2d.fillOval((width - lugWidth) / 2, height * 2 / 3 - lugWidth / 2, lugWidth, lugWidth);
g2d.fillRect(width / 2 - lugWidth * 3 / 2, height * 2 / 3 - lugWidth / 2, lugWidth * 3 / 2,
lugWidth);
g2d.setColor(PHENOLIC_COLOR);
g2d.fillOval((width - margin) / 2, height * 2 / 3 - margin / 2, margin, margin);
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
this.body = null;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@EditableProperty
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public DCPolarity getPolarity() {
if (polarity == null) {
polarity = DCPolarity.CENTER_NEGATIVE;
}
return polarity;
}
public void setPolarity(DCPolarity polarity) {
this.polarity = polarity;
}
}
@@ -0,0 +1,268 @@
package org.diylc.components.guitar;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Humbucker Pickup", category = "Guitar", author = "Branislav Stojkovic", description = "PAF-style humbucker guitar pickup", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "PKP")
public class HumbuckerPickup extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private static Color BODY_COLOR = Color.lightGray;
private static Color POINT_COLOR = Color.darkGray;
private static Size WIDTH = new Size(36.5d, SizeUnit.mm);
private static Size LENGTH = new Size(68.58d, SizeUnit.mm);
private static Size LIP_WIDTH = new Size(12.7d, SizeUnit.mm);
private static Size LIP_LENGTH = new Size(7.9d, SizeUnit.mm);
private static Size EDGE_RADIUS = new Size(4d, SizeUnit.mm);
private static Size POINT_MARGIN = new Size(5d, SizeUnit.mm);
private static Size POINT_SIZE = new Size(3d, SizeUnit.mm);
private static Size LIP_HOLE_SIZE = new Size(1.5d, SizeUnit.mm);
private static Size POLE_SIZE = new Size(3d, SizeUnit.mm);
private static Size POLE_SPACING = new Size(10.1d, SizeUnit.mm);
private static Size COIL_SPACING = new Size(18d, SizeUnit.mm);
private String value = "";
private Point controlPoint = new Point(0, 0);
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private Color color = BODY_COLOR;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
Shape[] body = getBody();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
/ MAX_ALPHA));
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : color);
g2d.fill(body[0]);
g2d.fill(body[1]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : POINT_COLOR);
g2d.fill(body[2]);
g2d.setComposite(oldComposite);
}
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : color.darker();
}
g2d.setColor(finalBorderColor);
g2d.draw(body[0]);
g2d.draw(body[1]);
if (!outlineMode) {
g2d.setColor(color.darker());
g2d.draw(body[3]);
}
Color finalLabelColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
.getOutlineColor();
} else {
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
g2d.setFont(LABEL_FONT);
Rectangle bounds = body[0].getBounds();
drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2,
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[4];
int x = controlPoint.x;
int y = controlPoint.y;
int width = (int) WIDTH.convertToPixels();
int length = (int) LENGTH.convertToPixels();
int lipWidth = (int) LIP_WIDTH.convertToPixels();
int lipLength = (int) LIP_LENGTH.convertToPixels();
int edgeRadius = (int) EDGE_RADIUS.convertToPixels();
int pointMargin = (int) POINT_MARGIN.convertToPixels();
int pointSize = getClosestOdd(POINT_SIZE.convertToPixels());
int lipHoleSize = getClosestOdd(LIP_HOLE_SIZE.convertToPixels());
body[0] = new Area(new RoundRectangle2D.Double(x + pointMargin - length, y
- pointMargin, length, width, edgeRadius, edgeRadius));
body[1] = new Area(new RoundRectangle2D.Double(x + pointMargin - length - lipLength, y
- pointMargin + width / 2 - lipWidth / 2, length + 2 * lipLength, lipWidth,
edgeRadius / 2, edgeRadius / 2));
Area lipArea = new Area(body[1]);
lipArea.subtract(new Area(body[0]));
lipArea.subtract(new Area(new Ellipse2D.Double(
x + pointMargin - length - lipLength / 2, y - pointMargin + width / 2
- lipHoleSize / 2, lipHoleSize, lipHoleSize)));
lipArea.subtract(new Area(new Ellipse2D.Double(x + pointMargin + lipLength / 2, y
- pointMargin + width / 2 - lipHoleSize / 2, lipHoleSize, lipHoleSize)));
body[1] = lipArea;
body[2] = new Area(new Ellipse2D.Double(x - pointSize / 2, y - pointSize / 2,
pointSize, pointSize));
int poleSize = (int) POLE_SIZE.convertToPixels();
int poleSpacing = (int) POLE_SPACING.convertToPixels();
int coilSpacing = (int) COIL_SPACING.convertToPixels();
int coilMargin = (width - coilSpacing) / 2;
int poleMargin = (length - poleSpacing * 5) / 2;
Area poleArea = new Area();
for (int i = 0; i < 6; i++) {
Ellipse2D pole = new Ellipse2D.Double(x + pointMargin - length + poleMargin + i
* poleSpacing - poleSize / 2, y - pointMargin + coilMargin - poleSize / 2,
poleSize, poleSize);
poleArea.add(new Area(pole));
pole = new Ellipse2D.Double(x + pointMargin - length + poleMargin + i * poleSpacing
- poleSize / 2, y - pointMargin + width - coilMargin - poleSize / 2,
poleSize, poleSize);
poleArea.add(new Area(pole));
}
body[3] = poleArea;
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
double theta = 0;
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
for (Shape shape : body) {
Area area = (Area) shape;
area.transform(rotation);
}
}
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int baseWidth = 16 * width / 32;
int baseLength = 27 * width / 32;
g2d.setColor(BODY_COLOR);
g2d.fillRoundRect((width - baseWidth / 4) / 2, 0, baseWidth / 4, height - 1,
2 * width / 32, 2 * width / 32);
g2d.setColor(BODY_COLOR.darker());
g2d.drawRoundRect((width - baseWidth / 4) / 2, 0, baseWidth / 4, height - 1,
2 * width / 32, 2 * width / 32);
g2d.setColor(BODY_COLOR);
g2d.fillRoundRect((width - baseWidth) / 2, (height - baseLength) / 2, baseWidth,
baseLength, 4 * width / 32, 4 * width / 32);
g2d.setColor(BODY_COLOR.darker());
g2d.drawRoundRect((width - baseWidth) / 2, (height - baseLength) / 2, baseWidth,
baseLength, 4 * width / 32, 4 * width / 32);
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public Point getControlPoint(int index) {
return controlPoint;
}
@Override
public void setControlPoint(Point point, int index) {
this.controlPoint.setLocation(point);
// Invalidate the body
body = null;
}
@EditableProperty(name = "Model")
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
// Invalidate the body
body = null;
}
@EditableProperty
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
@@ -0,0 +1,370 @@
package org.diylc.components.guitar;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Lever Switch", category = "Guitar", author = "Branislav Stojkovic", description = "Strat-style lever switch", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "SW")
public class LeverSwitch extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private static Color BASE_COLOR = Color.lightGray;
private static Color WAFER_COLOR = Color.decode("#CD8500");
private static Size BASE_WIDTH = new Size(10d, SizeUnit.mm);
private static Size BASE_LENGTH = new Size(47.5d, SizeUnit.mm);
private static Size WAFER_LENGTH = new Size(40d, SizeUnit.mm);
private static Size WAFER_SPACING = new Size(7.62d, SizeUnit.mm);
private static Size WAFER_THICKNESS = new Size(1.27d, SizeUnit.mm);
private static Size HOLE_SIZE = new Size(2d, SizeUnit.mm);
private static Size HOLE_SPACING = new Size(41.2d, SizeUnit.mm);
private static Size TERMINAL_WIDTH = new Size(2d, SizeUnit.mm);
private static Size TERMINAL_LENGTH = new Size(0.1d, SizeUnit.in);
private static Size TERMINAL_SPACING = new Size(0.1d, SizeUnit.in);
private String value = "";
private Point[] controlPoints = new Point[] { new Point(0, 0) };
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private LeverSwitchType type = LeverSwitchType.DP3T;
public LeverSwitch() {
super();
updateControlPoints();
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
Shape[] body = getBody();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
/ MAX_ALPHA));
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BASE_COLOR);
g2d.fill(body[0]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : WAFER_COLOR);
g2d.fill(body[1]);
g2d.setComposite(oldComposite);
}
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : BASE_COLOR
.darker();
}
g2d.setColor(finalBorderColor);
g2d.draw(body[0]);
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : WAFER_COLOR
.darker();
}
g2d.draw(body[1]);
g2d.setColor(METAL_COLOR);
g2d.fill(body[2]);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(body[2]);
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[3];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int baseWidth = (int) BASE_WIDTH.convertToPixels();
int baseLength = (int) BASE_LENGTH.convertToPixels();
int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
int holeSpacing = (int) HOLE_SPACING.convertToPixels();
int waferLength = (int) WAFER_LENGTH.convertToPixels();
int waferSpacing = (int) WAFER_SPACING.convertToPixels();
int waferThickness = (int) WAFER_THICKNESS.convertToPixels();
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
int terminalLength = getClosestOdd(TERMINAL_LENGTH.convertToPixels());
int terminalWidth = getClosestOdd(TERMINAL_WIDTH.convertToPixels());
int baseX = x - terminalLength / 2 - waferSpacing;
int baseY = y
- (baseLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12)) / 2;
Area baseArea = new Area(new Rectangle2D.Double(baseX, baseY, baseWidth, baseLength));
baseArea.subtract(new Area(new Ellipse2D.Double(baseX + baseWidth / 2 - holeSize / 2,
baseY + (baseLength - holeSpacing) / 2 - holeSize / 2, holeSize, holeSize)));
baseArea.subtract(new Area(new Ellipse2D.Double(baseX + baseWidth / 2 - holeSize / 2,
baseY + (baseLength - holeSpacing) / 2 - holeSize / 2 + holeSpacing, holeSize,
holeSize)));
body[0] = baseArea;
Area waferArea = new Area(new Rectangle2D.Double(x - terminalLength / 2
- waferThickness / 2,
y - (waferLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12))
/ 2, waferThickness, waferLength));
if (type == LeverSwitchType._4P5T) {
waferArea.add(new Area(new Rectangle2D.Double(x - terminalLength / 2
- waferThickness / 2 + waferSpacing, y
- (waferLength - terminalSpacing * (type == LeverSwitchType.DP3T ? 7 : 12))
/ 2, waferThickness, waferLength)));
}
body[1] = waferArea;
double theta = 0;
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
}
Area terminalArea = new Area();
for (Point point : controlPoints) {
Area terminal = new Area(new RoundRectangle2D.Double(point.x - terminalLength / 2,
point.y - terminalWidth / 2, terminalLength, terminalWidth,
terminalWidth / 2, terminalWidth / 2));
terminal.subtract(new Area(
new RoundRectangle2D.Double(point.x - terminalLength / 4, point.y
- terminalWidth / 4, terminalLength / 2, terminalWidth / 2,
terminalWidth / 2, terminalWidth / 2)));
// Rotate the terminal if needed
if (theta != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, point.x,
point.y);
terminal.transform(rotation);
}
terminalArea.add(terminal);
}
body[2] = terminalArea;
// Rotate if needed
if (theta != 0) {
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
// Skip the last one because it's already rotated
for (int i = 0; i < body.length - 1; i++) {
Shape shape = body[i];
Area area = (Area) shape;
area.transform(rotation);
}
}
}
return body;
}
private void updateControlPoints() {
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int waferSpacing = (int) WAFER_SPACING.convertToPixels();
int terminalSpacing = (int) TERMINAL_SPACING.convertToPixels();
int terminalLength = (int) TERMINAL_LENGTH.convertToPixels();
switch (type) {
case DP3T:
controlPoints = new Point[8];
for (int i = 0; i < 8; i++) {
controlPoints[i] = new Point(x - (i % 2 == 1 ? terminalLength : 0), y + i
* terminalSpacing);
}
break;
case DP5T:
controlPoints = new Point[12];
for (int i = 0; i < 12; i++) {
controlPoints[i] = new Point(x, y + i * terminalSpacing
+ (i >= 6 ? terminalSpacing : 0));
}
break;
case _4P5T:
controlPoints = new Point[24];
for (int i = 0; i < 12; i++) {
controlPoints[i] = new Point(x, y + i * terminalSpacing
+ (i >= 6 ? terminalSpacing : 0));
controlPoints[i + 12] = new Point(x + waferSpacing, y + i * terminalSpacing
+ (i >= 6 ? terminalSpacing : 0));
}
break;
}
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
double theta = 0;
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
for (Point point : controlPoints) {
rotation.transform(point, point);
}
}
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setClip(width / 32, width / 32, width, height);
g2d.setColor(BASE_COLOR);
g2d.fillRect(0, 0, width * 2 / 3, height);
g2d.setColor(BASE_COLOR.darker());
g2d.drawRect(0, 0, width * 2 / 3, height);
g2d.setColor(WAFER_COLOR);
g2d.fillRect(width / 8 * 3, 0, width / 8, height);
g2d.setColor(WAFER_COLOR.darker());
g2d.drawRect(width / 8 * 3, 0, width / 8, height);
Area terminals = new Area();
int terminalLength = getClosestOdd(11 * width / 32);
int terminalWidth = getClosestOdd(7 * width / 32);
Area terminal = new Area(new RoundRectangle2D.Double(width / 16 * 7, 4 * width / 32,
terminalLength, terminalWidth, terminalWidth / 2, terminalWidth / 2));
terminal.subtract(new Area(new RoundRectangle2D.Double(width / 16 * 7 + terminalLength / 4
+ 1, 4 * width / 32 + terminalWidth / 4 + 1, terminalLength / 2, terminalWidth / 2,
terminalWidth / 4, terminalWidth / 4)));
terminals.add(terminal);
terminal = new Area(terminal);
terminal.transform(AffineTransform.getTranslateInstance(-terminalLength, terminalWidth + 2
* width / 32));
terminals.add(terminal);
terminal = new Area(terminal);
terminal.transform(AffineTransform.getTranslateInstance(terminalLength, terminalWidth + 2
* width / 32));
terminals.add(terminal);
g2d.setColor(METAL_COLOR);
g2d.fill(terminals);
g2d.setColor(METAL_COLOR.darker());
g2d.draw(terminals);
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.NEVER;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public void setControlPoint(Point point, int index) {
this.controlPoints[index].setLocation(point);
// Invalidate the body
body = null;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
@EditableProperty
public LeverSwitchType getType() {
return type;
}
public void setType(LeverSwitchType type) {
this.type = type;
updateControlPoints();
// Invalidate body
this.body = null;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
updateControlPoints();
// Invalidate the body
body = null;
}
public enum LeverSwitchType {
DP3T("DP3T (Standard Strat)"), _4P5T("4P5T (Super/Mega)"), DP5T("DP5T");
private String title;
private LeverSwitchType(String title) {
this.title = title;
}
@Override
public String toString() {
return title;
}
}
}
@@ -0,0 +1,254 @@
package org.diylc.components.guitar;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Strat Single Coil Pickup", category = "Guitar", author = "Branislav Stojkovic", description = "Strat-style single coil guitar pickup", stretchable = false, zOrder = IDIYComponent.COMPONENT, instanceNamePrefix = "PKP")
public class SingleCoilPickup extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
private static Color BODY_COLOR = Color.darkGray;
private static Color POINT_COLOR = Color.lightGray;
private static Size WIDTH = new Size(15.5d, SizeUnit.mm);
private static Size LENGTH = new Size(83.82d, SizeUnit.mm);
private static Size LIP_WIDTH = new Size(5d, SizeUnit.mm);
private static Size LIP_LENGTH = new Size(20d, SizeUnit.mm);
private static Size POINT_SIZE = new Size(3d, SizeUnit.mm);
private static Size HOLE_SIZE = new Size(2d, SizeUnit.mm);
private static Size HOLE_MARGIN = new Size(4d, SizeUnit.mm);
private static Size POLE_SIZE = new Size(3d, SizeUnit.mm);
private static Size POLE_SPACING = new Size(11.68d, SizeUnit.mm);
private String value = "";
private Point controlPoint = new Point(0, 0);
transient Shape[] body;
private Orientation orientation = Orientation.DEFAULT;
private Color color = BODY_COLOR;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
Shape[] body = getBody();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
if (componentState != ComponentState.DRAGGING) {
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
/ MAX_ALPHA));
}
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : color);
g2d.fill(body[0]);
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : POINT_COLOR);
g2d.fill(body[1]);
g2d.setComposite(oldComposite);
}
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
.getOutlineColor();
} else {
finalBorderColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : color
.brighter();
}
g2d.setColor(finalBorderColor);
g2d.draw(body[0]);
if (!outlineMode) {
g2d.draw(body[2]);
}
Color finalLabelColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
.getOutlineColor();
} else {
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
g2d.setFont(LABEL_FONT);
Rectangle bounds = body[0].getBounds();
drawCenteredText(g2d, value, bounds.x + bounds.width / 2, bounds.y + bounds.height / 2,
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[3];
int x = controlPoint.x;
int y = controlPoint.y;
int width = (int) WIDTH.convertToPixels();
int length = (int) LENGTH.convertToPixels();
int lipWidth = (int) LIP_WIDTH.convertToPixels();
int lipLength = (int) LIP_LENGTH.convertToPixels();
int pointSize = getClosestOdd(POINT_SIZE.convertToPixels());
int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
int holeMargin = getClosestOdd(HOLE_MARGIN.convertToPixels());
Area mainArea = new Area(new RoundRectangle2D.Double(x - length / 2, y - lipWidth / 2
- width, length, width, width, width));
mainArea.add(new Area(new Polygon(new int[] { x - length / 2 + width / 2,
x + length / 2 - width / 2, x + lipLength / 2, x - lipLength / 2 }, new int[] {
y - lipWidth / 2, y - lipWidth / 2, y + lipWidth / 2, y + lipWidth / 2 }, 4)));
// Cutout holes
mainArea.subtract(new Area(new Ellipse2D.Double(x - length / 2 + holeMargin - holeSize
/ 2, y - lipWidth / 2 - width / 2 - holeSize / 2, holeSize, holeSize)));
mainArea.subtract(new Area(new Ellipse2D.Double(x + length / 2 - holeMargin - holeSize
/ 2, y - lipWidth / 2 - width / 2 - holeSize / 2, holeSize, holeSize)));
body[0] = mainArea;
body[1] = new Area(new Ellipse2D.Double(x - pointSize / 2, y - pointSize / 2,
pointSize, pointSize));
int poleSize = (int) POLE_SIZE.convertToPixels();
int poleSpacing = (int) POLE_SPACING.convertToPixels();
int poleMargin = (length - poleSpacing * 5) / 2;
Area poleArea = new Area();
for (int i = 0; i < 6; i++) {
Ellipse2D pole = new Ellipse2D.Double(
x - length / 2 + poleMargin + i * poleSpacing, y - lipWidth / 2 - width / 2
- poleSize / 2, poleSize, poleSize);
poleArea.add(new Area(pole));
}
body[2] = poleArea;
// Rotate if needed
if (orientation != Orientation.DEFAULT) {
double theta = 0;
switch (orientation) {
case _90:
theta = Math.PI / 2;
break;
case _180:
theta = Math.PI;
break;
case _270:
theta = Math.PI * 3 / 2;
break;
}
AffineTransform rotation = AffineTransform.getRotateInstance(theta, x, y);
for (Shape shape : body) {
Area area = (Area) shape;
area.transform(rotation);
}
}
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int bodyWidth = 8 * width / 32;
int bodyLength = 30 * width / 32;
g2d.setColor(BODY_COLOR);
g2d.fillRoundRect((width - bodyWidth) / 2, (height - bodyLength) / 2, bodyWidth,
bodyLength, bodyWidth, bodyWidth);
g2d.fillPolygon(new int[] { width * 9 / 16, width * 9 / 16, width * 11 / 16, width * 11 / 16 },
new int[] { (height - bodyLength) / 2, (height + bodyLength) / 2, height * 5 / 8,
height * 3 / 8 }, 4);
g2d.setColor(Color.lightGray);
g2d.drawLine(width / 2, 4 * width / 32, width / 2, 4 * width / 32);
g2d.drawLine(width / 2, height - 4 * width / 32, width / 2, height - 4 * width / 32);
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public Point getControlPoint(int index) {
return controlPoint;
}
@Override
public void setControlPoint(Point point, int index) {
this.controlPoint.setLocation(point);
// Invalidate the body
body = null;
}
@EditableProperty(name = "Model")
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@EditableProperty
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
// Invalidate the body
body = null;
}
@EditableProperty
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
@@ -15,6 +15,7 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
@@ -22,7 +23,7 @@ import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.BomEntry;
import org.diylc.utils.BomMaker;
@ComponentDescriptor(name = "Bill of Materials", author = "Branislav Stojkovic", category = "Misc", description = "", instanceNamePrefix = "BOM", zOrder = IDIYComponent.TEXT, stretchable = false)
@ComponentDescriptor(name = "Bill of Materials", author = "Branislav Stojkovic", category = "Misc", description = "", instanceNamePrefix = "BOM", zOrder = IDIYComponent.TEXT, stretchable = false, bomPolicy = BomPolicy.NEVER_SHOW)
public class BOM extends AbstractComponent<Void> {
public static Size DEFAULT_SIZE = new Size(10d, SizeUnit.cm);
@@ -49,14 +50,20 @@ public class BOM extends AbstractComponent<Void> {
}
g2d.setFont(LABEL_FONT);
g2d.setColor(componentState == ComponentState.DRAGGING
|| componentState == ComponentState.SELECTED ? SELECTION_COLOR : COLOR);
|| componentState == ComponentState.SELECTED ? SELECTION_COLOR : COLOR);
// Determine maximum name length and maximum value length to calculate
// number of columns.
// number of columns.
FontMetrics fontMetrics = g2d.getFontMetrics();
int maxNameWidth = 0;
int maxValueWidth = 0;
int maxHeight = 0;
for (BomEntry entry : bom) {
String valueStr;
if (entry.getValue() == null || entry.getValue().trim().isEmpty()) {
valueStr = "qty " + entry.getQuantity().toString();
} else {
valueStr = entry.getValue().toString();
}
Rectangle2D stringBounds = fontMetrics.getStringBounds(entry.getName(), g2d);
if (stringBounds.getWidth() > maxNameWidth) {
maxNameWidth = (int) stringBounds.getWidth();
@@ -64,7 +71,7 @@ public class BOM extends AbstractComponent<Void> {
if (stringBounds.getHeight() > maxHeight) {
maxHeight = (int) stringBounds.getHeight();
}
stringBounds = fontMetrics.getStringBounds(entry.getValue().toString(), g2d);
stringBounds = fontMetrics.getStringBounds(valueStr, g2d);
if (stringBounds.getWidth() > maxValueWidth) {
maxValueWidth = (int) stringBounds.getWidth();
}
@@ -75,6 +82,8 @@ public class BOM extends AbstractComponent<Void> {
// Calculate maximum entry size.
int maxEntrySize = maxNameWidth + maxValueWidth + 2 * (int) SPACING.convertToPixels();
int columnCount = (int) size.convertToPixels() / maxEntrySize;
if (columnCount == 0)
columnCount = 1;
int columnWidth = (int) size.convertToPixels() / columnCount;
int entriesPerColumn = (int) Math.ceil(1.d * bom.size() / columnCount);
if (entriesPerColumn == 0) {
@@ -82,13 +91,20 @@ public class BOM extends AbstractComponent<Void> {
return;
}
for (int i = 0; i < bom.size(); i++) {
String valueStr;
BomEntry entry = bom.get(i);
if (entry.getValue() == null || entry.getValue().trim().isEmpty()) {
valueStr = "qty " + entry.getQuantity().toString();
} else {
valueStr = entry.getValue().toString();
}
int columnIndex = i / entriesPerColumn;
int rowIndex = i % entriesPerColumn;
int x = point.x + columnIndex * columnWidth;
int y = point.y + rowIndex * maxHeight;
g2d.drawString(bom.get(i).getName(), x, y);
g2d.drawString(entry.getName(), x, y);
x += maxNameWidth + SPACING.convertToPixels();
g2d.drawString(bom.get(i).getValue().toString(), x, y);
g2d.drawString(valueStr, x, y);
}
}
@@ -0,0 +1,149 @@
package org.diylc.components.misc;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import org.diylc.common.ObjectCache;
import org.diylc.components.AbstractComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Ground Symbol", author = "Branislav Stojkovic", category = "Misc", instanceNamePrefix = "GND", description = "Ground schematic symbol", stretchable = false, zOrder = IDIYComponent.COMPONENT, bomPolicy = BomPolicy.NEVER_SHOW)
public class GroundSymbol extends AbstractComponent<Void> {
private static final long serialVersionUID = 1L;
public static Color COLOR = Color.black;
public static Size SIZE = new Size(0.15d, SizeUnit.in);
private Point point = new Point(0, 0);
private Color color = COLOR;
private Size size = SIZE;
private GroundSymbolType type = GroundSymbolType.DEFAULT;
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
int sizePx = (int) size.convertToPixels();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.setColor(color);
int x = point.x;
int y = point.y;
g2d.drawLine(x, y, x, y + sizePx / 6);
if (type == GroundSymbolType.DEFAULT) {
int delta = sizePx / 7;
for (int i = 0; i < 5; i++) {
g2d.drawLine(x - sizePx / 2 + delta * i, y + sizePx / 6 * (i + 1), x + sizePx / 2
- delta * i, y + sizePx / 6 * (i + 1));
}
} else {
Polygon poly = new Polygon(new int[] { x - sizePx / 2, x + sizePx / 2, x }, new int[] {
y + sizePx / 6, y + sizePx / 6, y + sizePx }, 3);
g2d.draw(poly);
}
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int margin = 3 * width / 32;
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.setColor(COLOR);
g2d.drawLine(width / 2, margin * 2, width / 2, margin * 3 + height / 5);
for (int i = 0; i < 5; i++) {
g2d.drawLine(margin * (i + 1), margin * (3 + i) + height / 5, width - margin * (i + 1),
margin * (3 + i) + height / 5);
}
}
@EditableProperty(name = "Style")
public GroundSymbolType getType() {
return type;
}
public void setType(GroundSymbolType type) {
this.type = type;
}
@Override
public Point getControlPoint(int index) {
return point;
}
@EditableProperty
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
@EditableProperty
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
@Override
public int getControlPointCount() {
return 1;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public void setControlPoint(Point point, int index) {
this.point = point;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@Deprecated
@Override
public Void getValue() {
return null;
}
@Deprecated
@Override
public void setValue(Void value) {
}
public static enum GroundSymbolType {
DEFAULT("Default"), TRIANGLE("Triangle");
private String title;
private GroundSymbolType(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
@Override
public String toString() {
return title;
}
}
}
@@ -14,12 +14,13 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import com.thoughtworks.xstream.annotations.XStreamConverter;
@ComponentDescriptor(name = "Image", author = "Branislav Stojkovic", category = "Misc", description = "User defined image", instanceNamePrefix = "Img", zOrder = IDIYComponent.TEXT, stretchable = false)
@ComponentDescriptor(name = "Image", author = "Branislav Stojkovic", category = "Misc", description = "User defined image", instanceNamePrefix = "Img", zOrder = IDIYComponent.COMPONENT, flexibleZOrder = true, stretchable = false, bomPolicy = BomPolicy.NEVER_SHOW)
public class Image extends AbstractTransparentComponent<Void> {
private static final long serialVersionUID = 1L;
@@ -13,10 +13,11 @@ import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "Label", author = "Branislav Stojkovic", category = "Misc", description = "User defined label", instanceNamePrefix = "L", zOrder = IDIYComponent.TEXT, stretchable = false)
@ComponentDescriptor(name = "Label", author = "Branislav Stojkovic", category = "Misc", description = "User defined label", instanceNamePrefix = "L", zOrder = IDIYComponent.TEXT, flexibleZOrder = true, stretchable = false, bomPolicy = BomPolicy.NEVER_SHOW)
public class Label extends AbstractComponent<Void> {
public static String DEFAULT_TEXT = "Double click to edit text";
@@ -18,6 +18,7 @@ import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.core.measures.VoltageUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Electrolytic Capacitor (axial)", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C", description = "Axial electrolytic capacitor, similar to Sprague Atom, F&T, etc", zOrder = IDIYComponent.COMPONENT)
@@ -33,7 +34,10 @@ public class AxialElectrolyticCapacitor extends AbstractLeadedComponent<Capacita
public static Color TICK_COLOR = Color.white;
private Capacitance value = new Capacitance(1d, CapacitanceUnit.uF);
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = new org.diylc.core.measures.Voltage(63d,
VoltageUnit.V);
private Color markerColor = MARKER_COLOR;
private Color tickColor = TICK_COLOR;
@@ -54,14 +58,30 @@ public class AxialElectrolyticCapacitor extends AbstractLeadedComponent<Capacita
this.value = value;
}
@EditableProperty
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
// Backward comptibility
if (voltageNew == null) {
voltageNew = voltage.convertToNewFormat();
voltage = null;
// Clear old value, don't need it anymore
}
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
@@ -14,6 +14,7 @@ import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.core.measures.VoltageUnit;
@ComponentDescriptor(name = "Film Capacitor (axial)", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C", description = "Axial film capacitor, similar to Mallory 150s", zOrder = IDIYComponent.COMPONENT)
public class AxialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
@@ -26,7 +27,10 @@ public class AxialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
public static Color BORDER_COLOR = BODY_COLOR.darker();
private Capacitance value = new Capacitance(22d, CapacitanceUnit.nF);
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = new org.diylc.core.measures.Voltage(63d,
VoltageUnit.V);
public AxialFilmCapacitor() {
super();
@@ -48,15 +52,30 @@ public class AxialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
this.value = value;
}
@EditableProperty
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
// Backward comptibility
if (voltageNew == null) {
voltageNew = voltage.convertToNewFormat();
voltage = null;
// Clear old value, don't need it anymore
}
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
@@ -13,6 +13,7 @@ import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.core.measures.VoltageUnit;
@ComponentDescriptor(name = "Capacitor (schematic symbol)", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C", description = "Capacitor schematic symbol with an optional polarity sign", zOrder = IDIYComponent.COMPONENT)
public class CapacitorSymbol extends AbstractSchematicLeadedSymbol<Capacitance> {
@@ -23,7 +24,10 @@ public class CapacitorSymbol extends AbstractSchematicLeadedSymbol<Capacitance>
public static Size DEFAULT_WIDTH = new Size(0.15, SizeUnit.in);
private Capacitance value = new Capacitance(22d, CapacitanceUnit.nF);
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = new org.diylc.core.measures.Voltage(63d,
VoltageUnit.V);
private boolean polarized = false;
@EditableProperty
@@ -35,15 +39,31 @@ public class CapacitorSymbol extends AbstractSchematicLeadedSymbol<Capacitance>
this.value = value;
}
@EditableProperty
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
// Backward compatibility
if (voltageNew == null) {
voltageNew = voltage.convertToNewFormat();
voltage = null;
// Clear old value, don't need it anymore
}
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
@EditableProperty
public boolean getPolarized() {
return polarized;
@@ -1,5 +1,7 @@
package org.diylc.components.passive;
import org.diylc.core.measures.PowerUnit;
public enum Power {
EIGHT("1/8W"), QUARTER("1/4W"), HALF("1/2W"), ONE("1W"), TWO("2W"), FIVE("5W"), TEN("10W"), FIFTY(
@@ -15,4 +17,40 @@ public enum Power {
public String toString() {
return label;
}
public org.diylc.core.measures.Power convertToNewFormat() {
org.diylc.core.measures.Power powerNew;
switch (this) {
case EIGHT:
powerNew = new org.diylc.core.measures.Power(1 / 8d, PowerUnit.W);
break;
case FIVE:
powerNew = new org.diylc.core.measures.Power(5d, PowerUnit.W);
break;
case FIFTY:
powerNew = new org.diylc.core.measures.Power(50d, PowerUnit.W);
break;
case HALF:
powerNew = new org.diylc.core.measures.Power(1 / 2d, PowerUnit.W);
break;
case HUNDRED:
powerNew = new org.diylc.core.measures.Power(100d, PowerUnit.W);
break;
case ONE:
powerNew = new org.diylc.core.measures.Power(1d, PowerUnit.W);
break;
case QUARTER:
powerNew = new org.diylc.core.measures.Power(1 / 4d, PowerUnit.W);
break;
case TEN:
powerNew = new org.diylc.core.measures.Power(10d, PowerUnit.W);
break;
case TWO:
powerNew = new org.diylc.core.measures.Power(2d, PowerUnit.W);
break;
default:
powerNew = new org.diylc.core.measures.Power(1 / 2d, PowerUnit.W);
}
return powerNew;
}
}
@@ -20,6 +20,7 @@ import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.core.measures.VoltageUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "Electrolytic Capacitor", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C", description = "Vertical mounted electrolytic capacitor, polarized or bipolar", zOrder = IDIYComponent.COMPONENT)
@@ -34,7 +35,10 @@ public class RadialElectrolytic extends AbstractLeadedComponent<Capacitance> {
public static Color TICK_COLOR = Color.white;
private Capacitance value = new Capacitance(1d, CapacitanceUnit.uF);
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = new org.diylc.core.measures.Voltage(63d,
VoltageUnit.V);
private Color markerColor = MARKER_COLOR;
private Color tickColor = TICK_COLOR;
@@ -55,14 +59,30 @@ public class RadialElectrolytic extends AbstractLeadedComponent<Capacitance> {
this.value = value;
}
@EditableProperty
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
// Backward comptibility
if (voltageNew == null) {
voltageNew = voltage.convertToNewFormat();
voltage = null;
// Clear old value, don't need it anymore
}
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(BODY_COLOR);
@@ -14,6 +14,7 @@ import org.diylc.core.measures.Capacitance;
import org.diylc.core.measures.CapacitanceUnit;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.core.measures.VoltageUnit;
@ComponentDescriptor(name = "Film Capacitor (radial)", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C", description = "Radial film capacitor, similar to Sprague Orange Drop", zOrder = IDIYComponent.COMPONENT)
public class RadialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
@@ -26,7 +27,10 @@ public class RadialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
public static Color BORDER_COLOR = BODY_COLOR.darker();
private Capacitance value = new Capacitance(123d, CapacitanceUnit.nF);
@Deprecated
private Voltage voltage = Voltage._63V;
private org.diylc.core.measures.Voltage voltageNew = new org.diylc.core.measures.Voltage(63d,
VoltageUnit.V);
public RadialFilmCapacitor() {
super();
@@ -43,16 +47,31 @@ public class RadialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
this.value = value;
}
@EditableProperty
@Deprecated
public Voltage getVoltage() {
return voltage;
}
@Deprecated
public void setVoltage(Voltage voltage) {
this.voltage = voltage;
}
@EditableProperty(name = "Voltage")
public org.diylc.core.measures.Voltage getVoltageNew() {
// Backward comptibility
if (voltageNew == null) {
voltageNew = voltage.convertToNewFormat();
voltage = null;
// Clear old value, don't need it anymore
}
return voltageNew;
}
public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) {
this.voltageNew = voltageNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR);
@@ -13,12 +13,13 @@ 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.PowerUnit;
import org.diylc.core.measures.Resistance;
import org.diylc.core.measures.ResistanceUnit;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Resistor", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "R", description = "test", zOrder = IDIYComponent.COMPONENT)
@ComponentDescriptor(name = "Resistor", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "R", description = "", zOrder = IDIYComponent.COMPONENT)
public class Resistor extends AbstractLeadedComponent<Resistance> {
private static final long serialVersionUID = 1L;
@@ -27,9 +28,14 @@ public class Resistor extends AbstractLeadedComponent<Resistance> {
public static Size DEFAULT_HEIGHT = new Size(1d / 8, SizeUnit.in);
public static Color BODY_COLOR = Color.decode("#82CFFD");
public static Color BORDER_COLOR = BODY_COLOR.darker();
public static int BAND_SPACING = 5;
public static int FIRST_BAND = 4;
private Resistance value = new Resistance(123d, ResistanceUnit.K);
private Resistance value = new Resistance(100d, ResistanceUnit.K);
@Deprecated
private Power power = Power.HALF;
private org.diylc.core.measures.Power powerNew = new org.diylc.core.measures.Power(0.5,
PowerUnit.W);
private ResistorColorCode colorCode = ResistorColorCode._5_BAND;
public Resistor() {
@@ -37,7 +43,7 @@ public class Resistor extends AbstractLeadedComponent<Resistance> {
this.bodyColor = BODY_COLOR;
this.borderColor = BORDER_COLOR;
}
@Override
protected boolean supportsStandingMode() {
return true;
@@ -52,15 +58,31 @@ public class Resistor extends AbstractLeadedComponent<Resistance> {
this.value = value;
}
@EditableProperty
@Deprecated
public Power getPower() {
return power;
}
@Deprecated
public void setPower(Power power) {
this.power = power;
}
@EditableProperty(name = "Power rating")
public org.diylc.core.measures.Power getPowerNew() {
// Backward compatibility
if (powerNew == null) {
powerNew = power.convertToNewFormat();
// Clear old value, don't need it anymore
power = null;
}
return powerNew;
}
public void setPowerNew(org.diylc.core.measures.Power powerNew) {
this.powerNew = powerNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
g2d.setColor(LEAD_COLOR);
@@ -110,12 +132,22 @@ public class Resistor extends AbstractLeadedComponent<Resistance> {
}
int height = getClosestOdd(getWidth().convertToPixels());
Color[] bands = value.getColorCode(colorCode);
int x = 4;
int x = FIRST_BAND;
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
for (int i = 0; i < bands.length; i++) {
g2d.setColor(bands[i]);
g2d.drawLine(x, 1, x, height - 1);
x += 5;
x += BAND_SPACING;
}
}
@Override
protected int getLabelOffset(int bodyWidth, int labelWidth) {
Color[] bands = value.getColorCode(colorCode);
int bandArea = FIRST_BAND + BAND_SPACING * (bands.length - 1);
// Only offset the label if overlaping with the band area.
if (labelWidth > bodyWidth - 2 * bandArea)
return bandArea / 2;
return 0;
}
}
@@ -9,12 +9,13 @@ import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.PowerUnit;
import org.diylc.core.measures.Resistance;
import org.diylc.core.measures.ResistanceUnit;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
@ComponentDescriptor(name = "Resistor (schematic symbol)", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "R", description = "", zOrder = IDIYComponent.COMPONENT)
@ComponentDescriptor(name = "Resistor (schematic symbol)", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "R", description = "Resistor schematic symbol", zOrder = IDIYComponent.COMPONENT)
public class ResistorSymbol extends AbstractSchematicLeadedSymbol<Resistance> {
private static final long serialVersionUID = 1L;
@@ -23,7 +24,10 @@ public class ResistorSymbol extends AbstractSchematicLeadedSymbol<Resistance> {
public static Size DEFAULT_WIDTH = new Size(0.08, SizeUnit.in);
private Resistance value = new Resistance(100d, ResistanceUnit.K);
@Deprecated
private Power power = Power.HALF;
private org.diylc.core.measures.Power powerNew = new org.diylc.core.measures.Power(0.5,
PowerUnit.W);
@EditableProperty
public Resistance getValue() {
@@ -34,14 +38,31 @@ public class ResistorSymbol extends AbstractSchematicLeadedSymbol<Resistance> {
this.value = value;
}
@EditableProperty
@Deprecated
public Power getPower() {
return power;
}
@Deprecated
public void setPower(Power power) {
this.power = power;
}
@EditableProperty(name = "Power rating")
public org.diylc.core.measures.Power getPowerNew() {
// Backward compatibility
if (powerNew == null) {
powerNew = power.convertToNewFormat();
// Clear old value, don't need it anymore
power = null;
}
return powerNew;
}
public void setPowerNew(org.diylc.core.measures.Power powerNew) {
this.powerNew = powerNew;
}
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
@@ -1,11 +1,58 @@
package org.diylc.components.passive;
import org.diylc.core.measures.VoltageUnit;
public enum Voltage {
_16V, _25V, _63V, _100V, _160V, _250V, _300V, _350V, _400V, _500V, _630V, _1KV;
@Override
public String toString() {
return name().replace("_", "");
}
public org.diylc.core.measures.Voltage convertToNewFormat() {
org.diylc.core.measures.Voltage voltageNew;
switch (this) {
case _100V:
voltageNew = new org.diylc.core.measures.Voltage(100d, VoltageUnit.V);
break;
case _160V:
voltageNew = new org.diylc.core.measures.Voltage(160d, VoltageUnit.V);
break;
case _16V:
voltageNew = new org.diylc.core.measures.Voltage(16d, VoltageUnit.V);
break;
case _1KV:
voltageNew = new org.diylc.core.measures.Voltage(1d, VoltageUnit.KV);
break;
case _250V:
voltageNew = new org.diylc.core.measures.Voltage(250d, VoltageUnit.V);
break;
case _25V:
voltageNew = new org.diylc.core.measures.Voltage(25d, VoltageUnit.V);
break;
case _300V:
voltageNew = new org.diylc.core.measures.Voltage(300d, VoltageUnit.V);
break;
case _350V:
voltageNew = new org.diylc.core.measures.Voltage(350d, VoltageUnit.V);
break;
case _400V:
voltageNew = new org.diylc.core.measures.Voltage(400d, VoltageUnit.V);
break;
case _500V:
voltageNew = new org.diylc.core.measures.Voltage(500d, VoltageUnit.V);
break;
case _630V:
voltageNew = new org.diylc.core.measures.Voltage(630d, VoltageUnit.V);
break;
case _63V:
voltageNew = new org.diylc.core.measures.Voltage(63d, VoltageUnit.V);
break;
default:
voltageNew = new org.diylc.core.measures.Voltage(100d, VoltageUnit.V);
}
return voltageNew;
}
}
@@ -0,0 +1,20 @@
package org.diylc.components.semiconductors;
import java.awt.Shape;
import org.diylc.components.AbstractLeadedComponent;
public abstract class AbstractDiodeSymbol extends AbstractLeadedComponent<String> {
private static final long serialVersionUID = 1L;
@Override
protected boolean shouldShadeLeads() {
return false;
}
@Override
protected Shape getBodyShape() {
return null;
}
}
@@ -0,0 +1,173 @@
package org.diylc.components.semiconductors;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.Display;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
public abstract class AbstractTransistorSymbol extends AbstractComponent<String> {
private static final long serialVersionUID = 1L;
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
public static Color COLOR = Color.black;
protected String value = "";
protected Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0),
new Point(0, 0) };
protected Color color = COLOR;
protected Display display = Display.NAME;
transient protected Shape[] body;
public AbstractTransistorSymbol() {
super();
updateControlPoints();
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int pinSpacing = (int) PIN_SPACING.convertToPixels();
Color finalColor;
if (componentState == ComponentState.SELECTED) {
finalColor = SELECTION_COLOR;
} else if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalColor = theme.getOutlineColor();
} else {
finalColor = color;
}
g2d.setColor(finalColor);
// Draw transistor
int x = controlPoints[0].x;
int y = controlPoints[0].y;
Shape[] body = getBody();
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.draw(body[0]);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.draw(body[1]);
g2d.fill(body[2]);
// Draw label
g2d.setFont(LABEL_FONT);
Color finalLabelColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
.getOutlineColor();
} else {
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
drawCenteredText(g2d, display == Display.VALUE ? getValue() : getName(),
x + pinSpacing * 2, y, HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public int getControlPointCount() {
return controlPoints.length;
}
private void updateControlPoints() {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
// Update control points.
int x = controlPoints[0].x;
int y = controlPoints[0].y;
controlPoints[1].x = x + pinSpacing * 2;
controlPoints[1].y = y - pinSpacing * 2;
controlPoints[2].x = x + pinSpacing * 2;
controlPoints[2].y = y + pinSpacing * 2;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@EditableProperty
@Override
public String getValue() {
return this.value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
// Invalidate body
body = null;
}
@EditableProperty
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
@EditableProperty
public Display getDisplay() {
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
/**
* Returns transistor shape consisting of 3 parts, in this order: main body,
* connectors, polarity arrow.
*
* @return
*/
protected abstract Shape[] getBody();
}
@@ -0,0 +1,11 @@
package org.diylc.components.semiconductors;
public enum BJTPolarity {
NPN, PNP;
@Override
public String toString() {
return name();
}
}
@@ -0,0 +1,98 @@
package org.diylc.components.semiconductors;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import org.diylc.common.ObjectCache;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "BJT Symbol", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "Bipolar junction transistor schematic symbol", stretchable = false, zOrder = IDIYComponent.COMPONENT)
public class BJTSymbol extends AbstractTransistorSymbol {
private static final long serialVersionUID = 1L;
protected BJTPolarity polarity = BJTPolarity.NPN;
public Shape[] getBody() {
if (body == null) {
body = new Shape[3];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int pinSpacing = (int) PIN_SPACING.convertToPixels();
GeneralPath polyline = new GeneralPath();
polyline.moveTo(x + pinSpacing / 2, y - pinSpacing);
polyline.lineTo(x + pinSpacing / 2, y + pinSpacing);
body[0] = polyline;
polyline = new GeneralPath();
polyline.moveTo(x, y);
polyline.lineTo(x + pinSpacing / 2, y);
polyline.moveTo(x + pinSpacing / 2, y - pinSpacing / 2);
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing);
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing * 2);
polyline.moveTo(x + pinSpacing / 2, y + pinSpacing / 2);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing * 2);
body[1] = polyline;
Area arrow;
double theta;
if (polarity == BJTPolarity.NPN) {
theta = Math.atan(1.0 / 3);
arrow = new Area(new Polygon(new int[] { x + pinSpacing, x + pinSpacing,
x + pinSpacing * 10 / 6 }, new int[] { y - pinSpacing / 5 + pinSpacing / 2,
y + pinSpacing / 5 + pinSpacing / 2, y + pinSpacing / 2 }, 3));
arrow.transform(AffineTransform.getRotateInstance(theta, x + pinSpacing / 2, y
+ pinSpacing / 2));
} else {
theta = -Math.atan(1.0 / 3);
arrow = new Area(new Polygon(new int[] { x + pinSpacing, x + pinSpacing * 10 / 6,
x + pinSpacing * 10 / 6 }, new int[] { y - pinSpacing / 2,
y - pinSpacing / 5 - pinSpacing / 2, y + pinSpacing / 5 - pinSpacing / 2 },
3));
arrow.transform(AffineTransform.getRotateInstance(theta, x + pinSpacing / 2, y
- pinSpacing / 2));
}
body[2] = arrow;
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.drawLine(width / 3, height / 5, width / 3, height * 4 / 5);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawLine(width / 8, height / 2, width / 3, height / 2);
g2d.drawLine(width * 3 / 4, 1, width * 3 / 4, height / 4);
g2d.drawLine(width / 3, height / 3 + 1, width * 3 / 4, height / 4);
g2d.drawLine(width * 3 / 4, height - 1, width * 3 / 4, height * 3 / 4);
g2d.drawLine(width / 3, height * 2 / 3 - 1, width * 3 / 4, height * 3 / 4);
}
@EditableProperty(name = "Polarity")
public BJTPolarity getPolarity() {
return polarity;
}
public void setPolarity(BJTPolarity polarity) {
this.polarity = polarity;
// Invalidate body
body = null;
}
}
@@ -13,6 +13,7 @@ import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.Display;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
@@ -50,6 +51,7 @@ public class DIL_IC extends AbstractTransparentComponent<String> {
private Size pinSpacing = new Size(0.1d, SizeUnit.in);
private Size rowSpacing = new Size(0.3d, SizeUnit.in);
private Point[] controlPoints = new Point[] { new Point(0, 0) };
protected Display display = Display.NAME;
// new Point(0, pinSpacing.convertToPixels()),
// new Point(0, 2 * pinSpacing.convertToPixels()),
// new Point(0, 3 * pinSpacing.convertToPixels()),
@@ -120,6 +122,18 @@ public class DIL_IC extends AbstractTransparentComponent<String> {
// Reset body shape;
body = null;
}
@EditableProperty
public Display getDisplay() {
if (display == null) {
display = Display.VALUE;
}
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
@Override
public int getControlPointCount() {
@@ -316,14 +330,15 @@ public class DIL_IC extends AbstractTransparentComponent<String> {
}
g2d.setColor(finalLabelColor);
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
Rectangle2D rect = fontMetrics.getStringBounds(getName(), g2d);
String label = display == Display.NAME ? getName() : getValue();
Rectangle2D rect = fontMetrics.getStringBounds(label, g2d);
int textHeight = (int) (rect.getHeight());
int textWidth = (int) (rect.getWidth());
// Center text horizontally and vertically
Rectangle bounds = mainArea.getBounds();
int x = bounds.x + (bounds.width - textWidth) / 2;
int y = bounds.y + (bounds.height - textHeight) / 2 + fontMetrics.getAscent();
g2d.drawString(getName(), x, y);
g2d.drawString(label, x, y);
}
@Override
@@ -0,0 +1,11 @@
package org.diylc.components.semiconductors;
public enum FETPolarity {
NEGATIVE, POSITIVE;
@Override
public String toString() {
return name().substring(0, 1) + name().substring(1).toLowerCase();
}
}
@@ -0,0 +1,22 @@
package org.diylc.components.semiconductors;
public enum ICPointCount {
_3("3", 3), _5("5", 5);
private String title;
private int value;
private ICPointCount(String title, int value) {
this.title = title;
this.value = value;
}
@Override
public String toString() {
return title;
}
public int getValue() {
return value;
}
}
@@ -0,0 +1,258 @@
package org.diylc.components.semiconductors;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.Display;
import org.diylc.common.HorizontalAlignment;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.VerticalAlignment;
import org.diylc.components.AbstractTransparentComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent;
import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project;
import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants;
@ComponentDescriptor(name = "IC Symbol", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "IC", description = "IC symbol with 3 or 5 contacts", stretchable = false, zOrder = IDIYComponent.COMPONENT)
public class ICSymbol extends AbstractTransparentComponent<String> {
private static final long serialVersionUID = 1L;
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
public static Color BODY_COLOR = Color.white;
public static Color BORDER_COLOR = Color.black;
protected ICPointCount icPointCount = ICPointCount._5;
protected String value = "";
protected Point[] controlPoints = new Point[] { new Point(0, 0), new Point(0, 0),
new Point(0, 0), new Point(0, 0), new Point(0, 0) };
protected Color bodyColor = BODY_COLOR;
protected Color borderColor = BORDER_COLOR;
protected Display display = Display.NAME;
transient private Shape[] body;
public ICSymbol() {
super();
updateControlPoints();
}
@Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
Project project, IDrawingObserver drawingObserver) {
if (checkPointsClipped(g2d.getClip())) {
return;
}
int pinSpacing = (int) PIN_SPACING.convertToPixels();
Composite oldComposite = g2d.getComposite();
if (alpha < MAX_ALPHA) {
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
/ MAX_ALPHA));
}
Shape[] body = getBody();
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
g2d.fill(body[0]);
g2d.setComposite(oldComposite);
Color finalBorderColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalBorderColor = theme.getOutlineColor();
} else {
finalBorderColor = borderColor;
}
g2d.setColor(finalBorderColor);
// Draw contacts
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.draw(body[1]);
// Draw triangle
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.draw(body[0]);
// Draw label
g2d.setFont(LABEL_FONT);
Color finalLabelColor;
if (outlineMode) {
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED : theme
.getOutlineColor();
} else {
finalLabelColor = componentState == ComponentState.SELECTED
|| componentState == ComponentState.DRAGGING ? LABEL_COLOR_SELECTED
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
int x = (controlPoints[0].x + controlPoints[2].x) / 2;
drawCenteredText(g2d, display == Display.VALUE ? getValue() : getName(), x,
controlPoints[0].y + pinSpacing, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
// Draw +/- markers
drawCenteredText(g2d, "-", controlPoints[0].x + pinSpacing, controlPoints[0].y,
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
drawCenteredText(g2d, "+", controlPoints[1].x + pinSpacing, controlPoints[1].y,
HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
int margin = 3 * width / 32;
Area area = new Area(new Polygon(new int[] { margin, margin, width - margin }, new int[] {
margin, height - margin, height / 2 }, 3));
// area.subtract(new Area(new Rectangle2D.Double(0, 0, 2 * margin,
// height)));
area.intersect(new Area(new Rectangle2D.Double(2 * margin, 0, width, height)));
g2d.setColor(BODY_COLOR);
g2d.fill(area);
g2d.setColor(BORDER_COLOR);
g2d.setFont(LABEL_FONT.deriveFont(8f));
drawCenteredText(g2d, "-", 3 * margin, height / 3, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
drawCenteredText(g2d, "+", 3 * margin + 1, height * 2 / 3, HorizontalAlignment.CENTER,
VerticalAlignment.CENTER);
// g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_ROUND,
// BasicStroke.JOIN_ROUND));
g2d.draw(area);
}
@Override
public Point getControlPoint(int index) {
return controlPoints[index];
}
@Override
public int getControlPointCount() {
return icPointCount.getValue();
}
private void updateControlPoints() {
int pinSpacing = (int) PIN_SPACING.convertToPixels();
// Update control points.
int x = controlPoints[0].x;
int y = controlPoints[0].y;
controlPoints[1].x = x;
controlPoints[1].y = y + pinSpacing * 2;
controlPoints[2].x = x + pinSpacing * 6;
controlPoints[2].y = y + pinSpacing;
controlPoints[3].x = x + pinSpacing * 3;
controlPoints[3].y = y - pinSpacing;
controlPoints[4].x = x + pinSpacing * 3;
controlPoints[4].y = y + pinSpacing * 3;
}
public Shape[] getBody() {
if (body == null) {
body = new Shape[2];
int pinSpacing = (int) PIN_SPACING.convertToPixels();
int x = controlPoints[0].x;
int y = controlPoints[0].y;
Shape triangle = new Polygon(new int[] { x + pinSpacing / 2, x + pinSpacing * 11 / 2,
x + pinSpacing / 2 }, new int[] { y - pinSpacing * 3 / 2, y + pinSpacing,
y + pinSpacing * 7 / 2 }, 3);
body[0] = triangle;
GeneralPath polyline = new GeneralPath();
polyline.moveTo(controlPoints[0].x, controlPoints[0].y);
polyline.lineTo(controlPoints[0].x + pinSpacing / 2, controlPoints[0].y);
polyline.moveTo(controlPoints[1].x, controlPoints[1].y);
polyline.lineTo(controlPoints[1].x + pinSpacing / 2, controlPoints[1].y);
polyline.moveTo(controlPoints[2].x, controlPoints[2].y);
polyline.lineTo(controlPoints[2].x - pinSpacing / 2, controlPoints[2].y);
if (icPointCount == ICPointCount._5) {
polyline.moveTo(controlPoints[3].x, controlPoints[3].y);
polyline.lineTo(controlPoints[3].x, controlPoints[3].y + pinSpacing * 3 / 4);
polyline.moveTo(controlPoints[4].x, controlPoints[4].y);
polyline.lineTo(controlPoints[4].x, controlPoints[4].y - pinSpacing * 3 / 4);
}
body[1] = polyline;
}
return body;
}
@Override
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
return VisibilityPolicy.WHEN_SELECTED;
}
@EditableProperty
@Override
public String getValue() {
return this.value;
}
@Override
public void setValue(String value) {
this.value = value;
}
@Override
public boolean isControlPointSticky(int index) {
return true;
}
@Override
public void setControlPoint(Point point, int index) {
controlPoints[index].setLocation(point);
body = null;
}
@EditableProperty(name = "Contacts")
public ICPointCount getIcPointCount() {
return icPointCount;
}
public void setIcPointCount(ICPointCount icPointCount) {
this.icPointCount = icPointCount;
updateControlPoints();
body = null;
}
@EditableProperty(name = "Body")
public Color getBodyColor() {
return bodyColor;
}
public void setBodyColor(Color bodyColor) {
this.bodyColor = bodyColor;
}
@EditableProperty(name = "Border")
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@EditableProperty
public Display getDisplay() {
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
}
@@ -0,0 +1,88 @@
package org.diylc.components.semiconductors;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import org.diylc.common.ObjectCache;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "JFET Symbol", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "JFET transistor schematic symbol", stretchable = false, zOrder = IDIYComponent.COMPONENT)
public class JFETSymbol extends AbstractTransistorSymbol {
private static final long serialVersionUID = 1L;
protected FETPolarity polarity = FETPolarity.NEGATIVE;
public Shape[] getBody() {
if (body == null) {
body = new Shape[3];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int pinSpacing = (int) PIN_SPACING.convertToPixels();
GeneralPath polyline = new GeneralPath();
polyline.moveTo(x + pinSpacing, y - pinSpacing);
polyline.lineTo(x + pinSpacing, y + pinSpacing);
body[0] = polyline;
polyline = new GeneralPath();
polyline.moveTo(x, y);
polyline.lineTo(x + pinSpacing, y);
polyline.moveTo(x + pinSpacing, y - pinSpacing * 7 / 8);
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing * 7 / 8);
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing * 2);
polyline.moveTo(x + pinSpacing, y + pinSpacing * 7 / 8);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing * 7 / 8);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing * 2);
body[1] = polyline;
Polygon arrow;
if (polarity == FETPolarity.NEGATIVE) {
arrow = new Polygon(new int[] { x + pinSpacing * 2 / 6, x + pinSpacing * 2 / 6,
x + pinSpacing * 6 / 6 }, new int[] { y - pinSpacing / 5,
y + pinSpacing / 5, y }, 3);
} else {
arrow = new Polygon(new int[] { x + pinSpacing / 6, x + pinSpacing * 5 / 6,
x + pinSpacing * 5 / 6 }, new int[] { y, y + pinSpacing / 5,
y - pinSpacing / 5 }, 3);
}
body[2] = arrow;
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.drawLine(width / 2, height / 5, width / 2, height * 4 / 5);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawLine(width / 5, height / 2, width / 2, height / 2);
g2d.drawLine(width * 3 / 4, 1, width * 3 / 4, height / 4);
g2d.drawLine(width / 2, height / 4, width * 3 / 4, height / 4);
g2d.drawLine(width * 3 / 4, height - 1, width * 3 / 4, height * 3 / 4);
g2d.drawLine(width / 2, height * 3 / 4, width * 3 / 4, height * 3 / 4);
}
@EditableProperty(name = "Channel")
public FETPolarity getPolarity() {
return polarity;
}
public void setPolarity(FETPolarity polarity) {
this.polarity = polarity;
// Invalidate body
body = null;
}
}
@@ -0,0 +1,91 @@
package org.diylc.components.semiconductors;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import org.diylc.common.ObjectCache;
import org.diylc.core.IDIYComponent;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
@ComponentDescriptor(name = "MOSFET Symbol", author = "Branislav Stojkovic", category = "Semiconductors", instanceNamePrefix = "Q", description = "MOSFET transistor schematic symbol", stretchable = false, zOrder = IDIYComponent.COMPONENT)
public class MOSFETSymbol extends AbstractTransistorSymbol {
private static final long serialVersionUID = 1L;
protected FETPolarity polarity = FETPolarity.NEGATIVE;
public Shape[] getBody() {
if (body == null) {
body = new Shape[3];
int x = controlPoints[0].x;
int y = controlPoints[0].y;
int pinSpacing = (int) PIN_SPACING.convertToPixels();
GeneralPath polyline = new GeneralPath();
polyline.moveTo(x + pinSpacing / 2, y - pinSpacing + 1);
polyline.lineTo(x + pinSpacing / 2, y + pinSpacing - 1);
polyline.moveTo(x + pinSpacing, y - pinSpacing + 1);
polyline.lineTo(x + pinSpacing, y + pinSpacing - 1);
body[0] = polyline;
polyline = new GeneralPath();
polyline.moveTo(x + pinSpacing, y - pinSpacing);
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing);
polyline.moveTo(x + pinSpacing, y + pinSpacing);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing);
polyline.moveTo(x, y);
polyline.lineTo(x + pinSpacing / 2, y);
polyline.moveTo(x + pinSpacing * 2, y - pinSpacing * 2);
polyline.lineTo(x + pinSpacing * 2, y - pinSpacing);
polyline.moveTo(x + pinSpacing * 2, y + pinSpacing * 2);
polyline.lineTo(x + pinSpacing * 2, y + pinSpacing);
body[1] = polyline;
Polygon arrow;
if (polarity == FETPolarity.NEGATIVE) {
arrow = new Polygon(new int[] { x + pinSpacing * 8 / 6, x + pinSpacing * 8 / 6,
x + pinSpacing * 12 / 6 }, new int[] { y + pinSpacing * 6 / 5,
y + pinSpacing * 4 / 5, y + pinSpacing }, 3);
} else {
arrow = new Polygon(new int[] { x + pinSpacing * 7 / 6, x + pinSpacing * 11 / 6,
x + pinSpacing * 11 / 6 }, new int[] { y - pinSpacing,
y - pinSpacing * 6 / 5, y - pinSpacing * 4 / 5 }, 3);
}
body[2] = arrow;
}
return body;
}
@Override
public void drawIcon(Graphics2D g2d, int width, int height) {
g2d.setColor(COLOR);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
g2d.drawLine(width * 2 / 5, height / 4 + 1, width * 2 / 5, height * 3 / 4 - 1);
g2d.drawLine(width * 3 / 5, height / 4 + 1, width * 3 / 5, height * 3 / 4 - 1);
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
g2d.drawLine(width / 5, height / 2, width * 2 / 5, height / 2);
g2d.drawLine(width * 4 / 5, 1, width * 4 / 5, height / 4);
g2d.drawLine(width * 4 / 5, height / 4, width * 3 / 5, height / 4);
g2d.drawLine(width * 4 / 5, height - 1, width * 4 / 5, height * 3 / 4);
g2d.drawLine(width * 4 / 5, height * 3 / 4, width * 3 / 5, height * 3 / 4);
}
@EditableProperty(name = "Channel")
public FETPolarity getPolarity() {
return polarity;
}
public void setPolarity(FETPolarity polarity) {
this.polarity = polarity;
// Invalidate body
body = null;
}
}
@@ -11,6 +11,7 @@ import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.Display;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
@@ -53,6 +54,7 @@ public class TransistorTO220 extends AbstractTransparentComponent<String> {
private Color borderColor = BORDER_COLOR;
private Color tabColor = TAB_COLOR;
private Color tabBorderColor = TAB_BORDER_COLOR;
private Display display = Display.NAME;
public TransistorTO220() {
super();
@@ -246,15 +248,16 @@ public class TransistorTO220 extends AbstractTransparentComponent<String> {
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
String label = (getDisplay() == Display.NAME) ? getName() : getValue();
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
Rectangle2D rect = fontMetrics.getStringBounds(getName(), g2d);
Rectangle2D rect = fontMetrics.getStringBounds(label, g2d);
int textHeight = (int) (rect.getHeight());
int textWidth = (int) (rect.getWidth());
// Center text horizontally and vertically
Rectangle bounds = mainArea.getBounds();
int x = bounds.x + (bounds.width - textWidth) / 2;
int y = bounds.y + (bounds.height - textHeight) / 2 + fontMetrics.getAscent();
g2d.drawString(getName(), x, y);
g2d.drawString(label, x, y);
}
@Override
@@ -304,4 +307,16 @@ public class TransistorTO220 extends AbstractTransparentComponent<String> {
public void setTabBorderColor(Color tabBorderColor) {
this.tabBorderColor = tabBorderColor;
}
@EditableProperty
public Display getDisplay() {
if (display == null) {
display = Display.NAME;
}
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
}
@@ -12,6 +12,7 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.Display;
import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation;
@@ -48,6 +49,7 @@ public class TransistorTO92 extends AbstractTransparentComponent<String> {
transient private Area body;
private Color bodyColor = BODY_COLOR;
private Color borderColor = BORDER_COLOR;
protected Display display = Display.NAME;
public TransistorTO92() {
super();
@@ -222,15 +224,16 @@ public class TransistorTO92 extends AbstractTransparentComponent<String> {
: LABEL_COLOR;
}
g2d.setColor(finalLabelColor);
String label = (getDisplay() == Display.NAME) ? getName() : getValue();
FontMetrics fontMetrics = g2d.getFontMetrics(g2d.getFont());
Rectangle2D rect = fontMetrics.getStringBounds(getName(), g2d);
Rectangle2D rect = fontMetrics.getStringBounds(label, g2d);
int textHeight = (int) (rect.getHeight());
int textWidth = (int) (rect.getWidth());
// Center text horizontally and vertically
Rectangle bounds = mainArea.getBounds();
int x = bounds.x + (bounds.width - textWidth) / 2;
int y = bounds.y + (bounds.height - textHeight) / 2 + fontMetrics.getAscent();
g2d.drawString(getName(), x, y);
g2d.drawString(label, x, y);
}
@Override
@@ -264,4 +267,16 @@ public class TransistorTO92 extends AbstractTransparentComponent<String> {
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
@EditableProperty
public Display getDisplay() {
if (display == null) {
display = Display.NAME;
}
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
}
+3 -5
View File
@@ -7,13 +7,11 @@
<classpathentry kind="lib" path="lib/xstream-1.3.1.jar"/>
<classpathentry kind="lib" path="lib/junit-4.7.jar"/>
<classpathentry kind="lib" path="lib/iText-2.1.7.jar"/>
<classpathentry kind="lib" path="lib/cloning-1.5.jar"/>
<classpathentry kind="lib" path="lib/objenesis-1.1.jar"/>
<classpathentry kind="lib" path="lib/jettison-1.0.1.jar"/>
<classpathentry kind="lib" path="lib/poi-3.5-FINAL-20090928.jar"/>
<classpathentry kind="lib" path="library/main.jar"/>
<classpathentry kind="lib" path="library/main.jar" sourcepath="/diylc-library"/>
<classpathentry combineaccessrules="false" kind="src" path="/diylc-core"/>
<classpathentry kind="lib" path="lib/app-framework.jar"/>
<classpathentry kind="lib" path="lib/swing-framework.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/app-framework"/>
<classpathentry combineaccessrules="false" kind="src" path="/swing-framework"/>
<classpathentry kind="output" path="bin"/>
</classpath>
+1 -1
View File
@@ -11,5 +11,5 @@
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;sourceLookupDirector&gt;&#13;&#10;&lt;sourceContainers duplicates=&quot;false&quot;&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;Library&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;javaProject name=&amp;quot;DIYLC&amp;quot;/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.jdt.launching.sourceContainer.javaProject&quot;/&gt;&#13;&#10;&lt;container memento=&quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;no&amp;quot;?&amp;gt;&amp;#13;&amp;#10;&amp;lt;default/&amp;gt;&amp;#13;&amp;#10;&quot; typeId=&quot;org.eclipse.debug.core.containerType.default&quot;/&gt;&#13;&#10;&lt;/sourceContainers&gt;&#13;&#10;&lt;/sourceLookupDirector&gt;&#13;&#10;"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.diylc.DIYLCStarter"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="diylc-swing"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms256m -Xmx512m -Dorg.diylc.debugComponentAreas=true"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms256m -Xmx512m -Dorg.diylc.scriptRun=true -Ddorg.diylc.debugComponentAreas=true"/>
</launchConfiguration>
+2
View File
@@ -0,0 +1,2 @@
ftype diyfile="%CD%\diylc.exe" "%%1"
assoc .diy=diyfile

Some files were not shown because too many files have changed in this diff Show More