mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 01:02:08 +10:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d5bd4a949 |
@@ -1 +0,0 @@
|
||||
/bin/
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>DIYLC</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,86 +0,0 @@
|
||||
<map>
|
||||
<entry>
|
||||
<string>default.org.diylc.components.passive.TrimmerPotentiometer:Type</string>
|
||||
<org.diylc.components.passive.TrimmerPotentiometer_-TrimmerType>FLAT_LARGE</org.diylc.components.passive.TrimmerPotentiometer_-TrimmerType>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>lastPath</string>
|
||||
<string>C:\Documents and Settings\Branislav Stojkovic\My Documents\Downloads</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>abnormalExit</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>stickyPoints</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>theme</string>
|
||||
<org.diylc.core.Theme>
|
||||
<name>Light</name>
|
||||
<bgColor>
|
||||
<red>255</red>
|
||||
<green>255</green>
|
||||
<blue>255</blue>
|
||||
<alpha>255</alpha>
|
||||
</bgColor>
|
||||
<gridColor>
|
||||
<red>240</red>
|
||||
<green>240</green>
|
||||
<blue>240</blue>
|
||||
<alpha>240</alpha>
|
||||
</gridColor>
|
||||
<outlineColor>
|
||||
<red>0</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
<alpha>255</alpha>
|
||||
</outlineColor>
|
||||
</org.diylc.core.Theme>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>antiAliasing</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>snapToGrid</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>hiQualityRender</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>outline</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>exportGrid</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>autoEdit</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>wheelZoom</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>default.org.diylc.components.misc.Label:Font Bold</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>autoCreatePads</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>continuousCreation</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>showTemplatesAtStartup</string>
|
||||
<boolean>false</boolean>
|
||||
</entry>
|
||||
</map>
|
||||
Binary file not shown.
Binary file not shown.
-19
@@ -1,19 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import com.diyfever.gui.simplemq.IMessageListener;
|
||||
|
||||
/**
|
||||
* Interface for plug-ins.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IPlugIn extends IMessageListener<EventType> {
|
||||
|
||||
/**
|
||||
* Method that connects the plug-in with {@link IPlugInPort}. Called by the
|
||||
* application when plug-in is installed.
|
||||
*
|
||||
* @param plugInPort
|
||||
*/
|
||||
void connect(IPlugInPort plugInPort);
|
||||
}
|
||||
-375
@@ -1,375 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.swing.plugins.edit.ComponentTransferable;
|
||||
|
||||
import com.diyfever.gui.simplemq.IMessageListener;
|
||||
import com.diyfever.gui.simplemq.MessageDispatcher;
|
||||
import com.diyfever.gui.update.VersionNumber;
|
||||
|
||||
/**
|
||||
* Interface for communication between plug-ins and the application. Plug-ins
|
||||
* may acquire information or make changes through this interface. Application
|
||||
* events are dispatched to plug-ins through {@link MessageDispatcher}
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @see IPlugIn
|
||||
* @see MessageDispatcher
|
||||
* @see IMessageListener
|
||||
* @see EventType
|
||||
*/
|
||||
public interface IPlugInPort {
|
||||
|
||||
public static final String ANTI_ALIASING_KEY = "antiAliasing";
|
||||
public static final String HI_QUALITY_RENDER_KEY = "hiQualityRender";
|
||||
public static final String EXPORT_GRID_KEY = "exportGrid";
|
||||
public static final String STICKY_POINTS_KEY = "stickyPoints";
|
||||
public static final String METRIC_KEY = "metric";
|
||||
public static final String SNAP_TO_GRID_KEY = "snapToGrid";
|
||||
public static final String AUTO_PADS_KEY = "autoCreatePads";
|
||||
public static final String CONTINUOUS_CREATION_KEY = "continuousCreation";
|
||||
public static final String AUTO_EDIT_KEY = "autoEdit";
|
||||
public static final String ABNORMAL_EXIT_KEY = "abnormalExit";
|
||||
public static final String WHEEL_ZOOM_KEY = "wheelZoom";
|
||||
public static final String OUTLINE_KEY = "outline";
|
||||
public static final String THEME_KEY = "theme";
|
||||
public static final String RECENT_COMPONENTS_KEY = "recentComponents";
|
||||
|
||||
/**
|
||||
* 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
|
||||
* actual size and the number of pixels per unit. If <code>useZoom</code> is
|
||||
* set to true, the result is scaled by zoom factor.
|
||||
*
|
||||
* @param useZoom
|
||||
*
|
||||
* @return canvas dimensions
|
||||
*/
|
||||
Dimension getCanvasDimensions(boolean useZoom);
|
||||
|
||||
/**
|
||||
* Returns an instance of {@link Cursor} that should be used at the
|
||||
* specified location.
|
||||
*
|
||||
* Note: point coordinates are scaled for zoom factor.
|
||||
*
|
||||
* @param point
|
||||
* @return cursor
|
||||
*/
|
||||
Cursor getCursorAt(Point point);
|
||||
|
||||
/**
|
||||
* Returns an instance of currently loaded project.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Project getCurrentProject();
|
||||
|
||||
/**
|
||||
* Loads specified {@link Project}.
|
||||
*
|
||||
* @param project
|
||||
* @param freshStart
|
||||
*/
|
||||
void loadProject(Project project, boolean freshStart);
|
||||
|
||||
/**
|
||||
* Creates a new project.
|
||||
*/
|
||||
void createNewProject();
|
||||
|
||||
/**
|
||||
* Loads a project from the specified file.
|
||||
*
|
||||
* @param fileName
|
||||
*/
|
||||
void loadProjectFromFile(String fileName);
|
||||
|
||||
/**
|
||||
* Saves the current project into the specified file.
|
||||
*
|
||||
* @param fileName
|
||||
* @param isBackup
|
||||
*/
|
||||
void saveProjectToFile(String fileName, boolean isBackup);
|
||||
|
||||
/**
|
||||
* @return the current file name.
|
||||
*/
|
||||
String getCurrentFileName();
|
||||
|
||||
/**
|
||||
* @return true if the current project is modified.
|
||||
*/
|
||||
boolean isProjectModified();
|
||||
|
||||
/**
|
||||
* Shows a user dialog if there are changes to confirm that it's safe to
|
||||
* proceed.
|
||||
*
|
||||
* @return true, if file actions (new, open, close) can be taken
|
||||
*/
|
||||
boolean allowFileAction();
|
||||
|
||||
/**
|
||||
* Returns all available {@link ComponentType}s classified by category.
|
||||
* Result is a {@link Map} between category name to a {@link List} of all
|
||||
* {@link ComponentType}s that share that category name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Map<String, List<ComponentType>> getComponentTypes();
|
||||
|
||||
/**
|
||||
* Draws project on the provided {@link Graphics2D}. If the provided filter
|
||||
* is not null, it will be used to filter the components that are shown.
|
||||
*
|
||||
* @param g2d
|
||||
* @param drawOptions
|
||||
* specific drawing options
|
||||
* @param filter
|
||||
*/
|
||||
void draw(Graphics2D g2d, Set<DrawOption> drawOptions, IComponentFiler filter);
|
||||
|
||||
Double[] getAvailableZoomLevels();
|
||||
|
||||
/**
|
||||
* Returns current zoom level where <code>zoomLevel = 1.0d</code> means
|
||||
* 100%.
|
||||
*
|
||||
* @return current zoom level
|
||||
*/
|
||||
double getZoomLevel();
|
||||
|
||||
/**
|
||||
* Changes current zoom level where <code>zoomLevel = 1.0d</code> means 100%
|
||||
*
|
||||
* @param zoomLevel
|
||||
* new zoom leve
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
VersionNumber getCurrentVersionNumber();
|
||||
|
||||
/**
|
||||
* Adds a list of components to the project.
|
||||
*
|
||||
* @param components
|
||||
*/
|
||||
void pasteComponents(List<IDIYComponent<?>> components);
|
||||
|
||||
/**
|
||||
* Deletes all the selected components from the project.
|
||||
*/
|
||||
void deleteSelectedComponents();
|
||||
|
||||
/**
|
||||
* Sets default value for the specified property name for currently selected
|
||||
* component types.
|
||||
*
|
||||
* @param propertyName
|
||||
* display name for property
|
||||
* @param value
|
||||
* new default value, must not be null
|
||||
*/
|
||||
void setSelectionDefaultPropertyValue(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* Sets default value for the specified property name for projects.
|
||||
*
|
||||
* @param propertyName
|
||||
* display name for property
|
||||
* @param value
|
||||
* new default value, must not be null
|
||||
*/
|
||||
void setProjectDefaultPropertyValue(String propertyName, Object value);
|
||||
|
||||
/**
|
||||
* @return a list of properties that are mutual for all the selected
|
||||
* components. Resulting list may be empty if selected components do
|
||||
* not have mutual properties or can be null if the selection is
|
||||
* empty.
|
||||
*/
|
||||
List<PropertyWrapper> getMutualSelectionProperties();
|
||||
|
||||
void editSelection();
|
||||
|
||||
/**
|
||||
* @return a list of editable properties of the current project.
|
||||
*/
|
||||
List<PropertyWrapper> getProjectProperties();
|
||||
|
||||
/**
|
||||
* Applies specified properties to the current project.
|
||||
*
|
||||
* @param properties
|
||||
*/
|
||||
void applyPropertiesToProject(List<PropertyWrapper> properties);
|
||||
|
||||
/**
|
||||
* Sets the new component slot. Specified component type will be used to
|
||||
* instantiate new component.
|
||||
*/
|
||||
void setNewComponentTypeSlot(ComponentType componentType);
|
||||
|
||||
/**
|
||||
* Changes default size notation, true for metric, false for imperial.
|
||||
*
|
||||
* @param isMetric
|
||||
*/
|
||||
void setMetric(boolean isMetric);
|
||||
|
||||
/**
|
||||
* Groups all selected components.
|
||||
*/
|
||||
void groupSelectedComponents();
|
||||
|
||||
/**
|
||||
* Ungroups all selected components.
|
||||
*/
|
||||
void ungroupSelectedComponents();
|
||||
|
||||
/**
|
||||
* Locks or unlocks the specified layer. All components within +- 0.5 range
|
||||
* will be affected by the change as well.
|
||||
*
|
||||
* @param layerZOrder
|
||||
* @param locked
|
||||
*/
|
||||
void setLayerLocked(int layerZOrder, boolean locked);
|
||||
|
||||
/**
|
||||
* @return selection size expressed in either inches or centimeters, based
|
||||
* on the user preference.
|
||||
*/
|
||||
Point2D calculateSelectionDimension();
|
||||
|
||||
/**
|
||||
* Sends each of the selected components one step back.
|
||||
*/
|
||||
void sendSelectionToBack();
|
||||
|
||||
/**
|
||||
* Brings each of the selected components one step to front.
|
||||
*/
|
||||
void bringSelectionToFront();
|
||||
|
||||
/**
|
||||
* Causes the display to refresh.
|
||||
*/
|
||||
void refresh();
|
||||
|
||||
/**
|
||||
* @return currently selected theme.
|
||||
*/
|
||||
Theme getSelectedTheme();
|
||||
|
||||
/**
|
||||
* Changes the current theme.
|
||||
*
|
||||
* @param theme
|
||||
*/
|
||||
void setSelectedTheme(Theme theme);
|
||||
|
||||
/**
|
||||
* Renumbers all the selected components.
|
||||
*
|
||||
* @param xAxisFirst
|
||||
*/
|
||||
void renumberSelectedComponents(boolean xAxisFirst);
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import org.diylc.common.ResistorColorCode;
|
||||
|
||||
public class Resistance extends AbstractMeasure<ResistanceUnit> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Color[] COLOR_DIGITS = new Color[] { Color.black, Color.decode("#8B4513"),
|
||||
Color.red, Color.orange, Color.yellow, Color.decode("#76EE00"), Color.blue,
|
||||
Color.decode("#91219E"), Color.lightGray, Color.white };
|
||||
private static final Color[] COLOR_MULTIPLIER = new Color[] { Color.lightGray.brighter(),
|
||||
Color.decode("#FFB90F"), Color.black, Color.decode("#8B4513"), Color.red, Color.orange,
|
||||
Color.yellow, Color.decode("#76EE00"), Color.blue };
|
||||
|
||||
public Resistance() {
|
||||
super();
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public Resistance(Double value, ResistanceUnit multiplier) {
|
||||
super(value, multiplier);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resistance clone() throws CloneNotSupportedException {
|
||||
return new Resistance(value, unit);
|
||||
}
|
||||
|
||||
public Color[] getColorCode(ResistorColorCode resistorColorCode) {
|
||||
Color[] bands;
|
||||
double base = getValue() * getUnit().getFactor();
|
||||
int multiplier = 0;
|
||||
while (base > (resistorColorCode == ResistorColorCode._4_BAND ? 99 : 999)) {
|
||||
multiplier += 1;
|
||||
base /= 10;
|
||||
}
|
||||
while (base < (resistorColorCode == ResistorColorCode._4_BAND ? 10 : 100)) {
|
||||
multiplier -= 1;
|
||||
base *= 10;
|
||||
}
|
||||
if (multiplier > 6 || multiplier < -2) {
|
||||
// Out of range.
|
||||
return new Color[] {};
|
||||
}
|
||||
switch (resistorColorCode) {
|
||||
case _4_BAND:
|
||||
bands = new Color[3];
|
||||
bands[0] = COLOR_DIGITS[(int) (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;
|
||||
}
|
||||
|
||||
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();
|
||||
return new Resistance(Double.parseDouble(value), unit);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse resistance: " + value);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public enum ResistanceUnit implements Unit {
|
||||
|
||||
R(1, "\u03a9"), K(1e3, "K"), M(1e6, "M");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
|
||||
private ResistanceUnit(double factor, String display) {
|
||||
this.factor = factor;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFactor() {
|
||||
return factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
}
|
||||
-673
@@ -1,673 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Image;
|
||||
import java.awt.Paint;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.RenderingHints.Key;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.CubicCurve2D;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.renderable.RenderableImage;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
|
||||
/**
|
||||
* {@link Graphics2D} wrapper that keeps track of all drawing actions and
|
||||
* creates an {@link Area} that corresponds to drawn objects. Before each
|
||||
* component is drawn, {@link #startedDrawingComponent()} should be called.
|
||||
* After the component is drawn, area may be retrieved using
|
||||
* {@link #finishedDrawingComponent()}. Graphics configuration (color, font,
|
||||
* etc) is reset between each two components.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class G2DWrapper extends Graphics2D implements IDrawingObserver {
|
||||
|
||||
public static int LINE_SENSITIVITY_MARGIN = 2;
|
||||
public static int CURVE_SENSITIVITY = 6;
|
||||
|
||||
private boolean drawingComponent = false;
|
||||
private boolean trackingAllowed = true;
|
||||
|
||||
private Graphics2D canvasGraphics;
|
||||
private Stroke originalStroke;
|
||||
private Color originalColor;
|
||||
private Composite originalComposite;
|
||||
private AffineTransform originalTx;
|
||||
private Font originalFont;
|
||||
private AffineTransform currentTx;
|
||||
private Area currentArea;
|
||||
private Shape lastShape;
|
||||
|
||||
/**
|
||||
* Creates a wrapper around specified {@link Graphics2D} object.
|
||||
*
|
||||
* @param canvasGraphics
|
||||
*/
|
||||
public G2DWrapper(Graphics2D canvasGraphics) {
|
||||
super();
|
||||
this.canvasGraphics = canvasGraphics;
|
||||
currentArea = new Area();
|
||||
currentTx = new AffineTransform();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears out the current area and caches canvas settings.
|
||||
*/
|
||||
public void startedDrawingComponent() {
|
||||
drawingComponent = true;
|
||||
currentArea = new Area();
|
||||
originalStroke = canvasGraphics.getStroke();
|
||||
originalColor = canvasGraphics.getColor();
|
||||
originalTx = canvasGraphics.getTransform();
|
||||
originalComposite = canvasGraphics.getComposite();
|
||||
originalFont = canvasGraphics.getFont();
|
||||
currentTx = new AffineTransform();
|
||||
lastShape = null;
|
||||
startTracking();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts {@link Graphics2D} settings and returns area drawn by component
|
||||
* in the meantime.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Area finishedDrawingComponent() {
|
||||
drawingComponent = false;
|
||||
canvasGraphics.setStroke(originalStroke);
|
||||
canvasGraphics.setColor(originalColor);
|
||||
canvasGraphics.setTransform(originalTx);
|
||||
canvasGraphics.setComposite(originalComposite);
|
||||
canvasGraphics.setFont(originalFont);
|
||||
return currentArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTracking() {
|
||||
this.trackingAllowed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTracking() {
|
||||
this.trackingAllowed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends shape interior to the current component area.
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
private void appendShape(Shape s) {
|
||||
if (!drawingComponent || !trackingAllowed) {
|
||||
return;
|
||||
}
|
||||
Rectangle2D bounds = s.getBounds2D();
|
||||
// Only cache the shape if it's not 1D.
|
||||
if (bounds.getWidth() > 1 && bounds.getHeight() > 1) {
|
||||
Area area = new Area(s);
|
||||
area.transform(currentTx);
|
||||
currentArea.add(area);
|
||||
lastShape = s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends shape outline to the current component area.
|
||||
*
|
||||
* @param s
|
||||
*/
|
||||
private void appendShapeOutline(Shape s) {
|
||||
// Do not add shape outline if the same shape has been filled recently.
|
||||
if (!drawingComponent || !trackingAllowed || s.equals(lastShape)) {
|
||||
return;
|
||||
}
|
||||
lastShape = s;
|
||||
PathIterator pathIterator = s.getPathIterator(null);
|
||||
double thickness;
|
||||
if (getStroke() instanceof BasicStroke) {
|
||||
thickness = ((BasicStroke) getStroke()).getLineWidth() + 2 * LINE_SENSITIVITY_MARGIN;
|
||||
} else {
|
||||
thickness = 2 * LINE_SENSITIVITY_MARGIN;
|
||||
}
|
||||
Point2D prevPoint = null;
|
||||
while (!pathIterator.isDone()) {
|
||||
double[] coord = new double[6];
|
||||
int type = pathIterator.currentSegment(coord);
|
||||
switch (type) {
|
||||
case PathIterator.SEG_MOVETO:
|
||||
prevPoint = new Point2D.Double(coord[0], coord[1]);
|
||||
break;
|
||||
case PathIterator.SEG_LINETO:
|
||||
// Represent straight line with a rectangle.
|
||||
Point2D nextPoint = new Point2D.Double(coord[0], coord[1]);
|
||||
Double theta = Math.atan2(nextPoint.getY() - prevPoint.getY(), nextPoint.getX()
|
||||
- prevPoint.getX());
|
||||
double width = Math.sqrt(Math.pow(nextPoint.getX() - prevPoint.getX(), 2)
|
||||
+ Math.pow(nextPoint.getY() - prevPoint.getY(), 2));
|
||||
double midX = (prevPoint.getX() + nextPoint.getX()) / 2;
|
||||
double midY = (prevPoint.getY() + nextPoint.getY()) / 2;
|
||||
Rectangle2D rect = new Rectangle2D.Double(midX - width / 2, midY - thickness / 2,
|
||||
width, thickness);
|
||||
Area area = new Area(rect);
|
||||
area.transform(AffineTransform.getRotateInstance(theta, midX, midY));
|
||||
// area.transform(currentTx);
|
||||
appendShape(area);
|
||||
// Set the prev point to line end
|
||||
prevPoint = nextPoint;
|
||||
break;
|
||||
case PathIterator.SEG_CUBICTO:
|
||||
CubicCurve2D cubicCurve = new CubicCurve2D.Double(prevPoint.getX(), prevPoint
|
||||
.getY(), coord[0], coord[1], coord[2], coord[3], coord[4], coord[5]);
|
||||
addCubicCurveArea(cubicCurve);
|
||||
prevPoint = new Point2D.Double(coord[4], coord[5]);
|
||||
break;
|
||||
case PathIterator.SEG_QUADTO:
|
||||
QuadCurve2D quadCurve = new QuadCurve2D.Double(prevPoint.getX(), prevPoint.getY(),
|
||||
coord[0], coord[1], coord[2], coord[3]);
|
||||
addQuadCurveArea(quadCurve);
|
||||
prevPoint = new Point2D.Double(coord[3], coord[3]);
|
||||
break;
|
||||
}
|
||||
pathIterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a cubic curve to the component area. It uses subdivision to
|
||||
* approximate the curve with a series of straight lines.
|
||||
*
|
||||
* @param curve
|
||||
*/
|
||||
private void addCubicCurveArea(CubicCurve2D curve) {
|
||||
// When end points are close enough, approximate the curve with a
|
||||
// straight line.
|
||||
if (curve.getFlatness() < CURVE_SENSITIVITY) {
|
||||
appendShapeOutline(new Line2D.Double(curve.getP1(), curve.getP2()));
|
||||
} else {
|
||||
CubicCurve2D leftSubcurve = new CubicCurve2D.Double();
|
||||
CubicCurve2D rightSubcurve = new CubicCurve2D.Double();
|
||||
curve.subdivide(leftSubcurve, rightSubcurve);
|
||||
addCubicCurveArea(leftSubcurve);
|
||||
addCubicCurveArea(rightSubcurve);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a quad curve to the component area. It uses subdivision to
|
||||
* approximate the curve with a series of straight lines.
|
||||
*
|
||||
* @param curve
|
||||
*/
|
||||
private void addQuadCurveArea(QuadCurve2D curve) {
|
||||
// When end points are close enough, approximate the curve with a
|
||||
// straight line.
|
||||
if (curve.getFlatness() < CURVE_SENSITIVITY) {
|
||||
appendShapeOutline(new Line2D.Double(curve.getP1(), curve.getP2()));
|
||||
} else {
|
||||
QuadCurve2D leftSubcurve = new QuadCurve2D.Double();
|
||||
QuadCurve2D rightSubcurve = new QuadCurve2D.Double();
|
||||
curve.subdivide(leftSubcurve, rightSubcurve);
|
||||
addQuadCurveArea(leftSubcurve);
|
||||
addQuadCurveArea(rightSubcurve);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRenderingHints(Map<?, ?> hints) {
|
||||
canvasGraphics.addRenderingHints(hints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clip(Shape s) {
|
||||
canvasGraphics.clip(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Shape s) {
|
||||
canvasGraphics.draw(s);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(s);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawGlyphVector(GlyphVector g, float x, float y) {
|
||||
canvasGraphics.drawGlyphVector(g, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) {
|
||||
// FIXME: process map
|
||||
return canvasGraphics.drawImage(img, xform, obs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) {
|
||||
canvasGraphics.drawImage(img, op, x, y);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
|
||||
canvasGraphics.drawRenderableImage(img, xform);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
|
||||
canvasGraphics.drawRenderedImage(img, xform);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(String str, int x, int y) {
|
||||
canvasGraphics.drawString(str, x, y);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
FontMetrics fontMetrics = canvasGraphics.getFontMetrics();
|
||||
Rectangle2D rect = fontMetrics.getStringBounds(str, canvasGraphics);
|
||||
appendShape(new Rectangle2D.Double(rect.getX() + x, rect.getY() + y, rect.getWidth(),
|
||||
rect.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(String str, float x, float y) {
|
||||
canvasGraphics.drawString(str, x, y);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
FontMetrics fontMetrics = canvasGraphics.getFontMetrics();
|
||||
Rectangle2D rect = fontMetrics.getStringBounds(str, canvasGraphics);
|
||||
appendShape(new Rectangle2D.Double(rect.getX() + x, rect.getY() + y, rect.getWidth(),
|
||||
rect.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(AttributedCharacterIterator iterator, int x, int y) {
|
||||
canvasGraphics.drawString(iterator, x, y);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString(AttributedCharacterIterator iterator, float x, float y) {
|
||||
canvasGraphics.drawString(iterator, x, y);
|
||||
// FIXME: process map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(Shape s) {
|
||||
canvasGraphics.fill(s);
|
||||
appendShape(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
return canvasGraphics.getBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Composite getComposite() {
|
||||
return canvasGraphics.getComposite();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphicsConfiguration getDeviceConfiguration() {
|
||||
return canvasGraphics.getDeviceConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontRenderContext getFontRenderContext() {
|
||||
return canvasGraphics.getFontRenderContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Paint getPaint() {
|
||||
return canvasGraphics.getPaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRenderingHint(Key hintKey) {
|
||||
return canvasGraphics.getRenderingHint(hintKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderingHints getRenderingHints() {
|
||||
return canvasGraphics.getRenderingHints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stroke getStroke() {
|
||||
return canvasGraphics.getStroke();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffineTransform getTransform() {
|
||||
return canvasGraphics.getTransform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
|
||||
return canvasGraphics.hit(rect, s, onStroke);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(double theta) {
|
||||
canvasGraphics.rotate(theta);
|
||||
currentTx.rotate(theta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rotate(double theta, double x, double y) {
|
||||
canvasGraphics.rotate(theta, x, y);
|
||||
currentTx.rotate(theta, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scale(double sx, double sy) {
|
||||
canvasGraphics.scale(sx, sy);
|
||||
currentTx.scale(sx, sy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackground(Color color) {
|
||||
canvasGraphics.setBackground(color);
|
||||
// FIXME: fix map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComposite(Composite comp) {
|
||||
canvasGraphics.setComposite(comp);
|
||||
// FIXME: check this.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint(Paint paint) {
|
||||
canvasGraphics.setPaint(paint);
|
||||
// FIXME: check this
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRenderingHint(Key hintKey, Object hintValue) {
|
||||
canvasGraphics.setRenderingHint(hintKey, hintValue);
|
||||
// FIXME: check this
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRenderingHints(Map<?, ?> hints) {
|
||||
canvasGraphics.setRenderingHints(hints);
|
||||
// FIXME: check this
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStroke(Stroke s) {
|
||||
canvasGraphics.setStroke(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransform(AffineTransform Tx) {
|
||||
canvasGraphics.setTransform(Tx);
|
||||
currentTx = Tx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shear(double shx, double shy) {
|
||||
canvasGraphics.shear(shx, shy);
|
||||
currentTx.shear(shx, shy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(AffineTransform Tx) {
|
||||
canvasGraphics.transform(Tx);
|
||||
currentTx.concatenate(Tx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(int x, int y) {
|
||||
canvasGraphics.translate(x, y);
|
||||
currentTx.translate(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translate(double tx, double ty) {
|
||||
canvasGraphics.translate(tx, ty);
|
||||
currentTx.translate(tx, ty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearRect(int x, int y, int width, int height) {
|
||||
canvasGraphics.clearRect(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clipRect(int x, int y, int width, int height) {
|
||||
canvasGraphics.clipRect(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyArea(int x, int y, int width, int height, int dx, int dy) {
|
||||
canvasGraphics.copyArea(x, y, width, height, dx, dy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Graphics create() {
|
||||
return canvasGraphics.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
canvasGraphics.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
|
||||
canvasGraphics.drawArc(x, y, width, height, startAngle, arcAngle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
|
||||
boolean result = canvasGraphics.drawImage(img, x, y, observer);
|
||||
appendShape(new Rectangle2D.Double(x, y, img.getWidth(observer), img.getHeight(observer)));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return canvasGraphics.drawImage(img, x, y, bgcolor, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return canvasGraphics.drawImage(img, x, y, width, height, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor,
|
||||
ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return canvasGraphics.drawImage(img, x, y, width, height, bgcolor, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
|
||||
int sx2, int sy2, ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return canvasGraphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
|
||||
int sx2, int sy2, Color bgcolor, ImageObserver observer) {
|
||||
// FIXME: map
|
||||
return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLine(int x1, int y1, int x2, int y2) {
|
||||
canvasGraphics.drawLine(x1, y1, x2, y2);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new Line2D.Double(x1, y1, x2, y2));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawOval(int x, int y, int width, int height) {
|
||||
canvasGraphics.drawOval(x, y, width, height);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new Ellipse2D.Double(x, y, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPolygon(int[] points, int[] points2, int points3) {
|
||||
canvasGraphics.drawPolygon(points, points2, points3);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new Polygon(points, points2, points3));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawPolyline(int[] points, int[] points2, int points3) {
|
||||
canvasGraphics.drawPolyline(points, points2, points3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
|
||||
canvasGraphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
|
||||
canvasGraphics.fillArc(x, y, width, height, startAngle, arcAngle);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new Arc2D.Double(x, y, width, height, startAngle, arcAngle, Arc2D.PIE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillOval(int x, int y, int width, int height) {
|
||||
canvasGraphics.fillOval(x, y, width, height);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new Ellipse2D.Double(x, y, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillPolygon(int[] points, int[] points2, int points3) {
|
||||
canvasGraphics.fillPolygon(points, points2, points3);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new Polygon(points, points2, points3));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRect(int x, int y, int width, int height) {
|
||||
canvasGraphics.drawRect(x, y, width, height);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShapeOutline(new Rectangle(x, y, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRect(int x, int y, int width, int height) {
|
||||
canvasGraphics.fillRect(x, y, width, height);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new Rectangle(x, y, width, height));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
|
||||
canvasGraphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
|
||||
if (drawingComponent && trackingAllowed) {
|
||||
appendShape(new RoundRectangle2D.Double(x, y, width, height, arcWidth, arcHeight));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getClip() {
|
||||
return canvasGraphics.getClip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getClipBounds() {
|
||||
return canvasGraphics.getClipBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return canvasGraphics.getColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Font getFont() {
|
||||
return canvasGraphics.getFont();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontMetrics getFontMetrics(Font f) {
|
||||
return canvasGraphics.getFontMetrics(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClip(Shape clip) {
|
||||
canvasGraphics.setClip(clip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClip(int x, int y, int width, int height) {
|
||||
canvasGraphics.setClip(x, y, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(Color c) {
|
||||
canvasGraphics.setColor(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFont(Font font) {
|
||||
canvasGraphics.setFont(font);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaintMode() {
|
||||
canvasGraphics.setPaintMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setXORMode(Color c1) {
|
||||
canvasGraphics.setXORMode(c1);
|
||||
}
|
||||
}
|
||||
-456
@@ -1,456 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Point;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.components.boards.AbstractBoard;
|
||||
import org.diylc.components.boards.BlankBoard;
|
||||
import org.diylc.components.boards.PerfBoard;
|
||||
import org.diylc.components.boards.VeroBoard;
|
||||
import org.diylc.components.connectivity.CopperTrace;
|
||||
import org.diylc.components.connectivity.HookupWire;
|
||||
import org.diylc.components.connectivity.Jumper;
|
||||
import org.diylc.components.connectivity.SolderPad;
|
||||
import org.diylc.components.misc.Label;
|
||||
import org.diylc.components.passive.RadialElectrolytic;
|
||||
import org.diylc.components.passive.RadialFilmCapacitor;
|
||||
import org.diylc.components.passive.Resistor;
|
||||
import org.diylc.components.semiconductors.DIL_IC;
|
||||
import org.diylc.components.semiconductors.DiodePlastic;
|
||||
import org.diylc.components.semiconductors.LED;
|
||||
import org.diylc.components.semiconductors.TransistorTO92;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.measures.Capacitance;
|
||||
import org.diylc.core.measures.Resistance;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.diyfever.gui.simplemq.MessageDispatcher;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.io.xml.DomDriver;
|
||||
|
||||
public class ProjectFileManager {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ProjectFileManager.class);
|
||||
|
||||
// private static final int V1_PIXELS_PER_INCH = 200;
|
||||
private static final Size V1_GRID_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
private static final Map<String, Color> V1_COLOR_MAP = new HashMap<String, Color>();
|
||||
static {
|
||||
V1_COLOR_MAP.put("red", Color.red);
|
||||
V1_COLOR_MAP.put("blue", Color.blue);
|
||||
V1_COLOR_MAP.put("white", Color.white);
|
||||
V1_COLOR_MAP.put("green", Color.green.darker());
|
||||
V1_COLOR_MAP.put("black", Color.black);
|
||||
V1_COLOR_MAP.put("yellow", Color.yellow);
|
||||
}
|
||||
|
||||
private XStream xStream;
|
||||
// Legacy deserializer for 3.0.1 through 3.0.7, loads Points referenced in
|
||||
// pixels.
|
||||
private XStream xStreamOld;
|
||||
|
||||
private String currentFileName = null;
|
||||
private boolean modified = false;
|
||||
|
||||
private MessageDispatcher<EventType> messageDispatcher;
|
||||
|
||||
public ProjectFileManager(MessageDispatcher<EventType> messageDispatcher) {
|
||||
super();
|
||||
this.xStream = new XStream(new DomDriver());
|
||||
xStream.autodetectAnnotations(true);
|
||||
xStream.registerConverter(new PointConverter());
|
||||
this.xStreamOld = new XStream(new DomDriver());
|
||||
xStreamOld.autodetectAnnotations(true);
|
||||
this.messageDispatcher = messageDispatcher;
|
||||
}
|
||||
|
||||
public void startNewFile() {
|
||||
currentFileName = null;
|
||||
modified = false;
|
||||
fireFileStatusChanged();
|
||||
}
|
||||
|
||||
public 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);
|
||||
fos.close();
|
||||
if (!isBackup) {
|
||||
this.currentFileName = fileName;
|
||||
this.modified = false;
|
||||
fireFileStatusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Project deserializeProjectFromFile(String fileName, List<String> warnings)
|
||||
throws SAXException, IOException, ParserConfigurationException {
|
||||
LOG.info(String.format("loadProjectFromFile(%s)", fileName));
|
||||
Project project;
|
||||
File file = new File(fileName);
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
Document doc = db.parse(file);
|
||||
doc.getDocumentElement().normalize();
|
||||
if (doc.getDocumentElement().getNodeName().equalsIgnoreCase(Project.class.getName())) {
|
||||
project = parseV3File(fileName);
|
||||
} else {
|
||||
if (!doc.getDocumentElement().getNodeName().equalsIgnoreCase("layout")) {
|
||||
throw new IllegalArgumentException(
|
||||
"Could not open DIY file. Root node is not named 'Layout'.");
|
||||
}
|
||||
String formatVersion = doc.getDocumentElement().getAttribute("formatVersion");
|
||||
if (formatVersion == null || formatVersion.trim().isEmpty()) {
|
||||
LOG.debug("Detected v1 file.");
|
||||
project = parseV1File(doc.getDocumentElement(), warnings);
|
||||
} else if (formatVersion.equals("2.0")) {
|
||||
LOG.debug("Detected v2 file.");
|
||||
project = parseV2File(doc.getDocumentElement());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown file format version: " + formatVersion);
|
||||
}
|
||||
}
|
||||
Collections.sort(warnings);
|
||||
this.currentFileName = fileName;
|
||||
this.modified = false;
|
||||
return project;
|
||||
}
|
||||
|
||||
public void notifyFileChange() {
|
||||
this.modified = true;
|
||||
fireFileStatusChanged();
|
||||
}
|
||||
|
||||
public String getCurrentFileName() {
|
||||
return currentFileName;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return modified;
|
||||
}
|
||||
|
||||
public void fireFileStatusChanged() {
|
||||
messageDispatcher.dispatchMessage(EventType.FILE_STATUS_CHANGED, getCurrentFileName(),
|
||||
isModified());
|
||||
}
|
||||
|
||||
private Project parseV1File(Element root, List<String> warnings) {
|
||||
Project project = new Project();
|
||||
project.setTitle(root.getAttribute("Project"));
|
||||
project.setAuthor(root.getAttribute("Credits"));
|
||||
project.setGridSpacing(V1_GRID_SPACING);
|
||||
String type = root.getAttribute("Type");
|
||||
|
||||
// Create the board.
|
||||
int width = Integer.parseInt(root.getAttribute("Width")) + 1;
|
||||
int height = Integer.parseInt(root.getAttribute("Height")) + 1;
|
||||
int boardWidth = (int) (width * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue());
|
||||
int boardHeight = (int) (height * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue());
|
||||
int projectWidth = (int) project.getWidth().convertToPixels();
|
||||
int projectHeight = (int) project.getHeight().convertToPixels();
|
||||
int x = (projectWidth - boardWidth) / 2;
|
||||
int y = (projectHeight - boardHeight) / 2;
|
||||
AbstractBoard board;
|
||||
if (type.equalsIgnoreCase("pcb")) {
|
||||
board = new BlankBoard();
|
||||
board.setBoardColor(Color.white);
|
||||
board.setBorderColor(Color.black);
|
||||
} else if (type.equalsIgnoreCase("perfboard")) {
|
||||
board = new PerfBoard();
|
||||
} else if (type.equalsIgnoreCase("stripboard")) {
|
||||
board = new VeroBoard();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unrecognized board type: " + type);
|
||||
}
|
||||
board.setName("Main board");
|
||||
Point referencePoint = new Point(CalcUtils.roundToGrid(x, V1_GRID_SPACING), CalcUtils
|
||||
.roundToGrid(y, V1_GRID_SPACING));
|
||||
board.setControlPoint(referencePoint, 0);
|
||||
board.setControlPoint(new Point(CalcUtils.roundToGrid(x + boardWidth, V1_GRID_SPACING),
|
||||
CalcUtils.roundToGrid(y + boardHeight, V1_GRID_SPACING)), 1);
|
||||
project.getComponents().add(board);
|
||||
|
||||
NodeList childNodes = root.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
String nodeName = node.getNodeName();
|
||||
String nameAttr = node.getAttributes().getNamedItem("Name").getNodeValue();
|
||||
Node valueNode = node.getAttributes().getNamedItem("Value");
|
||||
String valueAttr = valueNode == null ? null : valueNode.getNodeValue();
|
||||
int x1Attr = Integer.parseInt(node.getAttributes().getNamedItem("X1")
|
||||
.getNodeValue());
|
||||
int y1Attr = Integer.parseInt(node.getAttributes().getNamedItem("Y1")
|
||||
.getNodeValue());
|
||||
Point point1 = convertV1CoordinatesToV3Point(referencePoint, x1Attr, y1Attr);
|
||||
Point point2 = null;
|
||||
Integer x2Attr = null;
|
||||
Integer y2Attr = null;
|
||||
Color color = null;
|
||||
if (node.getAttributes().getNamedItem("Color") != null) {
|
||||
String colorAttr = node.getAttributes().getNamedItem("Color").getNodeValue();
|
||||
color = V1_COLOR_MAP.get(colorAttr.toLowerCase());
|
||||
}
|
||||
if (node.getAttributes().getNamedItem("X2") != null
|
||||
&& node.getAttributes().getNamedItem("Y2") != null) {
|
||||
x2Attr = Integer.parseInt(node.getAttributes().getNamedItem("X2")
|
||||
.getNodeValue());
|
||||
y2Attr = Integer.parseInt(node.getAttributes().getNamedItem("Y2")
|
||||
.getNodeValue());
|
||||
point2 = convertV1CoordinatesToV3Point(referencePoint, x2Attr, y2Attr);
|
||||
}
|
||||
IDIYComponent<?> component = null;
|
||||
if (nodeName.equalsIgnoreCase("text")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
Label label = new Label();
|
||||
label.setName(nameAttr);
|
||||
if (color != null) {
|
||||
label.setColor(color);
|
||||
}
|
||||
label.setText(valueAttr);
|
||||
label.setCenter(false);
|
||||
label.setControlPoint(convertV1CoordinatesToV3Point(referencePoint, x1Attr,
|
||||
y1Attr), 0);
|
||||
component = label;
|
||||
} else if (nodeName.equalsIgnoreCase("pad")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
SolderPad pad = new SolderPad();
|
||||
pad.setName(nameAttr);
|
||||
if (color != null) {
|
||||
pad.setColor(color);
|
||||
}
|
||||
pad.setControlPoint(convertV1CoordinatesToV3Point(referencePoint, x1Attr,
|
||||
y1Attr), 0);
|
||||
component = pad;
|
||||
} else if (nodeName.equalsIgnoreCase("trace")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
CopperTrace trace = new CopperTrace();
|
||||
trace.setName(nameAttr);
|
||||
if (color != null) {
|
||||
trace.setLeadColor(color);
|
||||
}
|
||||
trace.setControlPoint(point1, 0);
|
||||
trace.setControlPoint(point2, 1);
|
||||
component = trace;
|
||||
} else if (nodeName.equalsIgnoreCase("jumper")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
Jumper jumper = new Jumper();
|
||||
jumper.setName(nameAttr);
|
||||
jumper.setControlPoint(point1, 0);
|
||||
jumper.setControlPoint(point2, 1);
|
||||
component = jumper;
|
||||
} else if (nodeName.equalsIgnoreCase("wire")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
HookupWire wire = new HookupWire();
|
||||
Point midPoint = new Point((point1.x + point2.x) / 2, (point1.y + point2.y) / 2);
|
||||
wire.setName(nameAttr);
|
||||
wire.setControlPoint(point1, 0);
|
||||
wire.setControlPoint(midPoint, 1);
|
||||
wire.setControlPoint(midPoint, 2);
|
||||
wire.setControlPoint(point2, 3);
|
||||
component = wire;
|
||||
} else if (nodeName.equalsIgnoreCase("resistor")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
Resistor resistor = new Resistor();
|
||||
resistor.setName(nameAttr);
|
||||
try {
|
||||
resistor.setValue(Resistance.parseResistance(valueAttr));
|
||||
} 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.setControlPoint(point1, 0);
|
||||
resistor.setControlPoint(point2, 1);
|
||||
component = resistor;
|
||||
} else if (nodeName.equalsIgnoreCase("capacitor")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
RadialFilmCapacitor capacitor = new RadialFilmCapacitor();
|
||||
capacitor.setName(nameAttr);
|
||||
try {
|
||||
capacitor.setValue(Capacitance.parseCapacitance(valueAttr));
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not set value of " + nameAttr);
|
||||
}
|
||||
capacitor.setLength(new Size(6d, SizeUnit.mm));
|
||||
capacitor.setWidth(new Size(2d, SizeUnit.mm));
|
||||
capacitor.setControlPoint(point1, 0);
|
||||
capacitor.setControlPoint(point2, 1);
|
||||
component = capacitor;
|
||||
} else if (nodeName.equalsIgnoreCase("electrolyte")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
RadialElectrolytic capacitor = new RadialElectrolytic();
|
||||
capacitor.setName(nameAttr);
|
||||
try {
|
||||
capacitor.setValue(Capacitance.parseCapacitance(valueAttr));
|
||||
} 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")) {
|
||||
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));
|
||||
}
|
||||
capacitor.setControlPoint(point1, 0);
|
||||
capacitor.setControlPoint(point2, 1);
|
||||
component = capacitor;
|
||||
} else if (nodeName.equalsIgnoreCase("diode")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
DiodePlastic capacitor = new DiodePlastic();
|
||||
capacitor.setName(nameAttr);
|
||||
try {
|
||||
capacitor.setValue(valueAttr);
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not set value of " + nameAttr);
|
||||
}
|
||||
capacitor.setLength(new Size(6d, SizeUnit.mm));
|
||||
capacitor.setWidth(new Size(2d, SizeUnit.mm));
|
||||
capacitor.setControlPoint(point1, 0);
|
||||
capacitor.setControlPoint(point2, 1);
|
||||
component = capacitor;
|
||||
} else if (nodeName.equalsIgnoreCase("led")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
LED led = new LED();
|
||||
led.setName(nameAttr);
|
||||
led.setValue(valueAttr);
|
||||
led.setBodyColor(Color.red);
|
||||
led.setBorderColor(Color.red.darker());
|
||||
led.setLength(new Size(3d, SizeUnit.mm));
|
||||
led.setControlPoint(point1, 0);
|
||||
led.setControlPoint(point2, 1);
|
||||
component = led;
|
||||
} else if (nodeName.equalsIgnoreCase("transistor")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
TransistorTO92 transistor = new TransistorTO92();
|
||||
transistor.setName(nameAttr);
|
||||
try {
|
||||
transistor.setValue(valueAttr);
|
||||
} catch (Exception e) {
|
||||
LOG.debug("Could not set value of " + nameAttr);
|
||||
}
|
||||
transistor.setControlPoint(point1, 0);
|
||||
if (point1.y > point2.y) {
|
||||
transistor.setOrientation(Orientation._180);
|
||||
} else if (point1.y < point2.y) {
|
||||
transistor.setOrientation(Orientation.DEFAULT);
|
||||
} else if (point1.x < point2.x) {
|
||||
transistor.setOrientation(Orientation._270);
|
||||
} else if (point1.x > point2.x) {
|
||||
transistor.setOrientation(Orientation._90);
|
||||
}
|
||||
// capacitor.setControlPoint(point2, 1);
|
||||
component = transistor;
|
||||
} else if (nodeName.equalsIgnoreCase("ic")) {
|
||||
LOG.debug("Recognized " + nodeName);
|
||||
DIL_IC ic = new DIL_IC();
|
||||
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)));
|
||||
}
|
||||
}
|
||||
ic.setName(nameAttr);
|
||||
// Translate control points.
|
||||
for (int j = 0; j < ic.getControlPointCount(); j++) {
|
||||
Point p = new Point(ic.getControlPoint(j));
|
||||
p.translate(point1.x, point1.y);
|
||||
ic.setControlPoint(p, j);
|
||||
}
|
||||
ic.setValue(valueAttr);
|
||||
component = ic;
|
||||
} else {
|
||||
String message = "Could not recognize component type " + nodeName;
|
||||
LOG.debug(message);
|
||||
if (!warnings.contains(message)) {
|
||||
warnings.add(message);
|
||||
}
|
||||
}
|
||||
if (component != null) {
|
||||
project.getComponents().add(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(project.getComponents(), ComparatorFactory.getInstance()
|
||||
.getComponentZOrderComparator());
|
||||
return project;
|
||||
}
|
||||
|
||||
private Point convertV1CoordinatesToV3Point(Point reference, int x, int y) {
|
||||
Point point = new Point(reference);
|
||||
point.translate((int) (x * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue()),
|
||||
(int) (y * Constants.PIXELS_PER_INCH * V1_GRID_SPACING.getValue()));
|
||||
return point;
|
||||
}
|
||||
|
||||
private Project parseV2File(Element root) {
|
||||
Project project = new Project();
|
||||
String projectName = root.getAttribute("projectName");
|
||||
String credits = root.getAttribute("credits");
|
||||
String width = root.getAttribute("width");
|
||||
String height = root.getAttribute("height");
|
||||
NodeList childNodes = root.getChildNodes();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
if (node.getNodeName().equalsIgnoreCase("component")) {
|
||||
LOG.debug(node.getAttributes().getNamedItem("name").getNodeValue());
|
||||
} else {
|
||||
LOG.debug("Unrecognized node name found: " + node.getNodeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
private Project parseV3File(String fileName) throws IOException {
|
||||
Project project;
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
try {
|
||||
project = (Project) xStream.fromXML(fis);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Could not open with the new xStream, trying the old one");
|
||||
fis.close();
|
||||
fis = new FileInputStream(fileName);
|
||||
project = (Project) xStreamOld.fromXML(fis);
|
||||
}
|
||||
fis.close();
|
||||
return project;
|
||||
}
|
||||
}
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
package org.diylc.swing.gui;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.swing.gui.components.OverwritePromptFileChooser;
|
||||
import org.diylc.swing.gui.editor.PropertyEditorDialog;
|
||||
import org.diylc.swing.plugins.file.BomDialog;
|
||||
import org.diylc.swing.plugins.file.BomEntry;
|
||||
import org.diylc.swing.plugins.online.view.LoginDialog;
|
||||
import org.diylc.swing.plugins.online.view.NewUserDialog;
|
||||
import org.diylc.swing.plugins.online.view.UploadDialog;
|
||||
|
||||
import com.diyfever.gui.AboutDialog;
|
||||
import com.diyfever.gui.IFileChooserAccessory;
|
||||
import com.diyfever.gui.ProgressDialog;
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
public class DialogFactory {
|
||||
|
||||
private static DialogFactory instance;
|
||||
|
||||
private static final String PATH_KEY = "lastPath";
|
||||
|
||||
public static DialogFactory getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new DialogFactory();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private JFrame mainFrame;
|
||||
private File lastDirectory;
|
||||
|
||||
private DialogFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the frame to be used as dialog parent. This should be called prior
|
||||
* to any other methods in this class.
|
||||
*
|
||||
* @param mainFrame
|
||||
*/
|
||||
public void initialize(JFrame mainFrame) {
|
||||
this.mainFrame = mainFrame;
|
||||
String lastDirectoryPath = (String) ConfigurationManager.getInstance()
|
||||
.readString(PATH_KEY, null);
|
||||
if (lastDirectoryPath != null) {
|
||||
lastDirectory = new File(lastDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
public PropertyEditorDialog createPropertyEditorDialog(List<PropertyWrapper> properties,
|
||||
String title) {
|
||||
PropertyEditorDialog editor = new PropertyEditorDialog(mainFrame, properties, title);
|
||||
return editor;
|
||||
}
|
||||
|
||||
public BomDialog createBomDialog(List<BomEntry> bom) {
|
||||
BomDialog dialog = new BomDialog(mainFrame, bom);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public File showOpenDialog(FileFilter fileFilter, File initialFile, String defaultExtension,
|
||||
IFileChooserAccessory accessory) {
|
||||
JFileChooser openFileChooser = new JFileChooser();
|
||||
initializeFileChooser(openFileChooser, fileFilter, initialFile, defaultExtension, accessory);
|
||||
|
||||
int result = openFileChooser.showOpenDialog(mainFrame);
|
||||
|
||||
return processFileChooserResult(result, openFileChooser, defaultExtension);
|
||||
}
|
||||
|
||||
public File showSaveDialog(FileFilter fileFilter, File initialFile, String defaultExtension,
|
||||
IFileChooserAccessory accessory) {
|
||||
JFileChooser saveFileChooser = new OverwritePromptFileChooser();
|
||||
initializeFileChooser(saveFileChooser, fileFilter, initialFile, defaultExtension, accessory);
|
||||
|
||||
int result = saveFileChooser.showSaveDialog(mainFrame);
|
||||
|
||||
return processFileChooserResult(result, saveFileChooser, defaultExtension);
|
||||
}
|
||||
|
||||
private void initializeFileChooser(JFileChooser fileChooser, FileFilter fileFilter,
|
||||
File initialFile, String defaultExtension, IFileChooserAccessory accessory) {
|
||||
if (accessory != null) {
|
||||
accessory.install(fileChooser);
|
||||
}
|
||||
for (FileFilter filter : fileChooser.getChoosableFileFilters()) {
|
||||
fileChooser.removeChoosableFileFilter(filter);
|
||||
}
|
||||
if (fileChooser instanceof OverwritePromptFileChooser) {
|
||||
((OverwritePromptFileChooser) fileChooser).setFileFilter(fileFilter, defaultExtension);
|
||||
} else {
|
||||
fileChooser.setFileFilter(fileFilter);
|
||||
}
|
||||
if (lastDirectory != null) {
|
||||
fileChooser.setCurrentDirectory(lastDirectory);
|
||||
}
|
||||
fileChooser.setSelectedFile(initialFile);
|
||||
}
|
||||
|
||||
private File processFileChooserResult(int result, JFileChooser fileChooser,
|
||||
String defaultExtension) {
|
||||
fileChooser.setAccessory(null);
|
||||
if (result == JFileChooser.APPROVE_OPTION) {
|
||||
lastDirectory = fileChooser.getCurrentDirectory();
|
||||
ConfigurationManager.getInstance().writeValue(PATH_KEY,
|
||||
lastDirectory.getAbsolutePath());
|
||||
if (fileChooser.getSelectedFile().getAbsolutePath().contains(".")) {
|
||||
return fileChooser.getSelectedFile();
|
||||
} else {
|
||||
return new File(fileChooser.getSelectedFile().getAbsoluteFile() + "."
|
||||
+ defaultExtension);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public AboutDialog createAboutDialog(String appName, Icon icon, String version, String author,
|
||||
String url, String mail, String htmlContent) {
|
||||
AboutDialog dialog = new AboutDialog(mainFrame, appName, icon, version, author, url, mail,
|
||||
htmlContent);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public NewUserDialog createNewUserDialog() {
|
||||
NewUserDialog dialog = new NewUserDialog(mainFrame);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public LoginDialog createLoginDialog() {
|
||||
LoginDialog dialog = new LoginDialog(mainFrame);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public UploadDialog createUploadDialog() {
|
||||
UploadDialog dialog = new UploadDialog(mainFrame);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public ProgressDialog createProgressDialog(String title, String[] buttonCaptions,
|
||||
String description, boolean useProgress) {
|
||||
ProgressDialog dialog = new ProgressDialog(mainFrame, title, buttonCaptions, description,
|
||||
useProgress);
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
import com.diyfever.gui.FontChooserComboBox;
|
||||
|
||||
public class FontEditor extends FontChooserComboBox {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg = getBackground();
|
||||
|
||||
private final PropertyWrapper property;
|
||||
|
||||
public FontEditor(final PropertyWrapper property) {
|
||||
this.property = property;
|
||||
setSelectedItem(((Font) property.getValue()).getName());
|
||||
addItemListener(new ItemListener() {
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
property.setChanged(true);
|
||||
setBackground(oldBg);
|
||||
Font oldFont = (Font) FontEditor.this.property.getValue();
|
||||
Font newFont = new Font(getSelectedItem().toString(), oldFont.getStyle(),
|
||||
oldFont.getSize());
|
||||
FontEditor.this.property.setValue(newFont);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!property.isUnique()) {
|
||||
setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
package org.diylc.swing.gui.editor;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
import com.diyfever.gui.DoubleTextField;
|
||||
|
||||
public class IntEditor extends DoubleTextField {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Color oldBg = getBackground();
|
||||
|
||||
public IntEditor(final PropertyWrapper property) {
|
||||
setLayout(new BorderLayout());
|
||||
setValue((double) (Integer) property.getValue());
|
||||
addPropertyChangeListener(DoubleTextField.VALUE_PROPERTY, new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
property.setChanged(true);
|
||||
setBackground(oldBg);
|
||||
property.setValue(((Double) evt.getNewValue()).intValue());
|
||||
}
|
||||
});
|
||||
if (!property.isUnique()) {
|
||||
setBackground(Constants.MULTI_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.dnd.DragGestureEvent;
|
||||
import java.awt.dnd.DragGestureListener;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
/**
|
||||
* {@link DragGestureListener} for {@link CanvasPanel}.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class CanvasGestureListener implements DragGestureListener {
|
||||
|
||||
private IPlugInPort presenter;
|
||||
|
||||
public CanvasGestureListener(IPlugInPort presenter) {
|
||||
super();
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragGestureRecognized(DragGestureEvent dge) {
|
||||
presenter.dragStarted(dge.getDragOrigin(), dge.getTriggerEvent().isControlDown(), dge
|
||||
.getTriggerEvent().isShiftDown(), dge.getTriggerEvent().isAltDown());
|
||||
dge.startDrag(presenter.getCursorAt(dge.getDragOrigin()), new EmptyTransferable(),
|
||||
new CanvasSourceListener(presenter));
|
||||
}
|
||||
}
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
package org.diylc.swing.plugins.canvas;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.dnd.DnDConstants;
|
||||
import java.awt.dnd.DropTargetDragEvent;
|
||||
import java.awt.dnd.DropTargetDropEvent;
|
||||
import java.awt.dnd.DropTargetEvent;
|
||||
import java.awt.dnd.DropTargetListener;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
|
||||
/**
|
||||
* {@link DropTargetListener} for {@link CanvasPanel}.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class CanvasTargetListener implements DropTargetListener {
|
||||
|
||||
private IPlugInPort presenter;
|
||||
|
||||
// Cached values
|
||||
private Point currentPoint = null;
|
||||
private boolean lastAccept;
|
||||
|
||||
public CanvasTargetListener(IPlugInPort presenter) {
|
||||
super();
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragEnter(DropTargetDragEvent dtde) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragExit(DropTargetEvent dte) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragOver(DropTargetDragEvent dtde) {
|
||||
// If dragOver was previously called for this location use cached value.
|
||||
if (dtde.getLocation().equals(currentPoint)) {
|
||||
if (lastAccept) {
|
||||
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
|
||||
} else {
|
||||
dtde.rejectDrag();
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Transferable t = dtde.getTransferable();
|
||||
// if
|
||||
// (t.isDataFlavorSupported(SelectionTransferable.selectionFlavor))
|
||||
// {
|
||||
// if (currentPoint != null) {
|
||||
// List<IDIYComponent> selection = (List<IDIYComponent>) t
|
||||
// .getTransferData(SelectionTransferable.selectionFlavor);
|
||||
// Point startPoint = (Point) t
|
||||
// .getTransferData(PointTransferable.pointFlavor);
|
||||
// presenter.selectionMoved(dtde.getLocation().x
|
||||
// - currentPoint.x, dtde.getLocation().y
|
||||
// - currentPoint.y);
|
||||
// }
|
||||
// } else if
|
||||
// (t.isDataFlavorSupported(PointTransferable.pointFlavor)) {
|
||||
// Point startPoint = (Point) t
|
||||
// .getTransferData(PointTransferable.pointFlavor);
|
||||
// Point endPoint = dtde.getLocation();
|
||||
// presenter.setSelectionRect(Utils.createRectangle(startPoint,
|
||||
// endPoint));
|
||||
// }
|
||||
currentPoint = dtde.getLocation();
|
||||
if (presenter.dragOver(currentPoint)) {
|
||||
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
|
||||
lastAccept = true;
|
||||
} else {
|
||||
dtde.rejectDrag();
|
||||
lastAccept = false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
dtde.rejectDrag();
|
||||
lastAccept = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drop(DropTargetDropEvent dtde) {
|
||||
presenter.dragEnded(dtde.getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropActionChanged(DropTargetDragEvent dtde) {
|
||||
}
|
||||
}
|
||||
-180
@@ -1,180 +0,0 @@
|
||||
package org.diylc.swing.plugins.file;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.swing.gui.DialogFactory;
|
||||
|
||||
import com.diyfever.gui.export.TableExporter;
|
||||
import com.diyfever.gui.objecttable.ObjectListTable;
|
||||
|
||||
public class BomDialog extends JDialog {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private ObjectListTable<BomEntry> table;
|
||||
private JPanel toolbar;
|
||||
|
||||
public BomDialog(JFrame parent, List<BomEntry> bom) {
|
||||
super(parent, "Bill of Materials");
|
||||
setContentPane(createMainPanel());
|
||||
getTable().setData(bom);
|
||||
pack();
|
||||
setLocationRelativeTo(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
super.setVisible(b);
|
||||
if (b) {
|
||||
getTable().autoFit(Arrays.asList(3));
|
||||
}
|
||||
}
|
||||
|
||||
private JPanel createMainPanel() {
|
||||
JPanel mainPanel = new JPanel();
|
||||
mainPanel.setLayout(new BorderLayout());
|
||||
mainPanel.add(getToolbar(), BorderLayout.NORTH);
|
||||
mainPanel.add(new JScrollPane(getTable()), BorderLayout.CENTER);
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private ObjectListTable<BomEntry> getTable() {
|
||||
if (table == null) {
|
||||
try {
|
||||
table = new ObjectListTable<BomEntry>(BomEntry.class, new String[] { "getName",
|
||||
"getValue", "getQuantity", "getNotes/setNotes" }, null);
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
private JPanel getToolbar() {
|
||||
if (toolbar == null) {
|
||||
toolbar = new JPanel();
|
||||
toolbar.add(new JButton(new SaveToExcelAction()));
|
||||
toolbar.add(new JButton(new SaveToCSVAction()));
|
||||
toolbar.add(new JButton(new SaveToPNGAction()));
|
||||
toolbar.add(new JButton(new SaveToHTMLAction()));
|
||||
}
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
class SaveToExcelAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SaveToExcelAction() {
|
||||
super();
|
||||
putValue(Action.NAME, "Save to Excel");
|
||||
putValue(Action.SMALL_ICON, IconLoader.Excel.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
File file = DialogFactory.getInstance().showSaveDialog(
|
||||
FileFilterEnum.EXCEL.getFilter(), null,
|
||||
FileFilterEnum.EXCEL.getExtensions()[0], null);
|
||||
if (file != null) {
|
||||
try {
|
||||
TableExporter.getInstance().exportToExcel(getTable(), file);
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SaveToCSVAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SaveToCSVAction() {
|
||||
super();
|
||||
putValue(Action.NAME, "Save to CSV");
|
||||
putValue(Action.SMALL_ICON, IconLoader.CSV.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
File file = DialogFactory.getInstance().showSaveDialog(FileFilterEnum.CSV.getFilter(),
|
||||
null, FileFilterEnum.CSV.getExtensions()[0], null);
|
||||
if (file != null) {
|
||||
try {
|
||||
TableExporter.getInstance().exportToCSV(getTable(), file);
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SaveToHTMLAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SaveToHTMLAction() {
|
||||
super();
|
||||
putValue(Action.NAME, "Save to HTML");
|
||||
putValue(Action.SMALL_ICON, IconLoader.HTML.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
File file = DialogFactory.getInstance().showSaveDialog(FileFilterEnum.HTML.getFilter(),
|
||||
null, FileFilterEnum.HTML.getExtensions()[0], null);
|
||||
if (file != null) {
|
||||
try {
|
||||
TableExporter.getInstance().exportToHTML(getTable(), file);
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SaveToPNGAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SaveToPNGAction() {
|
||||
super();
|
||||
putValue(Action.NAME, "Save to PNG");
|
||||
putValue(Action.SMALL_ICON, IconLoader.Image.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
File file = DialogFactory.getInstance().showSaveDialog(FileFilterEnum.PNG.getFilter(),
|
||||
null, FileFilterEnum.PNG.getExtensions()[0], null);
|
||||
if (file != null) {
|
||||
try {
|
||||
TableExporter.getInstance().exportToPNG(getTable(), file);
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
package org.diylc.swing.plugins.file;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.diylc.common.DrawOption;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
|
||||
import com.diyfever.gui.IDrawingProvider;
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* {@link IDrawingProvider} implementation that uses {@link IPlugInPort} to draw
|
||||
* a project onto the canvas.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class ProjectDrawingProvider implements IDrawingProvider {
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private boolean useZoom;
|
||||
private boolean showGridWhenNeeded;
|
||||
|
||||
public ProjectDrawingProvider(IPlugInPort plugInPort, boolean useZoom,
|
||||
boolean showGridWhenNeeded) {
|
||||
super();
|
||||
this.plugInPort = plugInPort;
|
||||
this.useZoom = useZoom;
|
||||
this.showGridWhenNeeded = showGridWhenNeeded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics g) {
|
||||
EnumSet<DrawOption> drawOptions = EnumSet.of(DrawOption.ANTIALIASING);
|
||||
if (useZoom) {
|
||||
drawOptions.add(DrawOption.ZOOM);
|
||||
}
|
||||
if (showGridWhenNeeded
|
||||
&& ConfigurationManager.getInstance().readBoolean(IPlugInPort.EXPORT_GRID_KEY,
|
||||
false)) {
|
||||
drawOptions.add(DrawOption.GRID);
|
||||
}
|
||||
if (ConfigurationManager.getInstance().readBoolean(IPlugInPort.OUTLINE_KEY, false)) {
|
||||
drawOptions.add(DrawOption.OUTLINE_MODE);
|
||||
}
|
||||
plugInPort.draw((Graphics2D) g, drawOptions, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getSize() {
|
||||
return plugInPort.getCanvasDimensions(useZoom);
|
||||
}
|
||||
}
|
||||
-120
@@ -1,120 +0,0 @@
|
||||
package org.diylc.swing.plugins.help;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
import org.diylc.swing.gui.DialogFactory;
|
||||
|
||||
import com.diyfever.gui.AboutDialog;
|
||||
import com.diyfever.gui.LinkLabel;
|
||||
import com.diyfever.gui.miscutils.Utils;
|
||||
|
||||
/**
|
||||
* Entry point class for help-related utilities.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class HelpMenuPlugin implements IPlugIn {
|
||||
|
||||
private static final String HELP_TITLE = "Help";
|
||||
|
||||
public static String MANUAL_URL = "http://code.google.com/p/diy-layout-creator/wiki/Manual";
|
||||
public static String FAQ_URL = "http://code.google.com/p/diy-layout-creator/wiki/FAQ";
|
||||
public static String COMPONENT_URL = "http://code.google.com/p/diy-layout-creator/wiki/ComponentAPI";
|
||||
public static String PLUGIN_URL = "http://code.google.com/p/diy-layout-creator/wiki/PluginAPI";
|
||||
public static String BUG_URL = "http://code.google.com/p/diy-layout-creator/issues/entry";
|
||||
public static String DONATE_URL = "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=25161";
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private AboutDialog aboutDialog;
|
||||
|
||||
public HelpMenuPlugin(ISwingUI swingUI) {
|
||||
swingUI.injectMenuAction(new NavigateURLAction("User Manual", IconLoader.Manual.getIcon(),
|
||||
MANUAL_URL), HELP_TITLE);
|
||||
swingUI.injectMenuAction(new NavigateURLAction("FAQ", IconLoader.Faq.getIcon(), FAQ_URL),
|
||||
HELP_TITLE);
|
||||
swingUI.injectMenuAction(new NavigateURLAction("Component API", IconLoader.Component
|
||||
.getIcon(), COMPONENT_URL), HELP_TITLE);
|
||||
swingUI.injectMenuAction(new NavigateURLAction("Plugin API", IconLoader.Plugin.getIcon(),
|
||||
PLUGIN_URL), HELP_TITLE);
|
||||
swingUI.injectMenuAction(new NavigateURLAction("Submit a Bug", IconLoader.Bug.getIcon(),
|
||||
BUG_URL), HELP_TITLE);
|
||||
swingUI.injectMenuAction(null, HELP_TITLE);
|
||||
swingUI.injectMenuAction(new NavigateURLAction("Donate", IconLoader.Donate.getIcon(),
|
||||
DONATE_URL), HELP_TITLE);
|
||||
swingUI.injectMenuAction(new AboutAction(), HELP_TITLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessage(EventType eventType, Object... params) {
|
||||
}
|
||||
|
||||
private AboutDialog getAboutDialog() {
|
||||
if (aboutDialog == null) {
|
||||
aboutDialog = DialogFactory.getInstance().createAboutDialog("DIY Layout Creator",
|
||||
IconLoader.IconLarge.getIcon(),
|
||||
plugInPort.getCurrentVersionNumber().toString(), "Branislav Stojkovic",
|
||||
"https://github.com/bancika/diy-layout-creator", "bancika@gmail.com", "");
|
||||
}
|
||||
return aboutDialog;
|
||||
}
|
||||
|
||||
class AboutAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AboutAction() {
|
||||
super();
|
||||
putValue(AbstractAction.NAME, "About");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.About.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
getAboutDialog().setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
class NavigateURLAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String url;
|
||||
|
||||
public NavigateURLAction(String name, Icon icon, String url) {
|
||||
super();
|
||||
this.url = url;
|
||||
putValue(AbstractAction.NAME, name);
|
||||
putValue(AbstractAction.SMALL_ICON, icon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
Utils.openURL(url);
|
||||
} catch (Exception e1) {
|
||||
Logger.getLogger(LinkLabel.class).error("Could not launch default browser", e1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
package org.diylc.swing.plugins.online;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.swing.gui.DialogFactory;
|
||||
import org.diylc.swing.plugins.online.presenter.LibraryPresenter;
|
||||
import org.diylc.swing.plugins.online.view.LoginDialog;
|
||||
import org.diylc.swing.plugins.online.view.NewUserDialog;
|
||||
import org.diylc.swing.plugins.online.view.UploadDialog;
|
||||
|
||||
import com.diyfever.gui.ProgressDialog;
|
||||
|
||||
public class OnlineManager implements IPlugIn {
|
||||
|
||||
private static final String ONLINE_TITLE = "Online";
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
private LibraryPresenter libraryPresenter;
|
||||
|
||||
@Override
|
||||
public void connect(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
this.libraryPresenter = new LibraryPresenter();
|
||||
|
||||
initialize();
|
||||
|
||||
// plugInPort.injectMenuAction(new LibraryAction(), ONLINE_TITLE);
|
||||
// plugInPort.injectMenuAction(null, ONLINE_TITLE);
|
||||
// plugInPort.injectMenuAction(new LoginAction(), ONLINE_TITLE);
|
||||
// plugInPort.injectMenuAction(new CreateAccountAction(), ONLINE_TITLE);
|
||||
// plugInPort.injectMenuAction(null, ONLINE_TITLE);
|
||||
// plugInPort.injectMenuAction(new UploadAction(), ONLINE_TITLE);
|
||||
// plugInPort.injectMenuAction(new ManageProjectsAction(), ONLINE_TITLE);
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground() throws Exception {
|
||||
libraryPresenter.connectDb();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
if (libraryPresenter.isLoggedIn()) {
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
worker.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessage(EventType eventType, Object... params) {
|
||||
}
|
||||
|
||||
class LibraryAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public LibraryAction() {
|
||||
super();
|
||||
putValue(AbstractAction.NAME, "Browse Library");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Chest.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
}
|
||||
}
|
||||
|
||||
class LoginAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public LoginAction() {
|
||||
super();
|
||||
putValue(AbstractAction.NAME, "Log in");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.IdCard.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
LoginDialog dialog = DialogFactory.getInstance().createLoginDialog();
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
class CreateAccountAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CreateAccountAction() {
|
||||
super();
|
||||
putValue(AbstractAction.NAME, "Create New Account");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.IdCardAdd.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
NewUserDialog dialog = DialogFactory.getInstance().createNewUserDialog();
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
class UploadAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public UploadAction() {
|
||||
super();
|
||||
putValue(AbstractAction.NAME, "Upload Project");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Upload.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
UploadDialog dialog = DialogFactory.getInstance().createUploadDialog();
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
class ManageProjectsAction extends AbstractAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ManageProjectsAction() {
|
||||
super();
|
||||
putValue(AbstractAction.NAME, "Manage Projects");
|
||||
putValue(AbstractAction.SMALL_ICON, IconLoader.Wrench.getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ProgressDialog dialog = DialogFactory.getInstance().createProgressDialog("Test",
|
||||
new String[] {}, "Some text", false);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
package org.diylc.swing.plugins.online.view;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import com.diyfever.gui.ButtonDialog;
|
||||
|
||||
public class LoginDialog extends ButtonDialog {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private JPanel mainPanel;
|
||||
|
||||
private JTextField userNameField;
|
||||
private JPasswordField passwordField;
|
||||
|
||||
private String userName;
|
||||
private String password;
|
||||
|
||||
public LoginDialog(JFrame owner) {
|
||||
super(owner, "Login", new String[] { OK, CANCEL });
|
||||
setMinimumSize(new Dimension(240, 32));
|
||||
layoutGui();
|
||||
refreshState();
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getMainComponent() {
|
||||
if (mainPanel == null) {
|
||||
mainPanel = new JPanel(new GridBagLayout());
|
||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
|
||||
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.anchor = GridBagConstraints.LINE_START;
|
||||
gbc.fill = GridBagConstraints.NONE;
|
||||
gbc.insets = new Insets(2, 2, 2, 2);
|
||||
|
||||
gbc.gridx = 0;
|
||||
|
||||
gbc.gridy = 0;
|
||||
mainPanel.add(new JLabel("User Name:"), gbc);
|
||||
|
||||
gbc.gridy = 1;
|
||||
mainPanel.add(new JLabel("Password:"), gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc.weightx = 1;
|
||||
|
||||
gbc.gridy = 0;
|
||||
mainPanel.add(getUserNameField(), gbc);
|
||||
|
||||
gbc.gridy = 1;
|
||||
mainPanel.add(getPasswordField(), gbc);
|
||||
}
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private void refreshState() {
|
||||
this.userName = getUserNameField().getText();
|
||||
this.password = new String(getPasswordField().getPassword());
|
||||
|
||||
JButton okButton = getButton(OK);
|
||||
okButton.setEnabled((this.userName.length() > 0) && (this.password.length() > 0));
|
||||
}
|
||||
|
||||
private JTextField getUserNameField() {
|
||||
if (userNameField == null) {
|
||||
userNameField = new JTextField();
|
||||
userNameField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
});
|
||||
}
|
||||
return userNameField;
|
||||
}
|
||||
|
||||
private JPasswordField getPasswordField() {
|
||||
if (passwordField == null) {
|
||||
passwordField = new JPasswordField();
|
||||
passwordField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
});
|
||||
}
|
||||
return passwordField;
|
||||
}
|
||||
}
|
||||
-210
@@ -1,210 +0,0 @@
|
||||
package org.diylc.swing.plugins.online.view;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import com.diyfever.gui.ButtonDialog;
|
||||
|
||||
public class NewUserDialog extends ButtonDialog {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private JPanel mainPanel;
|
||||
|
||||
private JTextField userNameField;
|
||||
private JPasswordField passwordField;
|
||||
private JPasswordField confirmPasswordField;
|
||||
private JTextField emailField;
|
||||
|
||||
private String userName;
|
||||
private String password;
|
||||
private String email;
|
||||
|
||||
public NewUserDialog(JFrame owner) {
|
||||
super(owner, "New Account", new String[] { OK, CANCEL });
|
||||
setMinimumSize(new Dimension(240, 32));
|
||||
layoutGui();
|
||||
refreshState();
|
||||
userNameField.setText(System.getProperty("user.name"));
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getMainComponent() {
|
||||
if (mainPanel == null) {
|
||||
mainPanel = new JPanel(new GridBagLayout());
|
||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
|
||||
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.anchor = GridBagConstraints.LINE_START;
|
||||
gbc.fill = GridBagConstraints.NONE;
|
||||
gbc.insets = new Insets(2, 2, 2, 2);
|
||||
|
||||
gbc.gridx = 0;
|
||||
|
||||
gbc.gridy = 0;
|
||||
mainPanel.add(new JLabel("User Name:"), gbc);
|
||||
|
||||
gbc.gridy = 1;
|
||||
mainPanel.add(new JLabel("Password:"), gbc);
|
||||
|
||||
gbc.gridy = 2;
|
||||
mainPanel.add(new JLabel("Confirm Password:"), gbc);
|
||||
|
||||
gbc.gridy = 3;
|
||||
mainPanel.add(new JLabel("eMail:"), gbc);
|
||||
|
||||
gbc.gridx = 1;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc.weightx = 1;
|
||||
|
||||
gbc.gridy = 0;
|
||||
mainPanel.add(getUserNameField(), gbc);
|
||||
|
||||
gbc.gridy = 1;
|
||||
mainPanel.add(getPasswordField(), gbc);
|
||||
|
||||
gbc.gridy = 2;
|
||||
mainPanel.add(getConfirmPasswordField(), gbc);
|
||||
|
||||
gbc.gridy = 3;
|
||||
mainPanel.add(getEmailField(), gbc);
|
||||
}
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private void refreshState() {
|
||||
this.userName = getUserNameField().getText();
|
||||
String password = new String(getPasswordField().getPassword());
|
||||
String confirmPassword = new String(getConfirmPasswordField().getPassword());
|
||||
if (password.equals(confirmPassword)) {
|
||||
this.password = password;
|
||||
} else {
|
||||
this.password = null;
|
||||
}
|
||||
this.email = getEmailField().getText();
|
||||
JButton okButton = getButton(OK);
|
||||
okButton.setEnabled((this.userName.length() > 0) && (this.password != null)
|
||||
&& (this.password.length() > 0));
|
||||
}
|
||||
|
||||
private JTextField getUserNameField() {
|
||||
if (userNameField == null) {
|
||||
userNameField = new JTextField();
|
||||
userNameField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
});
|
||||
}
|
||||
return userNameField;
|
||||
}
|
||||
|
||||
private JPasswordField getPasswordField() {
|
||||
if (passwordField == null) {
|
||||
passwordField = new JPasswordField();
|
||||
passwordField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
});
|
||||
}
|
||||
return passwordField;
|
||||
}
|
||||
|
||||
private JPasswordField getConfirmPasswordField() {
|
||||
if (confirmPasswordField == null) {
|
||||
confirmPasswordField = new JPasswordField();
|
||||
confirmPasswordField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
});
|
||||
}
|
||||
return confirmPasswordField;
|
||||
}
|
||||
|
||||
private JTextField getEmailField() {
|
||||
if (emailField == null) {
|
||||
emailField = new JTextField();
|
||||
emailField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
});
|
||||
}
|
||||
return emailField;
|
||||
}
|
||||
}
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
package org.diylc.swing.plugins.online.view;
|
||||
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import com.diyfever.gui.ButtonDialog;
|
||||
|
||||
public class UploadDialog extends ButtonDialog {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String BULLET = " • ";
|
||||
private static final String TERMS_HTML = "<html><b>Terms of Service</b><br><br>"
|
||||
+ BULLET
|
||||
+ "Online Library is provided free of charge for DIY Layout Creator users.<br>"
|
||||
+ BULLET
|
||||
+ "Only finished and verified projects may be uploaded to the library. Online Library is <b>not</b> a repository for unfinished projects and temprary work.<br>"
|
||||
+ BULLET
|
||||
+ "Projects uploaded to the library may be reviewed, modified or deleted by the administrator without notice.<br>"
|
||||
+ BULLET
|
||||
+ "Once uploaded, project becomes avaialble to all other users. Anyone may use the project, modify it and upload modified version. When modifying an existing projects credit for the original author must be left.<br>"
|
||||
+ BULLET
|
||||
+ "You can <b>not</b> use Online Library to advertise products or services.<br>"
|
||||
+ BULLET
|
||||
+ "Users that do not follow these terms may be banned from the server, with or without notice.<br>"
|
||||
+ BULLET + "Administrator is not responsible for library contents.<br>" + "</html>";
|
||||
|
||||
private JPanel mainPanel;
|
||||
private JLabel termsLabel;
|
||||
private JCheckBox agreeBox;
|
||||
|
||||
public UploadDialog(JFrame owner) {
|
||||
super(owner, "Upload", new String[] { OK, CANCEL });
|
||||
layoutGui();
|
||||
refreshState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getMainComponent() {
|
||||
if (mainPanel == null) {
|
||||
mainPanel = new JPanel(new GridBagLayout());
|
||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
|
||||
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.anchor = GridBagConstraints.LINE_START;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
gbc.weightx = 1;
|
||||
gbc.weighty = 1;
|
||||
gbc.insets = new Insets(2, 2, 2, 2);
|
||||
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
mainPanel.add(getTermsLabel(), gbc);
|
||||
|
||||
gbc.gridy = 1;
|
||||
gbc.anchor = GridBagConstraints.CENTER;
|
||||
gbc.fill = GridBagConstraints.NONE;
|
||||
gbc.weightx = 0;
|
||||
gbc.weighty = 0;
|
||||
mainPanel.add(getAgreeBox(), gbc);
|
||||
}
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private void refreshState() {
|
||||
getButton(OK).setEnabled(getAgreeBox().isSelected());
|
||||
}
|
||||
|
||||
private JCheckBox getAgreeBox() {
|
||||
if (agreeBox == null) {
|
||||
agreeBox = new JCheckBox("I agree to these terms");
|
||||
agreeBox.addChangeListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
refreshState();
|
||||
}
|
||||
});
|
||||
}
|
||||
return agreeBox;
|
||||
}
|
||||
|
||||
private JLabel getTermsLabel() {
|
||||
if (termsLabel == null) {
|
||||
termsLabel = new JLabel();
|
||||
termsLabel.setOpaque(true);
|
||||
termsLabel.setBackground(UIManager.getColor("ToolTip.background"));
|
||||
termsLabel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
|
||||
.createEtchedBorder(), BorderFactory.createEmptyBorder(2, 2, 2, 2)));
|
||||
termsLabel.setText(TERMS_HTML);
|
||||
}
|
||||
return termsLabel;
|
||||
}
|
||||
}
|
||||
-301
@@ -1,301 +0,0 @@
|
||||
package org.diylc.swing.plugins.statusbar;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.Format;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.BadPositionException;
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.images.IconLoader;
|
||||
import org.diylc.presenter.Presenter;
|
||||
import org.diylc.swing.ISwingUI;
|
||||
|
||||
import com.diyfever.gui.MemoryBar;
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
import com.diyfever.gui.miscutils.PercentageListCellRenderer;
|
||||
import com.diyfever.gui.miscutils.Utils;
|
||||
import com.diyfever.gui.update.UpdateLabel;
|
||||
|
||||
public class StatusBar extends JPanel implements IPlugIn {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(StatusBar.class);
|
||||
|
||||
public static String UPDATE_URL = "http://www.diy-fever.com/update.xml";
|
||||
private static final Format sizeFormat = new DecimalFormat("0.##");
|
||||
|
||||
private JComboBox zoomBox;
|
||||
private UpdateLabel updateLabel;
|
||||
private MemoryBar memoryPanel;
|
||||
private JLabel statusLabel;
|
||||
private JLabel sizeLabel;
|
||||
|
||||
private IPlugInPort plugInPort;
|
||||
|
||||
// State variables
|
||||
private ComponentType componentSlot;
|
||||
private Point controlPointSlot;
|
||||
private List<String> componentNamesUnderCursor;
|
||||
private List<String> selectedComponentNames;
|
||||
private List<String> stuckComponentNames;
|
||||
private String statusMessage;
|
||||
|
||||
public StatusBar(ISwingUI swingUI) {
|
||||
super();
|
||||
|
||||
setLayout(new GridBagLayout());
|
||||
|
||||
try {
|
||||
swingUI.injectGUIComponent(this, SwingUtilities.BOTTOM);
|
||||
} catch (BadPositionException e) {
|
||||
LOG.error("Could not install status bar", e);
|
||||
}
|
||||
}
|
||||
|
||||
private JComboBox getZoomBox() {
|
||||
if (zoomBox == null) {
|
||||
zoomBox = new JComboBox(plugInPort.getAvailableZoomLevels());
|
||||
zoomBox.setSelectedItem(plugInPort.getZoomLevel());
|
||||
zoomBox.setFocusable(false);
|
||||
zoomBox.setRenderer(new PercentageListCellRenderer());
|
||||
zoomBox.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
plugInPort.setZoomLevel((Double) zoomBox.getSelectedItem());
|
||||
}
|
||||
});
|
||||
}
|
||||
return zoomBox;
|
||||
}
|
||||
|
||||
private UpdateLabel getUpdateLabel() {
|
||||
if (updateLabel == null) {
|
||||
updateLabel = new UpdateLabel(plugInPort.getCurrentVersionNumber(), UPDATE_URL);
|
||||
// updateLabel.setBorder(BorderFactory.createCompoundBorder(
|
||||
// BorderFactory.createEtchedBorder(), BorderFactory
|
||||
// .createEmptyBorder(2, 4, 2, 4)));
|
||||
updateLabel.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4));
|
||||
}
|
||||
return updateLabel;
|
||||
}
|
||||
|
||||
private MemoryBar getMemoryPanel() {
|
||||
if (memoryPanel == null) {
|
||||
memoryPanel = new MemoryBar(false);
|
||||
}
|
||||
return memoryPanel;
|
||||
}
|
||||
|
||||
private JLabel getStatusLabel() {
|
||||
if (statusLabel == null) {
|
||||
statusLabel = new JLabel();
|
||||
statusLabel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0));
|
||||
}
|
||||
return statusLabel;
|
||||
}
|
||||
|
||||
public JLabel getSizeLabel() {
|
||||
if (sizeLabel == null) {
|
||||
sizeLabel = new JLabel(IconLoader.Size.getIcon());
|
||||
sizeLabel.setFocusable(true);
|
||||
sizeLabel.setToolTipText("Click to calculate selection size");
|
||||
sizeLabel.addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
Point2D size = plugInPort.calculateSelectionDimension();
|
||||
boolean metric = ConfigurationManager.getInstance().readBoolean(
|
||||
Presenter.METRIC_KEY, true);
|
||||
String text;
|
||||
if (size == null) {
|
||||
text = "Selection is empty.";
|
||||
} else {
|
||||
text = "Selection size: " + sizeFormat.format(size.getX()) + " x "
|
||||
+ sizeFormat.format(size.getY()) + (metric ? " cm" : " in");
|
||||
}
|
||||
JOptionPane.showMessageDialog(SwingUtilities.getRootPane(StatusBar.this), text,
|
||||
"Information", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
return sizeLabel;
|
||||
}
|
||||
|
||||
private void layoutComponents() {
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = 0;
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc.weightx = 1;
|
||||
add(getStatusLabel(), gbc);
|
||||
|
||||
JPanel zoomPanel = new JPanel(new BorderLayout());
|
||||
zoomPanel.add(new JLabel("Zoom: "), BorderLayout.WEST);
|
||||
zoomPanel.add(getZoomBox(), BorderLayout.CENTER);
|
||||
// zoomPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory
|
||||
// .createEtchedBorder(), BorderFactory.createEmptyBorder(2, 4, 2,
|
||||
// 4)));
|
||||
zoomPanel.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4));
|
||||
|
||||
gbc.gridx = 1;
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
gbc.weightx = 0;
|
||||
add(zoomPanel, gbc);
|
||||
|
||||
gbc.gridx = 2;
|
||||
add(getSizeLabel(), gbc);
|
||||
|
||||
gbc.gridx = 3;
|
||||
add(getUpdateLabel(), gbc);
|
||||
|
||||
gbc.gridx = 4;
|
||||
gbc.fill = GridBagConstraints.NONE;
|
||||
add(getMemoryPanel(), gbc);
|
||||
|
||||
gbc.gridx = 5;
|
||||
add(new JPanel(), gbc);
|
||||
}
|
||||
|
||||
// IPlugIn
|
||||
|
||||
@Override
|
||||
public void connect(IPlugInPort plugInPort) {
|
||||
this.plugInPort = plugInPort;
|
||||
|
||||
layoutComponents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<EventType> getSubscribedEventTypes() {
|
||||
return EnumSet.of(EventType.ZOOM_CHANGED, EventType.SLOT_CHANGED,
|
||||
EventType.AVAILABLE_CTRL_POINTS_CHANGED, EventType.SELECTION_CHANGED,
|
||||
EventType.STATUS_MESSAGE_CHANGED);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void processMessage(EventType eventType, Object... params) {
|
||||
switch (eventType) {
|
||||
case ZOOM_CHANGED:
|
||||
if (!params[0].equals(getZoomBox().getSelectedItem())) {
|
||||
final Double zoom = (Double) params[0];
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
getZoomBox().setSelectedItem(zoom);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case SELECTION_CHANGED:
|
||||
List<IDIYComponent<?>> selection = (List<IDIYComponent<?>>) params[0];
|
||||
Collection<IDIYComponent<?>> stuckComponents = (Collection<IDIYComponent<?>>) params[1];
|
||||
Collection<String> componentNames = new HashSet<String>();
|
||||
for (IDIYComponent<?> component : selection) {
|
||||
componentNames.add("<font color='blue'>" + component.getName() + "</font>");
|
||||
}
|
||||
this.selectedComponentNames = new ArrayList<String>(componentNames);
|
||||
Collections.sort(this.selectedComponentNames);
|
||||
this.stuckComponentNames = new ArrayList<String>();
|
||||
for (IDIYComponent<?> component : stuckComponents) {
|
||||
this.stuckComponentNames.add("<font color='blue'>" + component.getName()
|
||||
+ "</font>");
|
||||
}
|
||||
this.stuckComponentNames.removeAll(this.selectedComponentNames);
|
||||
Collections.sort(this.stuckComponentNames);
|
||||
refreshStatusText();
|
||||
break;
|
||||
case SLOT_CHANGED:
|
||||
componentSlot = (ComponentType) params[0];
|
||||
controlPointSlot = (Point) params[1];
|
||||
refreshStatusText();
|
||||
break;
|
||||
case AVAILABLE_CTRL_POINTS_CHANGED:
|
||||
componentNamesUnderCursor = new ArrayList<String>();
|
||||
for (IDIYComponent<?> component : ((Map<IDIYComponent<?>, Integer>) params[0]).keySet()) {
|
||||
componentNamesUnderCursor.add("<font color='blue'>" + component.getName()
|
||||
+ "</font>");
|
||||
}
|
||||
Collections.sort(componentNamesUnderCursor);
|
||||
refreshStatusText();
|
||||
break;
|
||||
case STATUS_MESSAGE_CHANGED:
|
||||
statusMessage = (String) params[0];
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshStatusText() {
|
||||
String statusText = this.statusMessage;
|
||||
if (componentSlot == null) {
|
||||
if (componentNamesUnderCursor != null && !componentNamesUnderCursor.isEmpty()) {
|
||||
String formattedNames = Utils.toCommaString(componentNamesUnderCursor);
|
||||
statusText = "<html>Drag control point(s) of " + formattedNames + "</html>";
|
||||
} else if (selectedComponentNames != null && !selectedComponentNames.isEmpty()) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(Utils.toCommaString(selectedComponentNames));
|
||||
if (!stuckComponentNames.isEmpty()) {
|
||||
builder.append(" (hold <b>Ctrl</b> and drag to unstuck from ");
|
||||
builder.append(Utils.toCommaString(stuckComponentNames));
|
||||
builder.append(")");
|
||||
}
|
||||
statusText = "<html>Selection: " + builder.toString() + "</html>";
|
||||
}
|
||||
} else {
|
||||
switch (componentSlot.getCreationMethod()) {
|
||||
case POINT_BY_POINT:
|
||||
String count;
|
||||
if (controlPointSlot == null) {
|
||||
count = "first";
|
||||
} else {
|
||||
count = "second";
|
||||
}
|
||||
statusText = "<html>Click on the canvas to set the " + count
|
||||
+ " control point of a new <font color='blue'>" + componentSlot.getName()
|
||||
+ "</font> or press <b>Esc</b> to cancel</html>";
|
||||
break;
|
||||
case SINGLE_CLICK:
|
||||
statusText = "<html>Click on the canvas to create a new <font color='blue'>"
|
||||
+ componentSlot.getName() + "</font> or press <b>Esc</b> to cancel</html>";
|
||||
break;
|
||||
}
|
||||
}
|
||||
final String finalStatus = statusText;
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
getStatusLabel().setText(finalStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package org.diylc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
import org.apache.log4j.BasicConfigurator;
|
||||
import org.diylc.swing.plugins.online.model.ProjectEntity;
|
||||
|
||||
import com.diyfever.gui.objecttable.IActionProcessor;
|
||||
import com.diyfever.gui.objecttable.ObjectListTable;
|
||||
|
||||
public class TableTest {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
BasicConfigurator.configure();
|
||||
|
||||
List<ProjectEntity> projects = new ArrayList<ProjectEntity>();
|
||||
projects.add(new ProjectEntity(1, "first", "some text", "bane", "none"));
|
||||
projects.add(new ProjectEntity(2, "second", "anoter text", "bisera", "none"));
|
||||
|
||||
ObjectListTable<ProjectEntity> t = new ObjectListTable<ProjectEntity>(ProjectEntity.class,
|
||||
new String[] { "getName", "getDescription", "getCategory", "getOwner",
|
||||
"action:Download" }, new IActionProcessor<ProjectEntity>() {
|
||||
|
||||
@Override
|
||||
public void actionExecuted(ProjectEntity value, String actionColumnName) {
|
||||
System.out.println("row clicked: " + actionColumnName + " - " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getActionIcon(String actionColumnName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActionLabel(String actionColumnName) {
|
||||
return "get me";
|
||||
}
|
||||
});
|
||||
t.setData(projects);
|
||||
JFrame f = new JFrame();
|
||||
f.add(new JScrollPane(t));
|
||||
f.pack();
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
f.setVisible(true);
|
||||
}
|
||||
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
package org.diylc.plugins.file;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.components.MockDIYComponent;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.measures.Capacitance;
|
||||
import org.diylc.core.measures.CapacitanceUnit;
|
||||
import org.diylc.swing.plugins.file.BomEntry;
|
||||
import org.diylc.swing.plugins.file.BomMaker;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BomMakerTest {
|
||||
|
||||
@Test
|
||||
public void testCreateBom() {
|
||||
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
|
||||
MockDIYComponent c1 = new MockDIYComponent();
|
||||
c1.setValue(new Capacitance(3d, CapacitanceUnit.pF));
|
||||
components.add(c1);
|
||||
components.add(new MockDIYComponent());
|
||||
components.add(new MockDIYComponent());
|
||||
List<BomEntry> bom = BomMaker.getInstance().createBom(components);
|
||||
assertNotNull(bom);
|
||||
assertEquals(2, bom.size());
|
||||
BomEntry entry1 = bom.get(0);
|
||||
assertEquals("something", entry1.getName());
|
||||
assertEquals(2, (int) entry1.getQuantity());
|
||||
BomEntry entry2 = bom.get(1);
|
||||
assertEquals("something", entry2.getName());
|
||||
assertEquals(1, (int) entry2.getQuantity());
|
||||
}
|
||||
}
|
||||
@@ -1,373 +0,0 @@
|
||||
<java.util.Arrays_-ArrayList>
|
||||
<a class="com.diyfever.gui.update.Version-array">
|
||||
<com.diyfever.gui.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
<build>4</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2011-01-27 21:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Copy/paste between two instances of the application</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Parsing numerical values in countries that use comma as decimal separator</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Dragging sticky points affects selectability of objects</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Click is sometimes not registered while adding a new component</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Fixed NPE when using default values</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Allow shape control points of curves to overlap</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Added DIL IC first pin indentation</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Added transparency to the potentiometer</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Reduced number of layers</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Import from v1 files can now read label and electrolytic capacitor components and trace/pad colors</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Added worker thread for longer file operation, so GUI doesn't freeze</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added right click menu on the canvas</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added "send to back" and "bring to front" options</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added label component</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added image component</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list
|
||||
</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
<build>5</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2011-01-30 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Curved trace does not show control points</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Potentiometer draws wrong at 180 degrees</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Reset component selection when tab is changed</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Resistor can show color bands</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Electrolytic capacitor has a new icon and new looks</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Solder pad can be square</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Added keyboard shortcuts to some menu options</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>V1 file importer can recognize hookup wire and transistors</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added support for creating and loading templates</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added TO-92 transistor</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added TO-220 transistor</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added LED</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added axial electrolytic capacitor</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
<build>6</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2011-02-07 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Copy/paste doesn't work for some components (potentiometer, transistor, etc)</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Resistor color codes are sometimes wrong</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Resistors can specify power handling</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Capacitors can specify voltage handling</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Fixed lead alignment issue</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Better scaling, grid lines are more precise</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved performance</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added resistor schematic symbol</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added capacitor schematic symbol</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added eyelet/turret component</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added Marshall/Trainwreck style boards</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added few types of trimmers</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Configurable rendering quality to improve speed</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
<build>7</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2011-02-27 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Resistor and capacitor symbols are not clickable</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Boards sometimes render holes/pads on the edge</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Download link doesn't work on Mac</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Ruler ticks don't always match with the grid</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Micro symbol doesn't get exported to PDF</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>DIL IC now has more pin options</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Send to Back/Bring to Front are more flexible and renamed to match what they do</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Auto-save project and restore if app crashes</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added support for themes</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Added tube socket</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Sticky points may be turned off</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Snap to Grid may be turned off</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Auto-create solder pads</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Auto-edit mode</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Continuous component creation</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
<build>8</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2011-03-03 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Sometimes it's not possible to click on a component, especially when layout is large</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Curved traces and wires can have 2, 3 and 4 control points</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Switchable wheel zoom</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Automatic standing resistors, capacitors and diodes</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Vertical vero board</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Label has editable font</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
<com.diyfever.gui.update.Version>
|
||||
<versionNumber>
|
||||
<major>3</major>
|
||||
<minor>0</minor>
|
||||
<build>9</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2011-08-28 20:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Auto-created solder pads aren't assigned with default settings and name</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Component edit dialog allows changing property values even when they are not the same. Boxes are marked yellow to designate multi-valued state.</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Component edit dialog should show mutual properties when components of different types are selected (e.g. curved trace and straight trace width)</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Ctrl+click should not clear selection when clicked on the canvas</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Increased PNG export resolution</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Auto-increment component names when copy-pasting</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Do not attempt to write auto-save files if user does not have permissions to create files</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Allow zero ohm resistors</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Outline mode that resembles PCB silkscreen</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Double click on a component button in the toolbar selects all components of that type</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Renumber selected components by X or Y axis</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
<com.diyfever.gui.update.Change>
|
||||
<changeType>NEW_FEATURE</changeType>
|
||||
<description>Recently used components in the toolbar for easy navigation</description>
|
||||
</com.diyfever.gui.update.Change>
|
||||
</changes>
|
||||
<url>http://code.google.com/p/diy-layout-creator/downloads/list</url>
|
||||
</com.diyfever.gui.update.Version>
|
||||
</a>
|
||||
</java.util.Arrays_-ArrayList>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<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/bancika-gui-framework.jar"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/DIYLC"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -1 +0,0 @@
|
||||
/bin/
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Library</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
Binary file not shown.
Binary file not shown.
-124
@@ -1,124 +0,0 @@
|
||||
package org.diylc.components.boards;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.components.AbstractTransparentComponent;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.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;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
public abstract class AbstractBoard extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color BOARD_COLOR = Color.decode("#F8EBB3");
|
||||
public static Color BORDER_COLOR = BOARD_COLOR.darker();
|
||||
public static Size DEFAULT_WIDTH = new Size(1.5d, SizeUnit.in);
|
||||
public static Size DEFAULT_HEIGHT = new Size(1.2d, SizeUnit.in);
|
||||
|
||||
protected String value = "";
|
||||
protected Point[] controlPoints = new Point[] {
|
||||
new Point(0, 0),
|
||||
new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels()) };
|
||||
protected Point firstPoint = new Point();
|
||||
protected Point secondPoint = new Point();
|
||||
|
||||
protected Color boardColor = BOARD_COLOR;
|
||||
protected Color borderColor = BORDER_COLOR;
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
g2d.setColor(boardColor);
|
||||
g2d.fillRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y
|
||||
- firstPoint.y);
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
g2d.setColor(componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : borderColor);
|
||||
g2d.drawRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y
|
||||
- firstPoint.y);
|
||||
// Do not track any changes that follow because the whole board has been
|
||||
// tracked so far.
|
||||
drawingObserver.stopTracking();
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Color")
|
||||
public Color getBoardColor() {
|
||||
return boardColor;
|
||||
}
|
||||
|
||||
public void setBoardColor(Color boardColor) {
|
||||
this.boardColor = boardColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Border")
|
||||
public Color getBorderColor() {
|
||||
return borderColor;
|
||||
}
|
||||
|
||||
public void setBorderColor(Color borderColor) {
|
||||
this.borderColor = borderColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
firstPoint.setLocation(Math.min(controlPoints[0].x, controlPoints[1].x), Math.min(
|
||||
controlPoints[0].y, controlPoints[1].y));
|
||||
secondPoint.setLocation(Math.max(controlPoints[0].x, controlPoints[1].x), Math.max(
|
||||
controlPoints[0].y, controlPoints[1].y));
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
package org.diylc.components.passive;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Capacitance;
|
||||
import org.diylc.core.measures.CapacitanceUnit;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
@ComponentDescriptor(name = "Film Capacitor (axial)", author = "Branislav Stojkovic", category = "Passive", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "C", description = "Axial film capacitor, similar to Mallory 150s", zOrder = IDIYComponent.COMPONENT)
|
||||
public class AxialFilmCapacitor extends AbstractLeadedComponent<Capacitance> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Size DEFAULT_WIDTH = new Size(1d / 2, SizeUnit.in);
|
||||
public static Size DEFAULT_HEIGHT = new Size(1d / 8, SizeUnit.in);
|
||||
public static Color BODY_COLOR = Color.decode("#FFE303");
|
||||
public static Color BORDER_COLOR = BODY_COLOR.darker();
|
||||
|
||||
private Capacitance value = new Capacitance(22d, CapacitanceUnit.nF);
|
||||
private Voltage voltage = Voltage._63V;
|
||||
|
||||
public AxialFilmCapacitor() {
|
||||
super();
|
||||
this.bodyColor = BODY_COLOR;
|
||||
this.borderColor = BORDER_COLOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsStandingMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Capacitance getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Capacitance value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Voltage getVoltage() {
|
||||
return voltage;
|
||||
}
|
||||
|
||||
public void setVoltage(Voltage voltage) {
|
||||
this.voltage = voltage;
|
||||
}
|
||||
|
||||
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
|
||||
g2d.setColor(LEAD_COLOR);
|
||||
g2d.drawLine(0, height / 2, width, height / 2);
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRect(4, height / 2 - 3, width - 8, 6);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRect(4, height / 2 - 3, width - 8, 6);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Size getDefaultWidth() {
|
||||
return DEFAULT_HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Size getDefaultLength() {
|
||||
return DEFAULT_WIDTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shape getBodyShape() {
|
||||
return new Rectangle2D.Double(0f, 0f, getLength().convertToPixels(),
|
||||
getClosestOdd(getWidth().convertToPixels()));
|
||||
}
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package org.diylc.components.passive;
|
||||
|
||||
public enum Power {
|
||||
|
||||
EIGHT("1/8W"), QUARTER("1/4W"), HALF("1/2W"), ONE("1W"), TWO("2W"), FIVE("5W"), TEN("10W"), FIFTY(
|
||||
"50W"), HUNDRED("100W");
|
||||
|
||||
String label;
|
||||
|
||||
Power(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
package org.diylc.components.passive;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.ResistorColorCode;
|
||||
import org.diylc.components.AbstractLeadedComponent;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.PositiveMeasureValidator;
|
||||
import org.diylc.core.measures.Resistance;
|
||||
import org.diylc.core.measures.ResistanceUnit;
|
||||
import org.diylc.core.measures.Size;
|
||||
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)
|
||||
public class Resistor extends AbstractLeadedComponent<Resistance> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Size DEFAULT_WIDTH = new Size(1d / 2, SizeUnit.in);
|
||||
public static Size DEFAULT_HEIGHT = new Size(1d / 8, SizeUnit.in);
|
||||
public static Color BODY_COLOR = Color.decode("#82CFFD");
|
||||
public static Color BORDER_COLOR = BODY_COLOR.darker();
|
||||
|
||||
private Resistance value = new Resistance(123d, ResistanceUnit.K);
|
||||
private Power power = Power.HALF;
|
||||
private ResistorColorCode colorCode = ResistorColorCode._5_BAND;
|
||||
|
||||
public Resistor() {
|
||||
super();
|
||||
this.bodyColor = BODY_COLOR;
|
||||
this.borderColor = BORDER_COLOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsStandingMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@EditableProperty(validatorClass = PositiveMeasureValidator.class)
|
||||
public Resistance getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Resistance value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Power getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
public void setPower(Power power) {
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
|
||||
g2d.setColor(LEAD_COLOR);
|
||||
g2d.drawLine(0, height / 2, width, height / 2);
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fillRect(4, height / 2 - 3, width - 8, 6);
|
||||
g2d.setColor(Color.red);
|
||||
g2d.drawLine(7, height / 2 - 3, 7, height / 2 + 3);
|
||||
g2d.setColor(Color.orange);
|
||||
g2d.drawLine(11, height / 2 - 3, 11, height / 2 + 3);
|
||||
g2d.setColor(Color.black);
|
||||
g2d.drawLine(15, height / 2 - 3, 15, height / 2 + 3);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.drawRect(4, height / 2 - 3, width - 8, 6);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Size getDefaultWidth() {
|
||||
return DEFAULT_HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Size getDefaultLength() {
|
||||
return DEFAULT_WIDTH;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Color code")
|
||||
public ResistorColorCode getColorCode() {
|
||||
return colorCode;
|
||||
}
|
||||
|
||||
public void setColorCode(ResistorColorCode colorCode) {
|
||||
this.colorCode = colorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shape getBodyShape() {
|
||||
return new Rectangle2D.Double(0f, 0f, getLength().convertToPixels(),
|
||||
getClosestOdd(getWidth().convertToPixels()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
|
||||
// int width = getWidth().convertToPixels();
|
||||
if (colorCode == ResistorColorCode.NONE || outlineMode) {
|
||||
return;
|
||||
}
|
||||
int height = getClosestOdd(getWidth().convertToPixels());
|
||||
Color[] bands = value.getColorCode(colorCode);
|
||||
int x = 4;
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
||||
for (int i = 0; i < bands.length; i++) {
|
||||
g2d.setColor(bands[i]);
|
||||
g2d.drawLine(x, 1, x, height - 1);
|
||||
x += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
package org.diylc.components.passive;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.GeneralPath;
|
||||
|
||||
import org.diylc.components.AbstractSchematicLeadedSymbol;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.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)
|
||||
public class ResistorSymbol extends AbstractSchematicLeadedSymbol<Resistance> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Size DEFAULT_LENGTH = new Size(0.3, SizeUnit.in);
|
||||
public static Size DEFAULT_WIDTH = new Size(0.08, SizeUnit.in);
|
||||
|
||||
private Resistance value = new Resistance(100d, ResistanceUnit.K);
|
||||
private Power power = Power.HALF;
|
||||
|
||||
@EditableProperty
|
||||
public Resistance getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Resistance value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Power getPower() {
|
||||
return power;
|
||||
}
|
||||
|
||||
public void setPower(Power power) {
|
||||
this.power = power;
|
||||
}
|
||||
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.rotate(-Math.PI / 4, width / 2, height / 2);
|
||||
g2d.setColor(LEAD_COLOR);
|
||||
g2d.drawLine(0, height / 2, 4, height / 2);
|
||||
g2d.drawLine(width - 4, height / 2, width, height / 2);
|
||||
g2d.setColor(COLOR);
|
||||
g2d.drawPolyline(new int[] { 4, 6, 10, 14, 18, 22, 26, 28 }, new int[] { height / 2,
|
||||
height / 2 + 2, height / 2 - 2, height / 2 + 2, height / 2 - 2, height / 2 + 2,
|
||||
height / 2 - 2, height / 2 }, 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Size getDefaultWidth() {
|
||||
return DEFAULT_WIDTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Size getDefaultLength() {
|
||||
return DEFAULT_LENGTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shape getBodyShape() {
|
||||
GeneralPath polyline = new GeneralPath();
|
||||
double length = getLength().convertToPixels();
|
||||
double width = getWidth().convertToPixels();
|
||||
polyline.moveTo(0, width / 2);
|
||||
polyline.lineTo(length / 16, width);
|
||||
polyline.lineTo(3 * length / 16, 0);
|
||||
polyline.lineTo(5 * length / 16, width);
|
||||
polyline.lineTo(7 * length / 16, 0);
|
||||
polyline.lineTo(9 * length / 16, width);
|
||||
polyline.lineTo(11 * length / 16, 0);
|
||||
polyline.lineTo(13 * length / 16, width);
|
||||
polyline.lineTo(15 * length / 16, 0);
|
||||
polyline.lineTo(length, width / 2);
|
||||
return polyline;
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package org.diylc.components.passive;
|
||||
|
||||
public enum Voltage {
|
||||
|
||||
_16V, _25V, _63V, _100V, _160V, _250V, _300V, _350V, _400V, _500V, _630V, _1KV;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().replace("_", "");
|
||||
}
|
||||
}
|
||||
-328
@@ -1,328 +0,0 @@
|
||||
package org.diylc.components.tube;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
|
||||
import org.diylc.common.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;
|
||||
|
||||
import com.diyfever.gui.miscutils.ConfigurationManager;
|
||||
|
||||
@ComponentDescriptor(name = "Tube Socket", author = "Branislav Stojkovic", category = "Tubes", instanceNamePrefix = "V", description = "Various types of tube/valve sockets", stretchable = false, zOrder = IDIYComponent.COMPONENT)
|
||||
public class TubeSocket extends AbstractTransparentComponent<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static Color BODY_COLOR = Color.decode("#FFFFE0");
|
||||
private static Color BORDER_COLOR = Color.decode("#8E8E38");
|
||||
public static Color PIN_COLOR = Color.decode("#00B2EE");
|
||||
public static Color PIN_BORDER_COLOR = PIN_COLOR.darker();
|
||||
public static Size PIN_SIZE = new Size(1d, SizeUnit.mm);
|
||||
public static Size HOLE_SIZE = new Size(5d, SizeUnit.mm);
|
||||
public static Size TICK_SIZE = new Size(2d, SizeUnit.mm);
|
||||
|
||||
private Base base = Base.B9A;
|
||||
private String type = "";
|
||||
private Orientation orientation = Orientation.DEFAULT;
|
||||
// private Mount mount = Mount.CHASSIS;
|
||||
|
||||
private Point[] controlPoints = new Point[] { new Point(0, 0) };
|
||||
|
||||
transient private Shape body;
|
||||
|
||||
public TubeSocket() {
|
||||
super();
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Base getBase() {
|
||||
return base;
|
||||
}
|
||||
|
||||
public void setBase(Base base) {
|
||||
this.base = base;
|
||||
updateControlPoints();
|
||||
// Reset body shape
|
||||
body = null;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Orientation getOrientation() {
|
||||
return orientation;
|
||||
}
|
||||
|
||||
public void setOrientation(Orientation orientation) {
|
||||
this.orientation = orientation;
|
||||
updateControlPoints();
|
||||
// Reset body shape
|
||||
body = null;
|
||||
}
|
||||
|
||||
// @EditableProperty
|
||||
// public Mount getMount() {
|
||||
// return mount;
|
||||
// }
|
||||
//
|
||||
// public void setMount(Mount mount) {
|
||||
// this.mount = mount;
|
||||
// }
|
||||
|
||||
private void updateControlPoints() {
|
||||
Point firstPoint = controlPoints[0];
|
||||
int pinCount;
|
||||
int pinCircleDiameter;
|
||||
boolean hasEmptySpace;
|
||||
switch (base) {
|
||||
case B7G:
|
||||
pinCount = 7;
|
||||
pinCircleDiameter = getClosestOdd(new Size(12d, SizeUnit.mm).convertToPixels());
|
||||
hasEmptySpace = true;
|
||||
break;
|
||||
case OCTAL:
|
||||
pinCount = 8;
|
||||
pinCircleDiameter = getClosestOdd(new Size(17.5d, SizeUnit.mm).convertToPixels());
|
||||
hasEmptySpace = false;
|
||||
break;
|
||||
case B9A:
|
||||
pinCount = 9;
|
||||
pinCircleDiameter = getClosestOdd(new Size(21d, SizeUnit.mm).convertToPixels());
|
||||
hasEmptySpace = true;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected base: " + base);
|
||||
}
|
||||
double angleIncrement = Math.PI * 2 / (hasEmptySpace ? (pinCount + 1) : pinCount);
|
||||
double initialAngleOffset = hasEmptySpace ? angleIncrement : (angleIncrement / 2);
|
||||
double initialAngle;
|
||||
switch (orientation) {
|
||||
case DEFAULT:
|
||||
initialAngle = Math.PI / 2 + initialAngleOffset;
|
||||
break;
|
||||
case _90:
|
||||
initialAngle = Math.PI + initialAngleOffset;
|
||||
break;
|
||||
case _180:
|
||||
initialAngle = 3 * Math.PI / 2 + initialAngleOffset;
|
||||
break;
|
||||
case _270:
|
||||
initialAngle = initialAngleOffset;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected orientation: " + orientation);
|
||||
}
|
||||
controlPoints = new Point[pinCount + 1];
|
||||
double angle = initialAngle;
|
||||
controlPoints[0] = firstPoint;
|
||||
for (int i = 0; i < pinCount; i++) {
|
||||
controlPoints[i + 1] = new Point((int) (firstPoint.getX() + Math.cos(angle)
|
||||
* pinCircleDiameter / 2), (int) (firstPoint.getY() + Math.sin(angle)
|
||||
* pinCircleDiameter / 2));
|
||||
angle += angleIncrement;
|
||||
}
|
||||
}
|
||||
|
||||
public Shape getBody() {
|
||||
if (body == null) {
|
||||
int bodyDiameter;
|
||||
switch (base) {
|
||||
case B7G:
|
||||
bodyDiameter = getClosestOdd(new Size(17d, SizeUnit.mm).convertToPixels());
|
||||
break;
|
||||
case B9A:
|
||||
bodyDiameter = getClosestOdd(new Size(19d, SizeUnit.mm).convertToPixels());
|
||||
break;
|
||||
case OCTAL:
|
||||
bodyDiameter = getClosestOdd(new Size(24.5d, SizeUnit.mm).convertToPixels());
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected base: " + base);
|
||||
}
|
||||
body = new Ellipse2D.Double(controlPoints[0].x - bodyDiameter / 2, controlPoints[0].y
|
||||
- bodyDiameter / 2, bodyDiameter, bodyDiameter);
|
||||
Area bodyArea = new Area(body);
|
||||
int holeSize = getClosestOdd(HOLE_SIZE.convertToPixels());
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(controlPoints[0].x - holeSize / 2,
|
||||
controlPoints[0].y - holeSize / 2, holeSize, holeSize)));
|
||||
if (base == Base.OCTAL) {
|
||||
int tickSize = getClosestOdd(TICK_SIZE.convertToPixels());
|
||||
double angle = 0;
|
||||
switch (orientation) {
|
||||
case DEFAULT:
|
||||
angle = Math.PI / 2;
|
||||
break;
|
||||
case _90:
|
||||
angle = Math.PI;
|
||||
break;
|
||||
case _180:
|
||||
angle = 3 * Math.PI / 2;
|
||||
break;
|
||||
case _270:
|
||||
angle = 0;
|
||||
break;
|
||||
}
|
||||
int centerX = (int) (controlPoints[0].x + Math.cos(angle) * holeSize / 2);
|
||||
int centerY = (int) (controlPoints[0].y + Math.sin(angle) * holeSize / 2);
|
||||
bodyArea.subtract(new Area(new Ellipse2D.Double(centerX - tickSize / 2, centerY
|
||||
- tickSize / 2, tickSize, tickSize)));
|
||||
}
|
||||
body = bodyArea;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
// g2d.setColor(Color.black);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
// for (int i = 0; i < controlPoints.length; i++) {
|
||||
// g2d.drawString(Integer.toString(i), controlPoints[i].x,
|
||||
// controlPoints[i].y);
|
||||
// }
|
||||
// Draw body
|
||||
Shape body = getBody();
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
if (componentState != ComponentState.DRAGGING) {
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : BODY_COLOR);
|
||||
g2d.fill(body);
|
||||
}
|
||||
g2d.setComposite(oldComposite);
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(
|
||||
IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme
|
||||
.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : BORDER_COLOR;
|
||||
}
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body);
|
||||
// Draw pins
|
||||
if (!outlineMode) {
|
||||
int pinSize = getClosestOdd(PIN_SIZE.convertToPixels());
|
||||
for (int i = 1; i < controlPoints.length; i++) {
|
||||
g2d.setColor(PIN_COLOR);
|
||||
g2d.fillOval(controlPoints[i].x - pinSize / 2, controlPoints[i].y - pinSize / 2,
|
||||
pinSize, pinSize);
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.drawOval(controlPoints[i].x - pinSize / 2, controlPoints[i].y - pinSize / 2,
|
||||
pinSize, pinSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
Area area = new Area(new Ellipse2D.Double(1, 1, width - 2, width - 2));
|
||||
int center = width / 2;
|
||||
area.subtract(new Area(new Ellipse2D.Double(center - 2, center - 2, 5, 5)));
|
||||
g2d.setColor(BODY_COLOR);
|
||||
g2d.fill(area);
|
||||
g2d.setColor(BORDER_COLOR);
|
||||
g2d.draw(area);
|
||||
|
||||
int radius = width / 2 - 6;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int x = (int) (center + Math.cos(i * Math.PI / 4) * radius);
|
||||
int y = (int) (center + Math.sin(i * Math.PI / 4) * radius);
|
||||
g2d.setColor(PIN_COLOR);
|
||||
g2d.fillOval(x - 1, y - 1, 3, 3);
|
||||
g2d.setColor(PIN_BORDER_COLOR);
|
||||
g2d.drawOval(x - 1, y - 1, 3, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return controlPoints.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.NEVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
@EditableProperty(name = "Type")
|
||||
public String getValue() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.type = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
controlPoints[index].setLocation(point);
|
||||
body = null;
|
||||
}
|
||||
|
||||
static enum Base {
|
||||
B9A("Noval B9A"), OCTAL("Octal"), B7G("Small-button B7G");
|
||||
|
||||
String name;
|
||||
|
||||
private Base(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
static enum Mount {
|
||||
CHASSIS("Chassis"), PCB("PCB");
|
||||
|
||||
String name;
|
||||
|
||||
private Mount(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="test"/>
|
||||
<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
|
||||
<classpathentry kind="lib" path="lib/junit-4.7.jar"/>
|
||||
<classpathentry kind="lib" path="library/main.jar"/>
|
||||
<classpathentry kind="lib" path="lib/app-framework.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jettison-1.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/xstream-1.3.1.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.6.0_45"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -1 +0,0 @@
|
||||
/bin/
|
||||
Binary file not shown.
Binary file not shown.
-7
@@ -1,7 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public class BadPositionException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
-114
@@ -1,114 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
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.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @see IDIYComponent
|
||||
*/
|
||||
public class ComponentType {
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private CreationMethod creationMethod;
|
||||
private String category;
|
||||
private String namePrefix;
|
||||
private String author;
|
||||
private Icon icon;
|
||||
private Class<? extends IDIYComponent<?>> instanceClass;
|
||||
private double zOrder;
|
||||
private boolean flexibleZOrder;
|
||||
private boolean stretchable;
|
||||
private BomPolicy bomPolicy;
|
||||
private boolean autoEdit;
|
||||
private boolean rotatable;
|
||||
|
||||
public ComponentType(String name, String description, CreationMethod creationMethod,
|
||||
String category, String namePrefix, String author, Icon icon,
|
||||
Class<? extends IDIYComponent<?>> instanceClass, double zOrder, boolean flexibleZOrder,
|
||||
boolean stretchable, BomPolicy bomPolicy, boolean autoEdit, boolean rotatable) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.creationMethod = creationMethod;
|
||||
this.category = category;
|
||||
this.namePrefix = namePrefix;
|
||||
this.author = author;
|
||||
this.icon = icon;
|
||||
this.instanceClass = instanceClass;
|
||||
this.zOrder = zOrder;
|
||||
this.flexibleZOrder = flexibleZOrder;
|
||||
this.stretchable = stretchable;
|
||||
this.bomPolicy = bomPolicy;
|
||||
this.autoEdit = autoEdit;
|
||||
this.rotatable = rotatable;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public CreationMethod getCreationMethod() {
|
||||
return creationMethod;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public String getNamePrefix() {
|
||||
return namePrefix;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public Icon getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public Class<? extends IDIYComponent<?>> getInstanceClass() {
|
||||
return instanceClass;
|
||||
}
|
||||
|
||||
public double getZOrder() {
|
||||
return zOrder;
|
||||
}
|
||||
|
||||
public boolean isFlexibleZOrder() {
|
||||
return flexibleZOrder;
|
||||
}
|
||||
|
||||
public boolean isStretchable() {
|
||||
return stretchable;
|
||||
}
|
||||
|
||||
public BomPolicy getBomPolicy() {
|
||||
return bomPolicy;
|
||||
}
|
||||
|
||||
public boolean isAutoEdit() {
|
||||
return autoEdit;
|
||||
}
|
||||
|
||||
public boolean isRotatable() {
|
||||
return rotatable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum Display {
|
||||
|
||||
NAME, VALUE, NONE, BOTH;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.awt.Graphics;
|
||||
|
||||
/**
|
||||
* Enumerates all options that can be used when drawing a project.
|
||||
*
|
||||
* @see IPlugInPort#draw(java.awt.Graphics2D, java.util.Set, IComponentFiler)
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum DrawOption {
|
||||
|
||||
/**
|
||||
* Selection rectangle will be drawn when needed and selected components may
|
||||
* be rendered differently.
|
||||
*/
|
||||
SELECTION,
|
||||
/**
|
||||
* Selected zoom level will be applied to scale the {@link Graphics} before
|
||||
* drawing.
|
||||
*/
|
||||
ZOOM,
|
||||
/**
|
||||
* Grid lines are drawn.
|
||||
*/
|
||||
GRID,
|
||||
/**
|
||||
* Control points are drawn.
|
||||
*/
|
||||
CONTROL_POINTS,
|
||||
/**
|
||||
* Anti-aliasing is used when drawing.
|
||||
*/
|
||||
ANTIALIASING,
|
||||
/**
|
||||
* Draw components in outline mode.
|
||||
*/
|
||||
OUTLINE_MODE;
|
||||
}
|
||||
-83
@@ -1,83 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Point2D;
|
||||
|
||||
import org.diylc.core.Project;
|
||||
|
||||
/**
|
||||
* Enumerates all possible events between {@link IPlugInPort} and
|
||||
* {@link IPlugIn}. Some events overlap so be careful which ones you subscribe
|
||||
* for and how you process them.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum EventType {
|
||||
|
||||
/**
|
||||
* Called when zoom level changes. Typically only one parameter of type
|
||||
* {@link Double} is passed with new zoom level.
|
||||
*/
|
||||
ZOOM_CHANGED,
|
||||
/**
|
||||
* Called when a new project is loaded. New {@link Project} is the first
|
||||
* parameter. Boolean flag is the second parameter and it's true when new
|
||||
* project is loaded, false when the same project has been either reloaded
|
||||
* or loaded with undo/redo operations.
|
||||
*/
|
||||
PROJECT_LOADED,
|
||||
/**
|
||||
* Called when either current file name or modified flag are changed. The
|
||||
* first parameter is the current file name, the second one is a boolean
|
||||
* modified flag.
|
||||
*/
|
||||
FILE_STATUS_CHANGED,
|
||||
/**
|
||||
* Called when selection rectangle is changed. Object of type
|
||||
* {@link Rectangle} is the only parameter and it contains the new selection
|
||||
* rectangle.
|
||||
*/
|
||||
SELECTION_RECT_CHANGED,
|
||||
/**
|
||||
* Called when component selection is changed. New
|
||||
* {@link ComponentSelection} is attached as a parameter.
|
||||
*/
|
||||
SELECTION_CHANGED,
|
||||
/**
|
||||
* Called when selection size changes, together with a {@link Point2D}
|
||||
* object containing selection size (x = width, y = height). Size is
|
||||
* expressed in the default measure (cm for metric, inches for imperial).
|
||||
*/
|
||||
REPAINT,
|
||||
/**
|
||||
* Called when new component slot has been changed. The only parameter is
|
||||
* {@link ComponentType} and may be null.
|
||||
*/
|
||||
SLOT_CHANGED,
|
||||
/**
|
||||
* Called when the current project has been modified. Two instances of
|
||||
* {@link Project} are passed as parameters, one before and one after the
|
||||
* change. The third parameter is a string containing change description.
|
||||
*/
|
||||
PROJECT_MODIFIED,
|
||||
/**
|
||||
* Called when control points under the cursor are changed. A single
|
||||
* parameter is passed, an instance of
|
||||
* <code>Map<IDIYComponent<?>, Set<Integer>></code> containing all the
|
||||
* components and indices of their control points that are under the cursor.
|
||||
*/
|
||||
AVAILABLE_CTRL_POINTS_CHANGED,
|
||||
/**
|
||||
* Called when mouse cursor is moved. Point object is passed, containing the
|
||||
* current cursor location (not taking zoom into account).
|
||||
*/
|
||||
MOUSE_MOVED,
|
||||
/**
|
||||
* Called when a layer status is changed. The first parameter is a set of indices of locked layers. All layers not included are considered unlocked.
|
||||
*/
|
||||
LAYER_STATE_CHANGED,
|
||||
/**
|
||||
* Called to update the status message. New status message is passed as a first parameter.
|
||||
*/
|
||||
STATUS_MESSAGE_CHANGED;
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum GridType {
|
||||
|
||||
LINES, CROSSHAIR, DOT, NONE;
|
||||
}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum HorizontalAlignment {
|
||||
LEFT, CENTER, RIGHT;
|
||||
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
public interface IComponentFiler {
|
||||
|
||||
boolean testComponent(IDIYComponent<?> component);
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
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);
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
/**
|
||||
* Abstract layer between the app and platform worker thread implementation.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public interface ITask<T> {
|
||||
|
||||
/**
|
||||
* Runs in background thread.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
T doInBackground() throws Exception;
|
||||
|
||||
/**
|
||||
* Called if background thread fails.
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
void failed(Exception e);
|
||||
|
||||
/**
|
||||
* Called if background thread is executed correctly, the result is passed
|
||||
* as a parameter.
|
||||
*
|
||||
* @param result
|
||||
*/
|
||||
void complete(T result);
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.core.Template;
|
||||
|
||||
public interface ITemplateProcessor {
|
||||
|
||||
public static final String TEMPLATES_KEY = "templates";
|
||||
|
||||
void saveSelectedComponentAsTemplate(String templateName);
|
||||
|
||||
List<Template> getTemplatesFor(String categoryName, String componentTypeName);
|
||||
|
||||
List<Template> getTemplatesForSelection();
|
||||
|
||||
void applyTemplateToSelection(Template template);
|
||||
|
||||
void deleteTemplate(String categoryName, String componentTypeName, String templateName);
|
||||
|
||||
public class TemplateAlreadyExistsException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum LabelPosition {
|
||||
|
||||
ABOVE, BELOW;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Stroke;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Repository for object that may be reused, such as {@link Stroke} or
|
||||
* {@link AlphaComposite}.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class ObjectCache {
|
||||
|
||||
private static ObjectCache instance;
|
||||
|
||||
public static ObjectCache getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ObjectCache();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ObjectCache() {
|
||||
}
|
||||
|
||||
private Map<Integer, Stroke> basicStrokeMap = new HashMap<Integer, Stroke>();
|
||||
|
||||
public Stroke fetchBasicStroke(int width) {
|
||||
if (basicStrokeMap.containsKey(width)) {
|
||||
return basicStrokeMap.get(width);
|
||||
}
|
||||
Stroke stroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
|
||||
basicStrokeMap.put(width, stroke);
|
||||
return stroke;
|
||||
}
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum Orientation {
|
||||
|
||||
DEFAULT, _90, _180, _270;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this == DEFAULT) {
|
||||
return "Default";
|
||||
} else {
|
||||
return name().replace("_", "") + " degrees clockwise";
|
||||
}
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum OrientationHV {
|
||||
|
||||
VERTICAL, HORIZONTAL;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum PCBLayer {
|
||||
|
||||
_1, _2, _3, _4, _5;
|
||||
|
||||
public String toString() {
|
||||
return name().substring(1);
|
||||
};
|
||||
}
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.diylc.core.IPropertyValidator;
|
||||
|
||||
/**
|
||||
* Entity class for editable properties extracted from component objects.
|
||||
* Represents a single editable property together with it's current value.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class PropertyWrapper implements Cloneable {
|
||||
|
||||
private String name;
|
||||
private Class<?> type;
|
||||
private Object value;
|
||||
private String setter;
|
||||
private String getter;
|
||||
private boolean defaultable;
|
||||
private IPropertyValidator validator;
|
||||
private boolean unique = true;
|
||||
private boolean changed = false;
|
||||
|
||||
public PropertyWrapper(String name, Class<?> type, String getter,
|
||||
String setter, boolean defaultable, IPropertyValidator validator) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
this.defaultable = defaultable;
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
public void readFrom(Object object) throws IllegalArgumentException,
|
||||
IllegalAccessException, InvocationTargetException,
|
||||
SecurityException, NoSuchMethodException {
|
||||
this.value = object.getClass().getMethod(getter).invoke(object);
|
||||
}
|
||||
|
||||
// public void readUniqueFrom(IDIYComponent component)
|
||||
// throws IllegalArgumentException, IllegalAccessException,
|
||||
// InvocationTargetException {
|
||||
// Object newValue = getter.invoke(component);
|
||||
// if (!newValue.equals(value)) {
|
||||
// this.value = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
public void writeTo(Object object) throws IllegalArgumentException,
|
||||
IllegalAccessException, InvocationTargetException,
|
||||
SecurityException, NoSuchMethodException {
|
||||
object.getClass().getMethod(setter, type).invoke(object, this.value);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean isDefaultable() {
|
||||
return defaultable;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Object clone() throws CloneNotSupportedException {
|
||||
// // Try to invoke clone method on value if possible.
|
||||
// try {
|
||||
// Method cloneMethod = value.getClass().getMethod("clone");
|
||||
// return new Property(name, type, cloneMethod.invoke(value));
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
// 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() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (defaultable ? 1231 : 1237);
|
||||
result = prime * result + ((getter == null) ? 0 : getter.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((setter == null) ? 0 : setter.hashCode());
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PropertyWrapper other = (PropertyWrapper) obj;
|
||||
if (defaultable != other.defaultable)
|
||||
return false;
|
||||
if (getter == null) {
|
||||
if (other.getter != null)
|
||||
return false;
|
||||
} else if (!getter.equals(other.getter))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (setter == null) {
|
||||
if (other.setter != null)
|
||||
return false;
|
||||
} else if (!setter.equals(other.setter))
|
||||
return false;
|
||||
if (type == null) {
|
||||
if (other.type != null)
|
||||
return false;
|
||||
} else if (!type.equals(other.type))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + " = " + value;
|
||||
}
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum ResistorColorCode {
|
||||
|
||||
NONE, _4_BAND, _5_BAND;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (name().startsWith("_")) {
|
||||
return name().substring(1).replace("_", " ").toLowerCase();
|
||||
}
|
||||
return name().substring(0, 1).toUpperCase() + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
package org.diylc.common;
|
||||
|
||||
public enum VerticalAlignment {
|
||||
TOP, CENTER, BOTTOM;
|
||||
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
-248
@@ -1,248 +0,0 @@
|
||||
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.awt.geom.Rectangle2D;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.VerticalAlignment;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
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>
|
||||
*/
|
||||
public abstract class AbstractComponent<T> implements IDIYComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected String name = "";
|
||||
|
||||
public static Color SELECTION_COLOR = Color.red;
|
||||
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
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canControlPointOverlap(int index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueForDisplay() {
|
||||
return getValue() == null ? "" : getValue().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the closest odd number, i.e. x when x is odd, or x + 1 when x is
|
||||
* even.
|
||||
*
|
||||
* @param x
|
||||
* @return
|
||||
*/
|
||||
protected int getClosestOdd(double x) {
|
||||
return ((int) x / 2) * 2 + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clip
|
||||
* @return true if none of the control points lie in the clip rectangle.
|
||||
*/
|
||||
protected boolean checkPointsClipped(Shape clip) {
|
||||
for (int i = 0; i < getControlPointCount(); i++) {
|
||||
if (clip.contains(getControlPoint(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int maxX = Integer.MIN_VALUE;
|
||||
int maxY = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < getControlPointCount(); i++) {
|
||||
Point p = getControlPoint(i);
|
||||
if (minX > p.x) {
|
||||
minX = p.x;
|
||||
}
|
||||
if (maxX < p.x) {
|
||||
maxX = p.x;
|
||||
}
|
||||
if (minY > p.y) {
|
||||
minY = p.y;
|
||||
}
|
||||
if (maxY < p.y) {
|
||||
maxY = p.y;
|
||||
}
|
||||
}
|
||||
Rectangle2D rect = new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
|
||||
return !clip.intersects(rect);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equalsTo(IDIYComponent<?> other) {
|
||||
if (other == null)
|
||||
return false;
|
||||
if (!other.getClass().equals(this.getClass()))
|
||||
return false;
|
||||
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);
|
||||
try {
|
||||
Object value = field.get(this);
|
||||
Object otherValue = field.get(other);
|
||||
if (!compareObjects(value, otherValue))
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean compareObjects(Object o1, Object o2) {
|
||||
if (o1 == null && o2 == null)
|
||||
return true;
|
||||
if (o1 == null || o2 == null)
|
||||
return false;
|
||||
if (o1.getClass().isArray()) {
|
||||
return Arrays.equals((Object[])o1, (Object[])o2);
|
||||
}
|
||||
return o1.equals(o2);
|
||||
}
|
||||
}
|
||||
-249
@@ -1,249 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.geom.CubicCurve2D;
|
||||
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
public abstract class AbstractCurvedComponent<T> extends AbstractTransparentComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color GUIDELINE_COLOR = Color.blue;
|
||||
public static Size DEFAULT_SIZE = new Size(1d, SizeUnit.in);
|
||||
|
||||
protected Point[] controlPoints = new Point[] {
|
||||
new Point(0, 0),
|
||||
new Point((int) (DEFAULT_SIZE.convertToPixels() / 2), 0),
|
||||
new Point((int) (DEFAULT_SIZE.convertToPixels() / 2), (int) (DEFAULT_SIZE
|
||||
.convertToPixels())),
|
||||
new Point((int) DEFAULT_SIZE.convertToPixels(), (int) DEFAULT_SIZE.convertToPixels()) };
|
||||
|
||||
protected Color color = getDefaultColor();
|
||||
protected PointCount pointCount = PointCount.FOUR;
|
||||
|
||||
/**
|
||||
* Draws the specified curve onto graphics.
|
||||
*
|
||||
* @param curve
|
||||
* @param g2d
|
||||
* @param componentState
|
||||
* @param theme
|
||||
*/
|
||||
protected abstract void drawCurve(CubicCurve2D curve, Graphics2D g2d,
|
||||
ComponentState componentState);
|
||||
|
||||
/**
|
||||
* @return default color.
|
||||
*/
|
||||
protected abstract Color getDefaultColor();
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setColor(getDefaultColor().darker());
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(3));
|
||||
CubicCurve2D curve = new CubicCurve2D.Double(1, height - 1, width / 4, height / 3,
|
||||
3 * width / 4, 2 * height / 3, width - 1, 1);
|
||||
g2d.draw(curve);
|
||||
g2d.setColor(getDefaultColor());
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.draw(curve);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||
Project project, IDrawingObserver drawingObserver) {
|
||||
if (checkPointsClipped(g2d.getClip())) {
|
||||
return;
|
||||
}
|
||||
if (componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING) {
|
||||
// Do not track guidelines.
|
||||
drawingObserver.stopTracking();
|
||||
g2d.setStroke(Constants.DASHED_STROKE);
|
||||
g2d.setColor(GUIDELINE_COLOR);
|
||||
g2d.drawLine(controlPoints[0].x, controlPoints[0].y, controlPoints[1].x,
|
||||
controlPoints[1].y);
|
||||
g2d.drawLine(controlPoints[1].x, controlPoints[1].y, controlPoints[2].x,
|
||||
controlPoints[2].y);
|
||||
g2d.drawLine(controlPoints[2].x, controlPoints[2].y, controlPoints[3].x,
|
||||
controlPoints[3].y);
|
||||
drawingObserver.startTracking();
|
||||
}
|
||||
CubicCurve2D curve = new CubicCurve2D.Double(controlPoints[0].x, controlPoints[0].y,
|
||||
controlPoints[1].x, controlPoints[1].y, controlPoints[2].x, controlPoints[2].y,
|
||||
controlPoints[3].x, controlPoints[3].y);
|
||||
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha
|
||||
/ MAX_ALPHA));
|
||||
}
|
||||
// g2d.setColor(color.darker());
|
||||
// g2d.setStroke(new BasicStroke(thickness));
|
||||
// g2d.draw(path);
|
||||
// g2d.setColor(color);
|
||||
// g2d.setStroke(new BasicStroke(thickness - 2));
|
||||
// g2d.draw(path);
|
||||
drawCurve(curve, g2d, componentState);
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Point Count")
|
||||
public PointCount getPointCount() {
|
||||
if (pointCount == null) {
|
||||
pointCount = PointCount.FOUR;
|
||||
}
|
||||
return pointCount;
|
||||
}
|
||||
|
||||
public void setPointCount(PointCount pointCount) {
|
||||
this.pointCount = pointCount;
|
||||
// Reset control points.
|
||||
for (int i = 0; i < getControlPointCount(); i++) {
|
||||
setControlPoint(getControlPoint(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
switch (getPointCount()) {
|
||||
case TWO:
|
||||
return 2;
|
||||
case THREE:
|
||||
return 3;
|
||||
case FOUR:
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return index == 0 || index == getControlPointCount() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.WHEN_SELECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canControlPointOverlap(int index) {
|
||||
// Only shape control points may overlap.
|
||||
switch (getPointCount()) {
|
||||
case TWO:
|
||||
return false;
|
||||
case THREE:
|
||||
return index == 1;
|
||||
case FOUR:
|
||||
return index == 1 || index == 2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
if (index == 0) {
|
||||
return controlPoints[0];
|
||||
}
|
||||
switch (getPointCount()) {
|
||||
case TWO:
|
||||
switch (index) {
|
||||
case 1:
|
||||
return controlPoints[3];
|
||||
}
|
||||
case THREE:
|
||||
switch (index) {
|
||||
case 1:
|
||||
return controlPoints[1];
|
||||
case 2:
|
||||
return controlPoints[3];
|
||||
}
|
||||
case FOUR:
|
||||
switch (index) {
|
||||
case 1:
|
||||
return controlPoints[1];
|
||||
case 2:
|
||||
return controlPoints[2];
|
||||
case 3:
|
||||
return controlPoints[3];
|
||||
}
|
||||
}
|
||||
return controlPoints[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
if (index == 0) {
|
||||
controlPoints[0].setLocation(point);
|
||||
} else {
|
||||
switch (getPointCount()) {
|
||||
case TWO:
|
||||
switch (index) {
|
||||
case 1:
|
||||
Point center = new Point((point.x + controlPoints[0].x) / 2,
|
||||
(point.y + controlPoints[0].y) / 2);
|
||||
controlPoints[1].setLocation(center);
|
||||
controlPoints[2].setLocation(center);
|
||||
controlPoints[3].setLocation(point);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case THREE:
|
||||
switch (index) {
|
||||
case 1:
|
||||
controlPoints[1].setLocation(point);
|
||||
controlPoints[2].setLocation(point);
|
||||
break;
|
||||
case 2:
|
||||
controlPoints[3].setLocation(point);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FOUR:
|
||||
switch (index) {
|
||||
case 1:
|
||||
controlPoints[1].setLocation(point);
|
||||
break;
|
||||
case 2:
|
||||
controlPoints[2].setLocation(point);
|
||||
break;
|
||||
case 3:
|
||||
controlPoints[3].setLocation(point);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
enum PointCount {
|
||||
TWO, THREE, FOUR;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().substring(0, 1) + name().substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
-456
@@ -1,456 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* Base class for all leaded components such as resistors or capacitors. Has two
|
||||
* control points and draws leads between them. Also, it positions and draws the
|
||||
* shape of the component as specified by a child class.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public abstract class AbstractLeadedComponent<T> extends AbstractTransparentComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color LEAD_COLOR = Color.decode("#CCCCCC");
|
||||
public static Color LEAD_COLOR_ICON = LEAD_COLOR.darker().darker();
|
||||
public static Size LEAD_THICKNESS = new Size(0.6d, SizeUnit.mm);
|
||||
public static Size DEFAULT_SIZE = new Size(1d, SizeUnit.in);
|
||||
|
||||
protected Size length;
|
||||
protected Size width;
|
||||
protected Point[] points = new Point[] { new Point((int) (-DEFAULT_SIZE.convertToPixels() / 2), 0),
|
||||
new Point((int) (DEFAULT_SIZE.convertToPixels() / 2), 0) };
|
||||
protected Color bodyColor = Color.white;
|
||||
protected Color borderColor = Color.black;
|
||||
protected Color labelColor = LABEL_COLOR;
|
||||
protected Color leadColor = LEAD_COLOR;
|
||||
protected Display display = Display.NAME;
|
||||
private boolean flipStanding = false;
|
||||
|
||||
protected AbstractLeadedComponent() {
|
||||
super();
|
||||
try {
|
||||
this.length = getDefaultLength().clone();
|
||||
this.width = getDefaultWidth().clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
// This should never happen because Size supports cloning.
|
||||
} catch (NullPointerException e) {
|
||||
// This will happen if components do not have any shape.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
double distance = points[0].distance(points[1]);
|
||||
Shape shape = getBodyShape();
|
||||
// If there's no body, just draw the line connecting the ending points.
|
||||
if (shape == null) {
|
||||
drawLead(g2d, componentState);
|
||||
} else if (supportsStandingMode() && length.convertToPixels() > points[0].distance(points[1])) {
|
||||
// When ending points are too close draw the component in standing
|
||||
// mode.
|
||||
int width = getClosestOdd(this.width.convertToPixels());
|
||||
Shape body = new Ellipse2D.Double((getFlipStanding() ? points[1] : points[0]).x - width / 2,
|
||||
(getFlipStanding() ? points[1] : points[0]).y - width / 2, width, width);
|
||||
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 : getStandingBodyColor());
|
||||
g2d.fill(body);
|
||||
g2d.setComposite(oldComposite);
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY,
|
||||
Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : borderColor;
|
||||
}
|
||||
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(body);
|
||||
if (!outlineMode) {
|
||||
drawLead(g2d, componentState);
|
||||
}
|
||||
} else {
|
||||
// Normal mode with component body in the center and two lead parts.
|
||||
Rectangle shapeRect = shape.getBounds();
|
||||
Double theta = Math.atan2(points[1].y - points[0].y, points[1].x - points[0].x);
|
||||
// Go back to the original transformation to draw leads.
|
||||
if (!outlineMode) {
|
||||
AffineTransform textTransform = g2d.getTransform();
|
||||
// if (length.convertToPixels() > points[0].distance(points[1]))
|
||||
// {
|
||||
// g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
|
||||
// 0.5f));
|
||||
// }
|
||||
int leadThickness = getClosestOdd(getLeadThickness());
|
||||
double leadLength = (distance - calculatePinSpacing(shapeRect)) / 2 - leadThickness / 2;
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
|
||||
Color leadColor = shouldShadeLeads() ? getLeadColorForPainting(componentState).darker()
|
||||
: getLeadColorForPainting(componentState);
|
||||
g2d.setColor(leadColor);
|
||||
int endX = (int) (points[0].x + Math.cos(theta) * leadLength);
|
||||
int endY = (int) Math.round(points[0].y + Math.sin(theta) * leadLength);
|
||||
g2d.drawLine(points[0].x, points[0].y, endX, endY);
|
||||
endX = (int) (points[1].x + Math.cos(theta - Math.PI) * leadLength);
|
||||
endY = (int) Math.round(points[1].y + Math.sin(theta - Math.PI) * leadLength);
|
||||
g2d.drawLine(points[1].x, points[1].y, endX, endY);
|
||||
if (shouldShadeLeads()) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2));
|
||||
leadColor = getLeadColorForPainting(componentState);
|
||||
g2d.setColor(leadColor);
|
||||
g2d.drawLine(points[0].x, points[0].y, (int) (points[0].x + Math.cos(theta) * leadLength),
|
||||
(int) (points[0].y + Math.sin(theta) * leadLength));
|
||||
g2d.drawLine(points[1].x, points[1].y, (int) (points[1].x + Math.cos(theta - Math.PI) * leadLength),
|
||||
(int) (points[1].y + Math.sin(theta - Math.PI) * leadLength));
|
||||
}
|
||||
g2d.setTransform(textTransform);
|
||||
}
|
||||
// Transform graphics to draw the body in the right place and at the
|
||||
// right angle.
|
||||
AffineTransform oldTransform = null;
|
||||
double width;
|
||||
double length;
|
||||
if (useShapeRectAsPosition()) {
|
||||
width = shapeRect.getHeight();
|
||||
length = shapeRect.getWidth();
|
||||
} else {
|
||||
width = getWidth().convertToPixels();
|
||||
length = getLength().convertToPixels();
|
||||
}
|
||||
oldTransform = g2d.getTransform();
|
||||
g2d.translate((points[0].x + points[1].x - length) / 2, (points[0].y + points[1].y - width) / 2);
|
||||
g2d.rotate(theta, length / 2, width / 2);
|
||||
// Draw body.
|
||||
Composite oldComposite = g2d.getComposite();
|
||||
if (alpha < MAX_ALPHA) {
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
|
||||
}
|
||||
if (bodyColor != null) {
|
||||
if (bodyColor != null) {
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
|
||||
g2d.fill(shape);
|
||||
}
|
||||
}
|
||||
decorateComponentBody(g2d, outlineMode);
|
||||
g2d.setComposite(oldComposite);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
Color finalBorderColor;
|
||||
if (outlineMode) {
|
||||
Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY,
|
||||
Constants.DEFAULT_THEME);
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : theme.getOutlineColor();
|
||||
} else {
|
||||
finalBorderColor = componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : borderColor;
|
||||
}
|
||||
g2d.setColor(finalBorderColor);
|
||||
g2d.draw(shape);
|
||||
|
||||
// // Go back to the original transformation to draw leads.
|
||||
// if (!outlineMode) {
|
||||
// AffineTransform textTransform = g2d.getTransform();
|
||||
// g2d.setTransform(oldTransform);
|
||||
// if (length.convertToPixels() > points[0].distance(points[1])) {
|
||||
// g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
|
||||
// 0.5f));
|
||||
// }
|
||||
// int leadThickness = getClosestOdd(getLeadThickness());
|
||||
// double leadLength = (distance - calculatePinSpacing(shapeRect)) /
|
||||
// 2 - leadThickness / 2;
|
||||
// g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness));
|
||||
// Color leadColor = shouldShadeLeads() ?
|
||||
// getLeadColor(componentState).darker()
|
||||
// : getLeadColor(componentState);
|
||||
// g2d.setColor(leadColor);
|
||||
// int endX = (int) (points[0].x + Math.cos(theta) * leadLength);
|
||||
// int endY = (int) Math.round(points[0].y + Math.sin(theta) *
|
||||
// leadLength);
|
||||
// g2d.drawLine(points[0].x, points[0].y, endX, endY);
|
||||
// endX = (int) (points[1].x + Math.cos(theta - Math.PI) *
|
||||
// leadLength);
|
||||
// endY = (int) Math.round(points[1].y + Math.sin(theta - Math.PI) *
|
||||
// leadLength);
|
||||
// g2d.drawLine(points[1].x, points[1].y, endX, endY);
|
||||
// if (shouldShadeLeads()) {
|
||||
// g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness
|
||||
// - 2));
|
||||
// leadColor = getLeadColor(componentState);
|
||||
// g2d.setColor(leadColor);
|
||||
// g2d.drawLine(points[0].x, points[0].y, (int) (points[0].x +
|
||||
// Math.cos(theta)
|
||||
// * leadLength), (int) (points[0].y + Math.sin(theta) *
|
||||
// leadLength));
|
||||
// g2d.drawLine(points[1].x, points[1].y, (int) (points[1].x +
|
||||
// Math.cos(theta
|
||||
// - Math.PI)
|
||||
// * leadLength), (int) (points[1].y + Math.sin(theta - Math.PI)
|
||||
// * leadLength));
|
||||
// }
|
||||
// g2d.setComposite(oldComposite);
|
||||
// g2d.setTransform(textTransform);
|
||||
// }
|
||||
|
||||
// Draw label.
|
||||
g2d.setFont(LABEL_FONT);
|
||||
if (useShapeRectAsPosition()) {
|
||||
g2d.translate(shapeRect.x, shapeRect.y);
|
||||
}
|
||||
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 : labelColor;
|
||||
}
|
||||
g2d.setColor(finalLabelColor);
|
||||
FontMetrics fontMetrics = g2d.getFontMetrics();
|
||||
String label = "";
|
||||
label = display == Display.NAME ? getName() : (getValue() == null ? "" : getValue().toString());
|
||||
if (display == Display.NONE) {
|
||||
label = "";
|
||||
}
|
||||
if (display == Display.BOTH) {
|
||||
label = getName() + " " + (getValue() == null ? "" : getValue().toString());
|
||||
}
|
||||
Rectangle2D textRect = fontMetrics.getStringBounds(label, g2d);
|
||||
// Don't offset in outline mode.
|
||||
int offset = outlineMode ? 0 : getLabelOffset((int) length, (int) width);
|
||||
// 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, length / 2, width / 2);
|
||||
offset = -offset;
|
||||
}
|
||||
g2d.drawString(label, (int) (length - textRect.getWidth()) / 2 + offset,
|
||||
calculateLabelYCoordinate(shapeRect, textRect, fontMetrics));
|
||||
g2d.setTransform(oldTransform);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawLead(Graphics2D g2d, ComponentState componentState) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(getLeadThickness()));
|
||||
Color leadColor = shouldShadeLeads() ? getLeadColorForPainting(componentState).darker()
|
||||
: getLeadColorForPainting(componentState);
|
||||
g2d.setColor(leadColor);
|
||||
g2d.drawLine(points[0].x, points[0].y, points[1].x, points[1].y);
|
||||
if (shouldShadeLeads()) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(getLeadThickness() - 2));
|
||||
leadColor = getLeadColorForPainting(componentState);
|
||||
g2d.setColor(leadColor);
|
||||
g2d.drawLine(points[0].x, points[0].y, points[1].x, points[1].y);
|
||||
}
|
||||
}
|
||||
|
||||
protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
protected int calculateLabelYCoordinate(Rectangle2D shapeRect, Rectangle2D textRect, FontMetrics fontMetrics) {
|
||||
return (int) (shapeRect.getHeight() - textRect.getHeight()) / 2 + fontMetrics.getAscent();
|
||||
}
|
||||
|
||||
protected boolean shouldShadeLeads() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean supportsStandingMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected int getLabelOffset(int bodyWidth, int labelWidth) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return default component length.
|
||||
*/
|
||||
protected abstract Size getDefaultLength();
|
||||
|
||||
/**
|
||||
* Returns default component width.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract Size getDefaultWidth();
|
||||
|
||||
/**
|
||||
* @return shape that represents component body. Shape should not be
|
||||
* transformed and should be referenced to (0, 0).
|
||||
*/
|
||||
protected abstract Shape getBodyShape();
|
||||
|
||||
/**
|
||||
* Controls how component shape should be placed relative to start and end
|
||||
* point.
|
||||
*
|
||||
* @return <code>true<code> if shape rect should be used to center the component or <code>false</code>
|
||||
* to place the component relative to <code>length</code> and
|
||||
* <code>width</code> values.
|
||||
*/
|
||||
protected boolean useShapeRectAsPosition() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return default lead thickness. Override this method to change it.
|
||||
*/
|
||||
protected int getLeadThickness() {
|
||||
return (int) LEAD_THICKNESS.convertToPixels();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return default lead color. Override this method to change it.
|
||||
*/
|
||||
protected Color getLeadColorForPainting(ComponentState componentState) {
|
||||
return componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
|
||||
: getLeadColor();
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Lead color")
|
||||
public Color getLeadColor() {
|
||||
if (leadColor == null) {
|
||||
leadColor = LEAD_COLOR_ICON;
|
||||
}
|
||||
return leadColor;
|
||||
}
|
||||
|
||||
public void setLeadColor(Color leadColor) {
|
||||
this.leadColor = leadColor;
|
||||
}
|
||||
|
||||
protected int calculatePinSpacing(Rectangle shapeRect) {
|
||||
return shapeRect.width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getControlPointCount() {
|
||||
return points.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getControlPoint(int index) {
|
||||
return (Point) points[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isControlPointSticky(int index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||
return VisibilityPolicy.ALWAYS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlPoint(Point point, int index) {
|
||||
points[index].setLocation(point);
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Color")
|
||||
public Color getBodyColor() {
|
||||
return bodyColor;
|
||||
}
|
||||
|
||||
public void setBodyColor(Color bodyColor) {
|
||||
this.bodyColor = bodyColor;
|
||||
}
|
||||
|
||||
public Color getStandingBodyColor() {
|
||||
return bodyColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Border")
|
||||
public Color getBorderColor() {
|
||||
return borderColor;
|
||||
}
|
||||
|
||||
public void setBorderColor(Color borderColor) {
|
||||
this.borderColor = borderColor;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Length", defaultable = true)
|
||||
public Size getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(Size length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Width", defaultable = true)
|
||||
public Size getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Size width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Display getDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public void setDisplay(Display display) {
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Label color")
|
||||
public Color getLabelColor() {
|
||||
return labelColor;
|
||||
}
|
||||
|
||||
public void setLabelColor(Color labelColor) {
|
||||
this.labelColor = labelColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method with @EditableProperty annotation in child classes
|
||||
* where standing mode is supported
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean getFlipStanding() {
|
||||
return flipStanding;
|
||||
}
|
||||
|
||||
public void setFlipStanding(boolean flipStanding) {
|
||||
this.flipStanding = flipStanding;
|
||||
}
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
/**
|
||||
* Base class for radial components. The same as {@link AbstractRadialComponent}
|
||||
* but with added pin spacing.
|
||||
*
|
||||
* @author bancika
|
||||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class AbstractRadialComponent<T> extends
|
||||
AbstractLeadedComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Size PIN_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
|
||||
private Size pinSpacing = PIN_SPACING;
|
||||
|
||||
@Override
|
||||
protected int calculatePinSpacing(Rectangle shapeRect) {
|
||||
return getClosestOdd(getPinSpacing().convertToPixels());
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Pin spacing")
|
||||
public Size getPinSpacing() {
|
||||
if (pinSpacing == null) {
|
||||
pinSpacing = PIN_SPACING;
|
||||
}
|
||||
return pinSpacing;
|
||||
}
|
||||
|
||||
public void setPinSpacing(Size pinSpacing) {
|
||||
this.pinSpacing = pinSpacing;
|
||||
}
|
||||
|
||||
}
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.common.LabelPosition;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
public abstract class AbstractSchematicLeadedSymbol<T> extends AbstractLeadedComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color COLOR = Color.blue;
|
||||
public static Color LEAD_COLOR = Color.black;
|
||||
|
||||
protected LabelPosition labelPosition = LabelPosition.ABOVE;
|
||||
|
||||
public AbstractSchematicLeadedSymbol() {
|
||||
super();
|
||||
// We don't want to fill the body, so use null.
|
||||
this.bodyColor = null;
|
||||
this.leadColor = LEAD_COLOR;
|
||||
this.borderColor = COLOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBodyColor() {
|
||||
return super.getBodyColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShadeLeads() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLeadThickness() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateLabelYCoordinate(Rectangle2D shapeRect, Rectangle2D textRect,
|
||||
FontMetrics fontMetrics) {
|
||||
if (labelPosition == LabelPosition.ABOVE) {
|
||||
return -1;
|
||||
} else {
|
||||
return (int) (shapeRect.getHeight() + textRect.getHeight() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Label position")
|
||||
public LabelPosition getLabelPosition() {
|
||||
return labelPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
@EditableProperty(name = "Color")
|
||||
public Color getBorderColor() {
|
||||
return super.getBorderColor();
|
||||
}
|
||||
|
||||
public void setLabelPosition(LabelPosition labelPosition) {
|
||||
this.labelPosition = labelPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getLeadColorForPainting(ComponentState componentState) {
|
||||
return componentState == ComponentState.SELECTED
|
||||
|| componentState == ComponentState.DRAGGING ? SELECTION_COLOR : getLeadColor();
|
||||
}
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
package org.diylc.components;
|
||||
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
public abstract class AbstractTransparentComponent<T> extends AbstractComponent<T> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static byte MAX_ALPHA = 127;
|
||||
|
||||
protected byte alpha = MAX_ALPHA;
|
||||
|
||||
@EditableProperty
|
||||
public Byte getAlpha() {
|
||||
return alpha;
|
||||
}
|
||||
|
||||
public void setAlpha(Byte alpha) {
|
||||
this.alpha = alpha;
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Validator that allows all values.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class AllowAllValidator implements IPropertyValidator {
|
||||
|
||||
@Override
|
||||
public void validate(Object value) throws ValidationException {
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Enumerates all possible states that a component can be in.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum ComponentState {
|
||||
|
||||
NORMAL, SELECTED, LOCKED, DRAGGING
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
public enum CreationMethod {
|
||||
|
||||
SINGLE_CLICK, POINT_BY_POINT;
|
||||
}
|
||||
-143
@@ -1,143 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
/**
|
||||
* Interface for component instance. Implementation classes of this interface
|
||||
* will be instantiated by the application when component is added to the
|
||||
* canvas. <br>
|
||||
* <br>
|
||||
* <b>Implementing classes should meet the following: </b>
|
||||
* <ul>
|
||||
* <li>Must have an empty constructor.</li>
|
||||
* <li>Class should be annotated with {@link ComponentDescriptor}.</li>
|
||||
* <li>Getters for properties editable by users should be annotated with
|
||||
* {@link EditableProperty}.</li>
|
||||
* <li>Component configuration should be stored int <code>public static</code>
|
||||
* fields so they can be set through config file.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*
|
||||
* @param <T>
|
||||
* type of component values, e.g. Resistance for resistors or String
|
||||
* for transistors.
|
||||
*/
|
||||
public interface IDIYComponent<T> extends Serializable {
|
||||
|
||||
public static final int CHASSIS = 1;
|
||||
public static final int BOARD = 2;
|
||||
public static final int TRACE = 3;
|
||||
public static final int COMPONENT = 4;
|
||||
public static final int TEXT = 5;
|
||||
|
||||
/**
|
||||
* @return component instance name.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Updates component instance name.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
void setName(String name);
|
||||
|
||||
/**
|
||||
* @return component value.
|
||||
*/
|
||||
T getValue();
|
||||
|
||||
/**
|
||||
* Updates component value.
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setValue(T value);
|
||||
|
||||
/**
|
||||
* @return number of control points for this component instance. May vary
|
||||
* between two instances of the same type, e.g. DIL IC with 8 and 16
|
||||
* pins will have 8 or 16 pins although they are of the same type.
|
||||
*/
|
||||
int getControlPointCount();
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* @return control point at the specified index.
|
||||
*/
|
||||
Point getControlPoint(int index);
|
||||
|
||||
/**
|
||||
* Updates the control point at the specified index.
|
||||
*
|
||||
* @param point
|
||||
* @param index
|
||||
*/
|
||||
void setControlPoint(Point point, int index);
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* @return true, if the specified control point may stick to control points
|
||||
* of other components.
|
||||
*/
|
||||
boolean isControlPointSticky(int index);
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* @return true, if the specified control point may overlap with other
|
||||
* control points <b>of the same component</b>. The other control
|
||||
* point must be able to overlap too.
|
||||
*/
|
||||
boolean canControlPointOverlap(int index);
|
||||
|
||||
VisibilityPolicy getControlPointVisibilityPolicy(int index);
|
||||
|
||||
/**
|
||||
* Draws the component onto the {@link Graphics2D}.
|
||||
*
|
||||
* @param g2d
|
||||
* @param componentState
|
||||
* @param outlineMode
|
||||
* @param project
|
||||
* @param drawingObserver
|
||||
*/
|
||||
void draw(Graphics2D g2d, ComponentState componentState,
|
||||
boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver);
|
||||
|
||||
/**
|
||||
* Draws icon representation of the component. This should not depend on
|
||||
* component state, i.e. it should be treated as a static method.
|
||||
*
|
||||
* @param g2d
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
void drawIcon(Graphics2D g2d, int width, int height);
|
||||
|
||||
/**
|
||||
* Clones the component.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
IDIYComponent<T> clone() throws CloneNotSupportedException;
|
||||
|
||||
/**
|
||||
* @return full value for BOM.
|
||||
*/
|
||||
String getValueForDisplay();
|
||||
|
||||
/**
|
||||
* Checks if two components are equal.
|
||||
*
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
boolean equalsTo(IDIYComponent<?> other);
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Interface for tracking component drawing process. Components may use it to
|
||||
* stop or restart tracking. Anything drawn while tracking is stopped will not
|
||||
* be added to the mouse hot-spot area.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IDrawingObserver {
|
||||
|
||||
void stopTracking();
|
||||
|
||||
void startTracking();
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Interface for validating property value changes.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IPropertyValidator {
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* @throws ValidationException
|
||||
* if validation fails. Message will contain the reason.
|
||||
*/
|
||||
void validate(Object value) throws ValidationException;
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
|
||||
|
||||
/**
|
||||
* Base interface for the main GUI component.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public interface IView {
|
||||
|
||||
public static final int ERROR_MESSAGE = 0;
|
||||
public static final int INFORMATION_MESSAGE = 1;
|
||||
public static final int WARNING_MESSAGE = 2;
|
||||
public static final int QUESTION_MESSAGE = 3;
|
||||
public static final int PLAIN_MESSAGE = -1;
|
||||
public static final int DEFAULT_OPTION = -1;
|
||||
public static final int YES_NO_OPTION = 0;
|
||||
public static final int YES_NO_CANCEL_OPTION = 1;
|
||||
public static final int OK_CANCEL_OPTION = 2;
|
||||
public static final int YES_OPTION = 0;
|
||||
public static final int NO_OPTION = 1;
|
||||
public static final int CANCEL_OPTION = 2;
|
||||
public static final int OK_OPTION = 0;
|
||||
|
||||
public static final String CHECK_BOX_MENU_ITEM = "org.diylc.checkBoxMenuItem";
|
||||
public static final String RADIO_BUTTON_GROUP_KEY = "org.diylc.radioButtonGroup";
|
||||
|
||||
void showMessage(String message, String title, int messageType);
|
||||
|
||||
int showConfirmDialog(String message, String title, int optionType, int messageType);
|
||||
|
||||
boolean editProperties(List<PropertyWrapper> properties, Set<PropertyWrapper> defaultedProperties);
|
||||
|
||||
File promptFileSave();
|
||||
}
|
||||
-259
@@ -1,259 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.diylc.appframework.update.VersionNumber;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.PositiveMeasureValidator;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
|
||||
/**
|
||||
* Entity class that defines a project. Contains project properties and a
|
||||
* collection of components.This class is serialized to file. Some filed getters
|
||||
* are tagged with {@link EditableProperty} to enable for user to edit them.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class Project implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static String DEFAULT_TITLE = "New Project";
|
||||
public static Size DEFAULT_WIDTH = new Size(29d, SizeUnit.cm);
|
||||
public static Size DEFAULT_HEIGHT = new Size(21d, SizeUnit.cm);
|
||||
public static Size DEFAULT_GRID_SPACING = new Size(0.1d, SizeUnit.in);
|
||||
|
||||
private VersionNumber fileVersion;
|
||||
|
||||
private String title;
|
||||
private String author;
|
||||
private String description;
|
||||
private Size width;
|
||||
private Size height;
|
||||
private Size gridSpacing;
|
||||
private List<IDIYComponent<?>> components;
|
||||
private Set<Set<IDIYComponent<?>>> groups;
|
||||
private Set<Integer> lockedLayers;
|
||||
|
||||
public Project() {
|
||||
components = new ArrayList<IDIYComponent<?>>();
|
||||
groups = new HashSet<Set<IDIYComponent<?>>>();
|
||||
lockedLayers = new HashSet<Integer>();
|
||||
title = DEFAULT_TITLE;
|
||||
author = System.getProperty("user.name");
|
||||
width = DEFAULT_WIDTH;
|
||||
height = DEFAULT_HEIGHT;
|
||||
gridSpacing = DEFAULT_GRID_SPACING;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false)
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
@EditableProperty(defaultable = false)
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Size getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Size width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
@EditableProperty
|
||||
public Size getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Size height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Grid spacing", validatorClass = SpacingValidator.class)
|
||||
public Size getGridSpacing() {
|
||||
return gridSpacing;
|
||||
}
|
||||
|
||||
public void setGridSpacing(Size gridSpacing) {
|
||||
this.gridSpacing = gridSpacing;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of components sorted by z-order ascending.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<IDIYComponent<?>> getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set of grouped components.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Set<Set<IDIYComponent<?>>> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public Set<Integer> getLockedLayers() {
|
||||
return lockedLayers;
|
||||
}
|
||||
|
||||
public VersionNumber getFileVersion() {
|
||||
return fileVersion;
|
||||
}
|
||||
|
||||
public void setFileVersion(VersionNumber fileVersion) {
|
||||
this.fileVersion = fileVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((author == null) ? 0 : author.hashCode());
|
||||
result = prime * result + ((components == null) ? 0 : components.hashCode());
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((height == null) ? 0 : height.hashCode());
|
||||
result = prime * result + ((title == null) ? 0 : title.hashCode());
|
||||
result = prime * result + ((width == null) ? 0 : width.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Project other = (Project) obj;
|
||||
if (author == null) {
|
||||
if (other.author != null)
|
||||
return false;
|
||||
} else if (!author.equals(other.author))
|
||||
return false;
|
||||
if (components == null) {
|
||||
if (other.components != null)
|
||||
return false;
|
||||
} else if (components.size() != other.components.size()) {
|
||||
return false;
|
||||
} else {
|
||||
Iterator<IDIYComponent<?>> i1 = components.iterator();
|
||||
Iterator<IDIYComponent<?>> i2 = other.components.iterator();
|
||||
while (i1.hasNext()) {
|
||||
IDIYComponent<?> c1 = i1.next();
|
||||
IDIYComponent<?> c2 = i2.next();
|
||||
if (!c1.equalsTo(c2))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (description == null) {
|
||||
if (other.description != null)
|
||||
return false;
|
||||
} else if (!description.equals(other.description))
|
||||
return false;
|
||||
if (height == null) {
|
||||
if (other.height != null)
|
||||
return false;
|
||||
} else if (!height.equals(other.height))
|
||||
return false;
|
||||
if (title == null) {
|
||||
if (other.title != null)
|
||||
return false;
|
||||
} else if (!title.equals(other.title))
|
||||
return false;
|
||||
if (width == null) {
|
||||
if (other.width != null)
|
||||
return false;
|
||||
} else if (!width.equals(other.width))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public static class SpacingValidator extends PositiveMeasureValidator {
|
||||
|
||||
@Override
|
||||
public void validate(Object value) throws ValidationException {
|
||||
super.validate(value);
|
||||
Size size = (Size) value;
|
||||
if (size.compareTo(new Size(0.1d, SizeUnit.mm)) < 0) {
|
||||
throw new ValidationException("must be at least 0.1mm");
|
||||
}
|
||||
if (size.compareTo(new Size(1d, SizeUnit.in)) > 0) {
|
||||
throw new ValidationException("must be less than 1in");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Template {
|
||||
|
||||
private String name;
|
||||
private Map<String, Object> values;
|
||||
private List<Point> points;
|
||||
|
||||
public Template(String name, Map<String, Object> values, List<Point> points) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.values = values;
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Map<String, Object> getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public void setValues(Map<String, Object> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public List<Point> getPoints() {
|
||||
return points;
|
||||
}
|
||||
|
||||
public void setPoints(List<Point> points) {
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((points == null) ? 0 : points.hashCode());
|
||||
result = prime * result + ((values == null) ? 0 : values.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Template other = (Template) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (points == null) {
|
||||
if (other.points != null)
|
||||
return false;
|
||||
} else if (!points.equals(other.points))
|
||||
return false;
|
||||
if (values == null) {
|
||||
if (other.values != null)
|
||||
return false;
|
||||
} else if (!values.equals(other.values))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Theme implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String name;
|
||||
private Color bgColor;
|
||||
private Color gridColor;
|
||||
private Color outlineColor;
|
||||
|
||||
public Theme(String name, Color bgColor, Color gridColor, Color outlineColor) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.bgColor = bgColor;
|
||||
this.gridColor = gridColor;
|
||||
this.outlineColor = outlineColor;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Color getBgColor() {
|
||||
return bgColor;
|
||||
}
|
||||
|
||||
public Color getGridColor() {
|
||||
return gridColor;
|
||||
}
|
||||
|
||||
public Color getOutlineColor() {
|
||||
return outlineColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((bgColor == null) ? 0 : bgColor.hashCode());
|
||||
result = prime * result + ((gridColor == null) ? 0 : gridColor.hashCode());
|
||||
result = prime * result + ((outlineColor == null) ? 0 : outlineColor.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Theme other = (Theme) obj;
|
||||
if (bgColor == null) {
|
||||
if (other.bgColor != null)
|
||||
return false;
|
||||
} else if (!bgColor.equals(other.bgColor))
|
||||
return false;
|
||||
if (gridColor == null) {
|
||||
if (other.gridColor != null)
|
||||
return false;
|
||||
} else if (!gridColor.equals(other.gridColor))
|
||||
return false;
|
||||
if (outlineColor == null) {
|
||||
if (other.outlineColor != null)
|
||||
return false;
|
||||
} else if (!outlineColor.equals(other.outlineColor))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
|
||||
package org.diylc.core;
|
||||
|
||||
public class ValidationException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ValidationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package org.diylc.core;
|
||||
|
||||
/**
|
||||
* Enumerates control point visibility policies.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public enum VisibilityPolicy {
|
||||
|
||||
/**
|
||||
* Control point should be rendered all the time.
|
||||
*/
|
||||
ALWAYS,
|
||||
/**
|
||||
* Control point should be rendered only when the component is selected.
|
||||
*/
|
||||
WHEN_SELECTED,
|
||||
/**
|
||||
* Control point should not be rendered regardless of component selection.
|
||||
*/
|
||||
NEVER;
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
package org.diylc.core.annotations;
|
||||
|
||||
public enum BomPolicy {
|
||||
SHOW_ALL_NAMES,
|
||||
SHOW_ONLY_TYPE_NAME,
|
||||
NEVER_SHOW,
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
package org.diylc.core.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Annotation for {@link IDIYComponent} implementation. Describes component
|
||||
* properties.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ComponentDescriptor {
|
||||
|
||||
/**
|
||||
* @return component type name.
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* @return component type description.
|
||||
*/
|
||||
String description();
|
||||
|
||||
/**
|
||||
* @return method that should be used to create a component. If
|
||||
* <code>CreationMethod.POINT_BY_POINT</code> is used, user will
|
||||
* have to select ending points before the component is created.
|
||||
*/
|
||||
CreationMethod creationMethod() default CreationMethod.SINGLE_CLICK;
|
||||
|
||||
/**
|
||||
* @return component category, e.g. "Passive", "Semiconductors", etc.
|
||||
*/
|
||||
String category();
|
||||
|
||||
/**
|
||||
* @return component author name.
|
||||
*/
|
||||
String author();
|
||||
|
||||
/**
|
||||
* @return prefix that will be used to generate component instance names,
|
||||
* e.g. "R" for resistors or "Q" for transistors.
|
||||
*/
|
||||
String instanceNamePrefix();
|
||||
|
||||
/**
|
||||
* @return Z-order of the component.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @return when true, component editor dialog should be shown in Auto-Edit
|
||||
* mode.
|
||||
*/
|
||||
boolean autoEdit() default true;
|
||||
|
||||
/**
|
||||
* @return true if component may be rotated, false otherwise
|
||||
* @return
|
||||
*/
|
||||
boolean rotatable() default true;
|
||||
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
package org.diylc.core.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.diylc.core.AllowAllValidator;
|
||||
import org.diylc.core.IPropertyValidator;
|
||||
|
||||
/**
|
||||
* Used to annotate editable component property. Editable property XYZ must have
|
||||
* both getter and setter named <code>getXYZ</code> and <code>setXYZ</code>
|
||||
* respectively and this annotation must be placed on the getter method.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface EditableProperty {
|
||||
|
||||
/**
|
||||
* Returns property name. If left blank property name will be extracted from
|
||||
* the getter name, e.g. getter <code>getXYZ</code> will induce property
|
||||
* name <code>XYZ</code>. <br>
|
||||
* Default value is blank.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* If true, application may set default value for this property. <br>
|
||||
* Default value is true.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean defaultable() default true;
|
||||
|
||||
/**
|
||||
* Class of validator to use to
|
||||
* @return
|
||||
*/
|
||||
Class<? extends IPropertyValidator> validatorClass() default AllowAllValidator.class;
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package org.diylc.core.annotations;
|
||||
|
||||
import org.diylc.core.IPropertyValidator;
|
||||
import org.diylc.core.ValidationException;
|
||||
import org.diylc.core.measures.AbstractMeasure;
|
||||
|
||||
public class PositiveMeasureValidator implements IPropertyValidator {
|
||||
|
||||
@Override
|
||||
public void validate(Object value) throws ValidationException {
|
||||
if (value == null)
|
||||
return;
|
||||
if (value instanceof AbstractMeasure) {
|
||||
AbstractMeasure measure = (AbstractMeasure) value;
|
||||
if (measure.getValue() < 0) {
|
||||
throw new ValidationException("must be greater than zero.");
|
||||
}
|
||||
} else {
|
||||
throw new ValidationException("wrong data type, measure expected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
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;
|
||||
|
||||
protected static final Format format = new DecimalFormat("0.####");
|
||||
|
||||
protected Double value;
|
||||
protected T unit;
|
||||
|
||||
// public AbstractMeasure() {
|
||||
// }
|
||||
|
||||
public AbstractMeasure(Double value, T unit) {
|
||||
super();
|
||||
this.value = value;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public Double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
// public void setValue(Double value) {
|
||||
// this.value = value;
|
||||
// }
|
||||
|
||||
public T getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
// public void setUnit(T multiplier) {
|
||||
// this.unit = multiplier;
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public Object clone() throws CloneNotSupportedException {
|
||||
// return super.clone();
|
||||
// }
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((unit == null) ? 0 : unit.hashCode());
|
||||
result = prime * result + ((value == null) ? 0 : value.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
AbstractMeasure<?> other = (AbstractMeasure<?>) obj;
|
||||
if (unit == null) {
|
||||
if (other.unit != null)
|
||||
return false;
|
||||
} else if (!unit.equals(other.unit))
|
||||
return false;
|
||||
if (value == null) {
|
||||
if (other.value != null)
|
||||
return false;
|
||||
} else if (!value.equals(other.value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return format.format(value) + unit;
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public class Capacitance extends AbstractMeasure<CapacitanceUnit> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// public Capacitance() {
|
||||
// super();
|
||||
// // TODO Auto-generated constructor stub
|
||||
// }
|
||||
|
||||
public Capacitance(Double value, CapacitanceUnit unit) {
|
||||
super(value, unit);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Capacitance clone() throws CloneNotSupportedException {
|
||||
return new Capacitance(value, unit);
|
||||
}
|
||||
|
||||
public static Capacitance parseCapacitance(String value) {
|
||||
for (CapacitanceUnit unit : CapacitanceUnit.values()) {
|
||||
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||
return new Capacitance(Double.parseDouble(value), unit);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse capacitance: " + value);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public enum CapacitanceUnit implements Unit {
|
||||
|
||||
pF(1, "pF"), nF(1e3, "nF"), uF(1e6, "uF"), mF(1e9, "mF"), F(1e12, "F");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
|
||||
private CapacitanceUnit(double factor, String display) {
|
||||
this.factor = factor;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFactor() {
|
||||
return factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public class Current extends AbstractMeasure<CurrentUnit> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Current(Double value, CurrentUnit unit) {
|
||||
super(value, unit);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Current clone() throws CloneNotSupportedException {
|
||||
return new Current(value, unit);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public enum CurrentUnit implements Unit {
|
||||
|
||||
uA(1e-6, "uA"), mA(1e-3, "mA"), A(1, "A");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
|
||||
private CurrentUnit(double factor, String display) {
|
||||
this.factor = factor;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFactor() {
|
||||
return factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public class Inductance extends AbstractMeasure<InductanceUnit> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// public Inductance() {
|
||||
// super();
|
||||
// // TODO Auto-generated constructor stub
|
||||
// }
|
||||
|
||||
public Inductance(Double value, InductanceUnit unit) {
|
||||
super(value, unit);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inductance clone() throws CloneNotSupportedException {
|
||||
return new Inductance(value, unit);
|
||||
}
|
||||
|
||||
public static Inductance parseCapacitance(String value) {
|
||||
for (InductanceUnit unit : InductanceUnit.values()) {
|
||||
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||
return new Inductance(Double.parseDouble(value), unit);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse inductance: " + value);
|
||||
}
|
||||
}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public enum InductanceUnit implements Unit {
|
||||
|
||||
pH(1, "pH"), nH(1e3, "nH"), uH(1e6, "uH"), mH(1e9, "mH"), H(1e12, "H");
|
||||
|
||||
double factor;
|
||||
String display;
|
||||
|
||||
private InductanceUnit(double factor, String display) {
|
||||
this.factor = factor;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFactor() {
|
||||
return factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
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(Double value, SizeUnit unit) {
|
||||
super(value, unit);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public double convertToPixels() {
|
||||
// double factor = getUnit().getFactor() / SizeUnit.in.getFactor();
|
||||
// int grids = (int) (factor * getValue() * Constants.GRIDS_PER_INCH);
|
||||
// double remainder = (factor * getValue() * Constants.GRIDS_PER_INCH) - grids;
|
||||
// return (int) Math.round(Constants.PIXELS_PER_INCH / Constants.GRIDS_PER_INCH
|
||||
// * (grids + remainder));
|
||||
return getValue() * getUnit().getFactor() / SizeUnit.in.getFactor() * Constants.PIXELS_PER_INCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Size clone() throws CloneNotSupportedException {
|
||||
return new Size(value, unit);
|
||||
}
|
||||
|
||||
public static Size parseSize(String value) {
|
||||
for (SizeUnit unit : SizeUnit.values()) {
|
||||
if (value.toLowerCase().endsWith(unit.toString().toLowerCase())) {
|
||||
value = value.substring(0, value.length() - unit.toString().length() - 1).trim();
|
||||
return new Size(Double.parseDouble(value), unit);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Could not parse size: " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Size o) {
|
||||
return new Double(value * unit.getFactor()).compareTo(o.getValue() * o.getUnit().getFactor());
|
||||
}
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public enum SizeUnit implements Unit {
|
||||
|
||||
mm(1d), cm(10d), m(1e4d), in(25.4d), ft(25.4d * 12), yd(9144d);
|
||||
|
||||
double factor;
|
||||
|
||||
private SizeUnit(double factor) {
|
||||
this.factor = factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getFactor() {
|
||||
return factor;
|
||||
}
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
package org.diylc.core.measures;
|
||||
|
||||
public interface Unit {
|
||||
|
||||
double getFactor();
|
||||
}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
log4j.rootLogger = DEBUG, fileout, stdout
|
||||
log4j.appender.fileout = com.diyfever.gui.miscutils.NewLogForEachRunFileAppender
|
||||
log4j.appender.fileout.layout.ConversionPattern = %d{ABSOLUTE} %5p [%t] %c{1} - %m%n
|
||||
log4j.appender.fileout.layout = org.apache.log4j.PatternLayout
|
||||
log4j.appender.fileout.File = log/log.log
|
||||
|
||||
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p [%t] %c{1} - %m%n
|
||||
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.diylc.core.measures.Size;
|
||||
|
||||
public class CalcUtils {
|
||||
|
||||
/**
|
||||
* Rounds the number to the closest grid line.
|
||||
*
|
||||
* @param x
|
||||
* @return
|
||||
*/
|
||||
public static int roundToGrid(int x, Size gridSpacing) {
|
||||
double grid = gridSpacing.convertToPixels();
|
||||
return (int) (Math.round(1f * x / grid) * grid);
|
||||
}
|
||||
|
||||
public static void snapPointToGrid(Point point, Size gridSpacing) {
|
||||
int x = roundToGrid(point.x, gridSpacing);
|
||||
int y = roundToGrid(point.y, gridSpacing);
|
||||
point.setLocation(x, y);
|
||||
}
|
||||
}
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
public class ComparatorFactory {
|
||||
|
||||
private static ComparatorFactory instance;
|
||||
|
||||
private Comparator<IDIYComponent<?>> componentNameComparator;
|
||||
private Comparator<ComponentType> componentTypeComparator;
|
||||
private Comparator<PropertyWrapper> propertyNameComparator;
|
||||
private Comparator<IDIYComponent<?>> componentZOrderComparator;
|
||||
|
||||
public static ComparatorFactory getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ComparatorFactory();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Comparator<IDIYComponent<?>> getComponentNameComparator() {
|
||||
if (componentNameComparator == null) {
|
||||
componentNameComparator = new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@Override
|
||||
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||
String name1 = o1.getName();
|
||||
String name2 = o2.getName();
|
||||
if (name1 == null || name2 == null) {
|
||||
return 0;
|
||||
}
|
||||
return name1.compareToIgnoreCase(name2);
|
||||
}
|
||||
};
|
||||
}
|
||||
return componentNameComparator;
|
||||
}
|
||||
|
||||
public Comparator<ComponentType> getComponentTypeComparator() {
|
||||
if (componentTypeComparator == null) {
|
||||
componentTypeComparator = new Comparator<ComponentType>() {
|
||||
|
||||
@Override
|
||||
public int compare(ComponentType o1, ComponentType o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
};
|
||||
}
|
||||
return componentTypeComparator;
|
||||
}
|
||||
|
||||
public Comparator<PropertyWrapper> getPropertyNameComparator() {
|
||||
if (propertyNameComparator == null) {
|
||||
propertyNameComparator = new Comparator<PropertyWrapper>() {
|
||||
|
||||
@Override
|
||||
public int compare(PropertyWrapper o1, PropertyWrapper o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
return propertyNameComparator;
|
||||
}
|
||||
|
||||
public Comparator<IDIYComponent<?>> getComponentZOrderComparator() {
|
||||
if (componentZOrderComparator == null) {
|
||||
componentZOrderComparator = new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@Override
|
||||
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||
ComponentType type1 = ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o1.getClass());
|
||||
ComponentType type2 = ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom(
|
||||
(Class<? extends IDIYComponent<?>>) o2.getClass());
|
||||
return new Double(type1.getZOrder()).compareTo(type2.getZOrder());
|
||||
}
|
||||
};
|
||||
}
|
||||
return componentZOrderComparator;
|
||||
}
|
||||
}
|
||||
-251
@@ -1,251 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IPropertyValidator;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
|
||||
/**
|
||||
* Utility class with component processing methods.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class ComponentProcessor {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ComponentProcessor.class);
|
||||
|
||||
private static ComponentProcessor instance;
|
||||
|
||||
private Map<String, List<PropertyWrapper>> propertyCache;
|
||||
private Map<String, IPropertyValidator> propertyValidatorCache;
|
||||
private Map<String, ComponentType> componentTypeMap;
|
||||
|
||||
public static ComponentProcessor getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new ComponentProcessor();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ComponentProcessor() {
|
||||
super();
|
||||
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) {
|
||||
if (componentTypeMap.containsKey(clazz.getName())) {
|
||||
return componentTypeMap.get(clazz.getName());
|
||||
}
|
||||
String name;
|
||||
String description;
|
||||
CreationMethod creationMethod;
|
||||
String category;
|
||||
String namePrefix;
|
||||
String author;
|
||||
Icon icon;
|
||||
double zOrder;
|
||||
boolean flexibleZOrder;
|
||||
boolean stretchable;
|
||||
BomPolicy bomPolicy;
|
||||
boolean autoEdit;
|
||||
boolean rotatable;
|
||||
if (clazz.isAnnotationPresent(ComponentDescriptor.class)) {
|
||||
ComponentDescriptor annotation = clazz.getAnnotation(ComponentDescriptor.class);
|
||||
name = annotation.name();
|
||||
description = annotation.description();
|
||||
creationMethod = annotation.creationMethod();
|
||||
category = annotation.category();
|
||||
namePrefix = annotation.instanceNamePrefix();
|
||||
author = annotation.author();
|
||||
zOrder = annotation.zOrder();
|
||||
flexibleZOrder = annotation.flexibleZOrder();
|
||||
stretchable = annotation.stretchable();
|
||||
bomPolicy = annotation.bomPolicy();
|
||||
autoEdit = annotation.autoEdit();
|
||||
rotatable = annotation.rotatable();
|
||||
} else {
|
||||
name = clazz.getSimpleName();
|
||||
description = "";
|
||||
creationMethod = CreationMethod.SINGLE_CLICK;
|
||||
category = "Uncategorized";
|
||||
namePrefix = "Unknown";
|
||||
author = "Unknown";
|
||||
zOrder = IDIYComponent.COMPONENT;
|
||||
flexibleZOrder = false;
|
||||
stretchable = true;
|
||||
bomPolicy = BomPolicy.SHOW_ALL_NAMES;
|
||||
autoEdit = true;
|
||||
rotatable = true;
|
||||
}
|
||||
icon = null;
|
||||
// Draw component icon.
|
||||
try {
|
||||
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);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
// g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
|
||||
// RenderingHints.VALUE_STROKE_PURE);
|
||||
componentInstance.drawIcon(g2d, Presenter.ICON_SIZE, Presenter.ICON_SIZE);
|
||||
icon = new ImageIcon(image);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ComponentType componentType = new ComponentType(name, description, creationMethod,
|
||||
category, namePrefix, author, icon, clazz, zOrder, flexibleZOrder, stretchable,
|
||||
bomPolicy, autoEdit, rotatable);
|
||||
componentTypeMap.put(clazz.getName(), componentType);
|
||||
return componentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts all editable properties from the component class.
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public List<PropertyWrapper> extractProperties(Class<?> clazz) {
|
||||
if (propertyCache.containsKey(clazz.getName())) {
|
||||
return cloneProperties(propertyCache.get(clazz.getName()));
|
||||
}
|
||||
List<PropertyWrapper> properties = new ArrayList<PropertyWrapper>();
|
||||
for (Method method : clazz.getMethods()) {
|
||||
if (method.getName().startsWith("get")) {
|
||||
try {
|
||||
if (method.isAnnotationPresent(EditableProperty.class)
|
||||
&& !method.isAnnotationPresent(Deprecated.class)) {
|
||||
EditableProperty annotation = method.getAnnotation(EditableProperty.class);
|
||||
String name;
|
||||
if (annotation.name().equals("")) {
|
||||
name = method.getName().substring(3);
|
||||
} else {
|
||||
name = annotation.name();
|
||||
}
|
||||
IPropertyValidator validator = getPropertyValidator(annotation
|
||||
.validatorClass());
|
||||
Method setter = clazz.getMethod("set" + method.getName().substring(3),
|
||||
method.getReturnType());
|
||||
PropertyWrapper property = new PropertyWrapper(name,
|
||||
method.getReturnType(), method.getName(), setter.getName(),
|
||||
annotation.defaultable(), validator);
|
||||
properties.add(property);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
LOG.debug("No matching setter found for \"" + method.getName()
|
||||
+ "\". Skipping...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
propertyCache.put(clazz.getName(), 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns properties that have the same value for all the selected
|
||||
* components.
|
||||
*
|
||||
* @param selectedComponents
|
||||
* @return
|
||||
*/
|
||||
public List<PropertyWrapper> getMutualSelectionProperties(
|
||||
List<IDIYComponent<?>> selectedComponents) throws Exception {
|
||||
if (selectedComponents.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
List<PropertyWrapper> properties = new ArrayList<PropertyWrapper>();
|
||||
IDIYComponent<?> firstComponent = selectedComponents.get(0);
|
||||
properties.addAll(extractProperties(firstComponent.getClass()));
|
||||
// Initialize values
|
||||
for (PropertyWrapper property : properties) {
|
||||
property.readFrom(firstComponent);
|
||||
}
|
||||
for (int i = 1; i < selectedComponents.size(); i++) {
|
||||
IDIYComponent<?> component = selectedComponents.get(i);
|
||||
List<PropertyWrapper> newProperties = extractProperties(component.getClass());
|
||||
for (PropertyWrapper property : newProperties) {
|
||||
property.readFrom(component);
|
||||
}
|
||||
properties.retainAll(newProperties);
|
||||
// Try to find matching properties in old and new lists and see if
|
||||
// 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) {
|
||||
if (!newProperty.getValue().equals(oldProperty.getValue()))
|
||||
// Values don't match, so the property is not unique
|
||||
// valued.
|
||||
oldProperty.setUnique(false);
|
||||
} else if ((newProperty.getValue() == null && oldProperty.getValue() != null)
|
||||
|| (newProperty.getValue() != null && oldProperty.getValue() == null)) {
|
||||
oldProperty.setUnique(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (PropertyWrapper property : properties) {
|
||||
// try {
|
||||
// property.readUniqueFrom(component);
|
||||
// } catch (Exception e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
Collections.sort(properties, ComparatorFactory.getInstance().getPropertyNameComparator());
|
||||
return properties;
|
||||
}
|
||||
|
||||
private IPropertyValidator getPropertyValidator(Class<? extends IPropertyValidator> clazz) {
|
||||
if (propertyValidatorCache.containsKey(clazz.getName())) {
|
||||
return propertyValidatorCache.get(clazz.getName());
|
||||
}
|
||||
IPropertyValidator validator;
|
||||
try {
|
||||
validator = clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not instantiate validator for " + clazz.getName(), e);
|
||||
return null;
|
||||
}
|
||||
propertyValidatorCache.put(clazz.getName(), validator);
|
||||
return validator;
|
||||
}
|
||||
}
|
||||
-425
@@ -1,425 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Area;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.appframework.simplemq.MessageDispatcher;
|
||||
import org.diylc.common.DrawOption;
|
||||
import org.diylc.common.EventType;
|
||||
import org.diylc.common.GridType;
|
||||
import org.diylc.common.IComponentFiler;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Theme;
|
||||
import org.diylc.core.VisibilityPolicy;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
/**
|
||||
* Utility that deals with painting {@link Project} on the {@link Graphics2D}
|
||||
* and keeps areas taken by each drawn component.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class DrawingManager {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(DrawingManager.class);
|
||||
|
||||
public static int CONTROL_POINT_SIZE = 7;
|
||||
|
||||
public static final String ZOOM_KEY = "zoom";
|
||||
|
||||
public static String DEBUG_COMPONENT_AREAS = "org.diylc.debugComponentAreas";
|
||||
|
||||
public static Color CONTROL_POINT_COLOR = Color.blue;
|
||||
public static Color SELECTED_CONTROL_POINT_COLOR = Color.green;
|
||||
|
||||
private Theme theme = (Theme) ConfigurationManager.getInstance()
|
||||
.readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
|
||||
// Keeps Area object of each drawn component.
|
||||
private Map<IDIYComponent<?>, Area> componentAreaMap;
|
||||
// Maps components to the last state they are drawn in. Also, used to
|
||||
// determine which components are invalidated when they are not in the map.
|
||||
private Map<IDIYComponent<?>, ComponentState> lastDrawnStateMap;
|
||||
|
||||
private Composite slotComposite = AlphaComposite.getInstance(
|
||||
AlphaComposite.SRC_OVER, 0.3f);
|
||||
private Composite lockedComposite = AlphaComposite.getInstance(
|
||||
AlphaComposite.SRC_OVER, 0.3f);
|
||||
private List<IDIYComponent<?>> failedComponents = new ArrayList<IDIYComponent<?>>();
|
||||
|
||||
private double zoomLevel = 1d;// ConfigurationManager.getInstance().readDouble(ZOOM_KEY,
|
||||
// 1d);
|
||||
|
||||
private MessageDispatcher<EventType> messageDispatcher;
|
||||
|
||||
private boolean debugComponentAreas;
|
||||
|
||||
public DrawingManager(MessageDispatcher<EventType> messageDispatcher) {
|
||||
super();
|
||||
this.messageDispatcher = messageDispatcher;
|
||||
componentAreaMap = new HashMap<IDIYComponent<?>, Area>();
|
||||
lastDrawnStateMap = new HashMap<IDIYComponent<?>, ComponentState>();
|
||||
String debugComponentAreasStr = System
|
||||
.getProperty(DEBUG_COMPONENT_AREAS);
|
||||
debugComponentAreas = debugComponentAreasStr != null
|
||||
&& debugComponentAreasStr.equalsIgnoreCase("true");
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the project onto the canvas and returns the list of components
|
||||
* that failed to draw.
|
||||
*
|
||||
* @param g2d
|
||||
* @param project
|
||||
* @param drawOptions
|
||||
* @param filter
|
||||
* @param selectionRect
|
||||
* @param selectedComponents
|
||||
* @param lockedComponents
|
||||
* @param groupedComponents
|
||||
* @param controlPointSlot
|
||||
* @param componentSlot
|
||||
* @param dragInProgress
|
||||
* @return
|
||||
*/
|
||||
public List<IDIYComponent<?>> drawProject(Graphics2D g2d, Project project,
|
||||
Set<DrawOption> drawOptions, IComponentFiler filter,
|
||||
Rectangle selectionRect, List<IDIYComponent<?>> selectedComponents,
|
||||
Set<IDIYComponent<?>> lockedComponents,
|
||||
Set<IDIYComponent<?>> groupedComponents,
|
||||
List<Point> controlPointSlot, List<IDIYComponent<?>> componentSlot,
|
||||
boolean dragInProgress) {
|
||||
failedComponents.clear();
|
||||
if (project == null) {
|
||||
return failedComponents;
|
||||
}
|
||||
G2DWrapper g2dWrapper = new G2DWrapper(g2d);
|
||||
|
||||
if (drawOptions.contains(DrawOption.ANTIALIASING)) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
} else {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_OFF);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
||||
}
|
||||
if (ConfigurationManager.getInstance().readBoolean(
|
||||
IPlugInPort.HI_QUALITY_RENDER_KEY, false)) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
|
||||
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
|
||||
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
|
||||
RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING,
|
||||
RenderingHints.VALUE_DITHER_ENABLE);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
// g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
|
||||
// RenderingHints.VALUE_STROKE_PURE);
|
||||
} else {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
|
||||
RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
|
||||
RenderingHints.VALUE_COLOR_RENDER_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
|
||||
RenderingHints.VALUE_RENDER_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING,
|
||||
RenderingHints.VALUE_DITHER_DISABLE);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||
}
|
||||
|
||||
double zoom = 1d;
|
||||
if (drawOptions.contains(DrawOption.ZOOM)) {
|
||||
zoom = zoomLevel;
|
||||
} else {
|
||||
zoom = 1 / Constants.PIXEL_SIZE;
|
||||
}
|
||||
|
||||
// AffineTransform initialTx = g2d.getTransform();
|
||||
Dimension d = getCanvasDimensions(project, zoom, true);
|
||||
|
||||
g2dWrapper.setColor(theme.getBgColor());
|
||||
g2dWrapper.fillRect(0, 0, d.width, d.height);
|
||||
g2d.clip(new Rectangle(new Point(0, 0), d));
|
||||
|
||||
GridType gridType = GridType.LINES;
|
||||
if (drawOptions.contains(DrawOption.GRID) && gridType != GridType.NONE) {
|
||||
double zoomStep = project.getGridSpacing().convertToPixels() * zoom;
|
||||
if (gridType == GridType.CROSSHAIR) {
|
||||
g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_MITER, 10f, new float[] {
|
||||
(float) zoomStep / 2, (float) zoomStep / 2 },
|
||||
(float) zoomStep / 4));
|
||||
} else if (gridType == GridType.DOT) {
|
||||
g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_MITER, 10f, new float[] { 1f,
|
||||
(float) zoomStep - 1 }, 0f));
|
||||
}
|
||||
|
||||
g2dWrapper.setColor(theme.getGridColor());
|
||||
for (double i = zoomStep; i < d.width; i += zoomStep) {
|
||||
g2dWrapper.drawLine((int) i, 0, (int) i, d.height - 1);
|
||||
}
|
||||
for (double j = zoomStep; j < d.height; j += zoomStep) {
|
||||
g2dWrapper.drawLine(0, (int) j, d.width - 1, (int) j);
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.abs(1.0 - zoom) > 1e-4) {
|
||||
g2dWrapper.scale(zoom, zoom);
|
||||
}
|
||||
|
||||
// Composite mainComposite = g2d.getComposite();
|
||||
// Composite alphaComposite =
|
||||
// AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
|
||||
|
||||
// g2dWrapper.resetTx();
|
||||
|
||||
// componentAreaMap.clear();
|
||||
for (IDIYComponent<?> component : project.getComponents()) {
|
||||
// Do not draw the component if it's filtered out.
|
||||
if (filter != null && !filter.testComponent(component)) {
|
||||
continue;
|
||||
}
|
||||
ComponentState state = ComponentState.NORMAL;
|
||||
if (drawOptions.contains(DrawOption.SELECTION)
|
||||
&& selectedComponents.contains(component)) {
|
||||
if (dragInProgress) {
|
||||
state = ComponentState.DRAGGING;
|
||||
} else {
|
||||
state = ComponentState.SELECTED;
|
||||
}
|
||||
}
|
||||
// Do not track the area if component is not invalidated and was
|
||||
// drawn in the same state.
|
||||
boolean trackArea = lastDrawnStateMap.get(component) != state;
|
||||
|
||||
synchronized (g2d) {
|
||||
g2dWrapper.startedDrawingComponent();
|
||||
if (!trackArea) {
|
||||
g2dWrapper.stopTracking();
|
||||
}
|
||||
// Draw locked components in a new composite.
|
||||
if (lockedComponents.contains(component)) {
|
||||
g2d.setComposite(lockedComposite);
|
||||
}
|
||||
// Draw the component through the g2dWrapper.
|
||||
try {
|
||||
component.draw(g2dWrapper, state, drawOptions
|
||||
.contains(DrawOption.OUTLINE_MODE), project,
|
||||
g2dWrapper);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error drawing " + component.getName(), e);
|
||||
failedComponents.add(component);
|
||||
}
|
||||
Area area = g2dWrapper.finishedDrawingComponent();
|
||||
if (trackArea && area != null && !area.isEmpty()) {
|
||||
componentAreaMap.put(component, area);
|
||||
lastDrawnStateMap.put(component, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw control points.
|
||||
if (drawOptions.contains(DrawOption.CONTROL_POINTS)) {
|
||||
// Draw unselected points first to make sure they are below.
|
||||
if (dragInProgress || drawOptions.contains(DrawOption.OUTLINE_MODE)) {
|
||||
for (IDIYComponent<?> component : project.getComponents()) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
VisibilityPolicy visibilityPolicy = component
|
||||
.getControlPointVisibilityPolicy(i);
|
||||
if ((groupedComponents.contains(component)
|
||||
&& (visibilityPolicy == VisibilityPolicy.ALWAYS || (selectedComponents
|
||||
.contains(component) && visibilityPolicy == VisibilityPolicy.WHEN_SELECTED)) || (!groupedComponents
|
||||
.contains(component)
|
||||
&& !selectedComponents.contains(component) && component
|
||||
.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS))) {
|
||||
g2dWrapper.setColor(CONTROL_POINT_COLOR);
|
||||
Point controlPoint = component.getControlPoint(i);
|
||||
int pointSize = CONTROL_POINT_SIZE - 2;
|
||||
g2dWrapper.fillOval(controlPoint.x - pointSize / 2,
|
||||
controlPoint.y - pointSize / 2, pointSize,
|
||||
pointSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Then draw the selected ones.
|
||||
for (IDIYComponent<?> component : selectedComponents) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
if (!groupedComponents.contains(component)
|
||||
&& (component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.WHEN_SELECTED || component
|
||||
.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS)) {
|
||||
|
||||
Point controlPoint = component.getControlPoint(i);
|
||||
int pointSize = CONTROL_POINT_SIZE;
|
||||
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR
|
||||
.darker());
|
||||
g2dWrapper.fillOval(controlPoint.x - pointSize / 2,
|
||||
controlPoint.y - pointSize / 2, pointSize,
|
||||
pointSize);
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
||||
g2dWrapper.fillOval(controlPoint.x - CONTROL_POINT_SIZE
|
||||
/ 2 + 1, controlPoint.y - CONTROL_POINT_SIZE
|
||||
/ 2 + 1, CONTROL_POINT_SIZE - 2,
|
||||
CONTROL_POINT_SIZE - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw component slot in a separate composite.
|
||||
if (componentSlot != null) {
|
||||
g2dWrapper.startedDrawingComponent();
|
||||
g2dWrapper.setComposite(slotComposite);
|
||||
for (IDIYComponent<?> component : componentSlot) {
|
||||
try {
|
||||
|
||||
component.draw(g2dWrapper, ComponentState.NORMAL,
|
||||
drawOptions.contains(DrawOption.OUTLINE_MODE),
|
||||
project, g2dWrapper);
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error drawing " + component.getName(), e);
|
||||
failedComponents.add(component);
|
||||
}
|
||||
}
|
||||
g2dWrapper.finishedDrawingComponent();
|
||||
}
|
||||
|
||||
// Draw control points of the component in the slot.
|
||||
if (controlPointSlot != null) {
|
||||
for (Point point : controlPointSlot) {
|
||||
if (point != null) {
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
||||
g2dWrapper.fillOval(point.x - CONTROL_POINT_SIZE / 2,
|
||||
point.y - CONTROL_POINT_SIZE / 2,
|
||||
CONTROL_POINT_SIZE, CONTROL_POINT_SIZE);
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
||||
g2dWrapper.fillOval(point.x - CONTROL_POINT_SIZE / 2 + 1,
|
||||
point.y - CONTROL_POINT_SIZE / 2 + 1,
|
||||
CONTROL_POINT_SIZE - 2, CONTROL_POINT_SIZE - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go back to the original transformation and zoom in to draw the
|
||||
// selection rectangle and other similar elements.
|
||||
// g2d.setTransform(initialTx);
|
||||
// if ((drawOptions.contains(DrawOption.ZOOM)) && (Math.abs(1.0 -
|
||||
// zoomLevel) > 1e-4)) {
|
||||
// g2d.scale(zoomLevel, zoomLevel);
|
||||
// }
|
||||
|
||||
// At the end draw selection rectangle if needed.
|
||||
if (drawOptions.contains(DrawOption.SELECTION)
|
||||
&& (selectionRect != null)) {
|
||||
g2d.setColor(Color.white);
|
||||
g2d.draw(selectionRect);
|
||||
g2d.setColor(Color.black);
|
||||
g2d.setStroke(Constants.DASHED_STROKE);
|
||||
g2d.draw(selectionRect);
|
||||
}
|
||||
|
||||
// Draw component area for test
|
||||
if (debugComponentAreas) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||
g2d.setColor(Color.red);
|
||||
for (Area area : componentAreaMap.values()) {
|
||||
g2d.draw(area);
|
||||
}
|
||||
}
|
||||
|
||||
return failedComponents;
|
||||
}
|
||||
|
||||
public double getZoomLevel() {
|
||||
return zoomLevel;
|
||||
}
|
||||
|
||||
public void setZoomLevel(double zoomLevel) {
|
||||
this.zoomLevel = zoomLevel;
|
||||
fireZoomChanged();
|
||||
// ConfigurationManager.getInstance().writeValue(ZOOM_KEY, zoomLevel);
|
||||
}
|
||||
|
||||
public void invalidateComponent(IDIYComponent<?> component) {
|
||||
componentAreaMap.remove(component);
|
||||
lastDrawnStateMap.remove(component);
|
||||
}
|
||||
|
||||
public Area getComponentArea(IDIYComponent<?> component) {
|
||||
return componentAreaMap.get(component);
|
||||
}
|
||||
|
||||
public void clearComponentAreaMap() {
|
||||
componentAreaMap.clear();
|
||||
lastDrawnStateMap.clear();
|
||||
}
|
||||
|
||||
public List<IDIYComponent<?>> findComponentsAt(Point point, Project project) {
|
||||
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
|
||||
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(0, project.getComponents().get(i));
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
public Dimension getCanvasDimensions(Project project, Double zoomLevel,
|
||||
boolean useZoom) {
|
||||
double width = project.getWidth().convertToPixels();
|
||||
double height = project.getHeight().convertToPixels();
|
||||
if (useZoom) {
|
||||
width *= zoomLevel;
|
||||
height *= zoomLevel;
|
||||
} else {
|
||||
width /= Constants.PIXEL_SIZE;
|
||||
height /= Constants.PIXEL_SIZE;
|
||||
}
|
||||
return new Dimension((int) width, (int) height);
|
||||
}
|
||||
|
||||
public void fireZoomChanged() {
|
||||
messageDispatcher.dispatchMessage(EventType.ZOOM_CHANGED, zoomLevel);
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
}
|
||||
|
||||
public Theme getTheme() {
|
||||
return theme;
|
||||
}
|
||||
|
||||
public void setTheme(Theme theme) {
|
||||
this.theme = theme;
|
||||
ConfigurationManager.getInstance().writeValue(IPlugInPort.THEME_KEY,
|
||||
theme);
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
}
|
||||
}
|
||||
-399
@@ -1,399 +0,0 @@
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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.OrientationHV;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.core.CreationMethod;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Template;
|
||||
import org.diylc.core.measures.Size;
|
||||
|
||||
/**
|
||||
* Manages component instantiation.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class InstantiationManager {
|
||||
|
||||
private static final Logger LOG = Logger
|
||||
.getLogger(InstantiationManager.class);
|
||||
|
||||
public static int MAX_RECENT_COMPONENTS = 16;
|
||||
|
||||
private ComponentType componentTypeSlot;
|
||||
private Template template;
|
||||
private List<IDIYComponent<?>> componentSlot;
|
||||
private Point firstControlPoint;
|
||||
private Point potentialControlPoint;
|
||||
|
||||
private static final ComponentType clipboardType = new ComponentType(
|
||||
"Clipboard contents", "Components from the clipboard",
|
||||
CreationMethod.SINGLE_CLICK, "Multi", "", "", null, null, 0, false,
|
||||
false, null, false, true);
|
||||
|
||||
public InstantiationManager() {
|
||||
}
|
||||
|
||||
public ComponentType getComponentTypeSlot() {
|
||||
return componentTypeSlot;
|
||||
}
|
||||
|
||||
public Template getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
public List<IDIYComponent<?>> getComponentSlot() {
|
||||
return componentSlot;
|
||||
}
|
||||
|
||||
public Point getFirstControlPoint() {
|
||||
return firstControlPoint;
|
||||
}
|
||||
|
||||
public Point getPotentialControlPoint() {
|
||||
return potentialControlPoint;
|
||||
}
|
||||
|
||||
public void setComponentTypeSlot(ComponentType componentTypeSlot,
|
||||
Template template, Project currentProject) throws Exception {
|
||||
this.componentTypeSlot = componentTypeSlot;
|
||||
this.template = template;
|
||||
if (componentTypeSlot == null) {
|
||||
this.componentSlot = null;
|
||||
} else {
|
||||
switch (componentTypeSlot.getCreationMethod()) {
|
||||
case POINT_BY_POINT:
|
||||
this.componentSlot = null;
|
||||
break;
|
||||
case SINGLE_CLICK:
|
||||
this.componentSlot = instantiateComponent(componentTypeSlot,
|
||||
template, new Point(0, 0), currentProject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.firstControlPoint = null;
|
||||
this.potentialControlPoint = null;
|
||||
}
|
||||
|
||||
public void instatiatePointByPoint(Point scaledPoint, Project currentProject)
|
||||
throws Exception {
|
||||
firstControlPoint = scaledPoint;
|
||||
componentSlot = instantiateComponent(componentTypeSlot, template,
|
||||
firstControlPoint, currentProject);
|
||||
|
||||
// Set the other control point to the same location, we'll
|
||||
// move it later when mouse moves.
|
||||
componentSlot.get(0).setControlPoint(firstControlPoint, 0);
|
||||
componentSlot.get(0).setControlPoint(firstControlPoint, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates component in the slot with the new second control point.
|
||||
*
|
||||
* @param scaledPoint
|
||||
* @return true, if any change is made
|
||||
*/
|
||||
public boolean updatePointByPoint(Point scaledPoint) {
|
||||
boolean changeMade = !scaledPoint.equals(potentialControlPoint);
|
||||
potentialControlPoint = scaledPoint;
|
||||
if (componentSlot != null && !componentSlot.isEmpty()) {
|
||||
componentSlot.get(0).setControlPoint(scaledPoint, 1);
|
||||
}
|
||||
return changeMade;
|
||||
}
|
||||
|
||||
public void pasteComponents(List<IDIYComponent<?>> components,
|
||||
Point scaledPoint, boolean snapToGrid, Size gridSpacing) {
|
||||
// Adjust location of components so they are centered under the mouse
|
||||
// cursor
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int maxX = Integer.MIN_VALUE;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int maxY = Integer.MIN_VALUE;
|
||||
for (IDIYComponent<?> component : components) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
Point p = component.getControlPoint(i);
|
||||
if (p.x > maxX) {
|
||||
maxX = p.x;
|
||||
}
|
||||
if (p.x < minX) {
|
||||
minX = p.x;
|
||||
}
|
||||
if (p.y > maxY) {
|
||||
maxY = p.y;
|
||||
}
|
||||
if (p.y < minY) {
|
||||
minY = p.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
int x = minX;
|
||||
int y = minY;
|
||||
if (snapToGrid) {
|
||||
x = CalcUtils.roundToGrid(x, gridSpacing);
|
||||
x = CalcUtils.roundToGrid(x, gridSpacing);
|
||||
}
|
||||
for (IDIYComponent<?> component : components) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
Point p = component.getControlPoint(i);
|
||||
p.translate(-x, -y);
|
||||
component.setControlPoint(p, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Update component slot
|
||||
this.componentSlot = new ArrayList<IDIYComponent<?>>(components);
|
||||
|
||||
// Update the component type slot so the app knows that something's
|
||||
// being instantiated.
|
||||
this.componentTypeSlot = clipboardType;
|
||||
|
||||
if (snapToGrid) {
|
||||
scaledPoint = new Point(scaledPoint);
|
||||
CalcUtils.snapPointToGrid(scaledPoint, gridSpacing);
|
||||
}
|
||||
// Update the location according to mouse location
|
||||
updateSingleClick(scaledPoint, snapToGrid, gridSpacing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates location of component slot based on the new mouse location.
|
||||
*
|
||||
* @param scaledPoint
|
||||
* @param snapToGrid
|
||||
* @param gridSpacing
|
||||
* @return true if we need to refresh the canvas
|
||||
*/
|
||||
public boolean updateSingleClick(Point scaledPoint, boolean snapToGrid,
|
||||
Size gridSpacing) {
|
||||
if (potentialControlPoint == null) {
|
||||
potentialControlPoint = new Point(0, 0);
|
||||
}
|
||||
if (scaledPoint == null) {
|
||||
scaledPoint = new Point(0, 0);
|
||||
}
|
||||
int dx = scaledPoint.x - potentialControlPoint.x;
|
||||
int dy = scaledPoint.y - potentialControlPoint.y;
|
||||
if (snapToGrid) {
|
||||
dx = CalcUtils.roundToGrid(dx, gridSpacing);
|
||||
dy = CalcUtils.roundToGrid(dy, gridSpacing);
|
||||
}
|
||||
// Only repaint if there's an actual change.
|
||||
if (dx == 0 && dy == 0) {
|
||||
return false;
|
||||
}
|
||||
potentialControlPoint.translate(dx, dy);
|
||||
if (componentSlot == null) {
|
||||
LOG.error("Component slot should not be null!");
|
||||
} else {
|
||||
Point p = new Point();
|
||||
for (IDIYComponent<?> component : componentSlot) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
p.setLocation(component.getControlPoint(i));
|
||||
p.translate(dx, dy);
|
||||
component.setControlPoint(p, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<IDIYComponent<?>> instantiateComponent(
|
||||
ComponentType componentType, Template template, Point point,
|
||||
Project currentProject) throws Exception {
|
||||
LOG.info("Instatiating component of type: "
|
||||
+ componentType.getInstanceClass().getName());
|
||||
|
||||
// Instantiate the component.
|
||||
IDIYComponent<?> component = componentType.getInstanceClass()
|
||||
.newInstance();
|
||||
|
||||
component.setName(createUniqueName(componentType, currentProject));
|
||||
|
||||
// Translate them to the desired location.
|
||||
if (point != null) {
|
||||
for (int j = 0; j < component.getControlPointCount(); j++) {
|
||||
Point controlPoint = new Point(component.getControlPoint(j));
|
||||
controlPoint.translate(point.x, point.y);
|
||||
// snapPointToGrid(controlPoint);
|
||||
component.setControlPoint(controlPoint, j);
|
||||
}
|
||||
}
|
||||
|
||||
loadComponentShapeFromTemplate(component, template);
|
||||
|
||||
fillWithDefaultProperties(component, template);
|
||||
|
||||
// Write to recent components
|
||||
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)) {
|
||||
// Remove if it's already somewhere in the list.
|
||||
recentComponentTypes.remove(className);
|
||||
// Add to the end of the list.
|
||||
recentComponentTypes.add(0, className);
|
||||
// Trim the list if necessary.
|
||||
if (recentComponentTypes.size() > MAX_RECENT_COMPONENTS) {
|
||||
recentComponentTypes.remove(recentComponentTypes.size() - 1);
|
||||
}
|
||||
ConfigurationManager.getInstance().writeValue(
|
||||
IPlugInPort.RECENT_COMPONENTS_KEY, recentComponentTypes);
|
||||
}
|
||||
|
||||
List<IDIYComponent<?>> list = new ArrayList<IDIYComponent<?>>();
|
||||
list.add(component);
|
||||
return list;
|
||||
}
|
||||
|
||||
public String createUniqueName(ComponentType componentType,
|
||||
Project currentProject) {
|
||||
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(j).getName();
|
||||
}
|
||||
Arrays.sort(takenNames);
|
||||
int i = 0;
|
||||
while (exists) {
|
||||
i++;
|
||||
String name = componentType.getNamePrefix() + i;
|
||||
exists = false;
|
||||
if (Arrays.binarySearch(takenNames, name) >= 0) {
|
||||
exists = true;
|
||||
}
|
||||
}
|
||||
return componentType.getNamePrefix() + i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds any properties that have default values and injects default values.
|
||||
* Typically it should be used for {@link IDIYComponent} and {@link Project}
|
||||
* objects.
|
||||
*
|
||||
* @param object
|
||||
* @param template
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
* @throws NoSuchMethodException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
public void fillWithDefaultProperties(Object object, Template template)
|
||||
throws IllegalArgumentException, IllegalAccessException,
|
||||
InvocationTargetException, SecurityException, NoSuchMethodException {
|
||||
// Extract properties.
|
||||
List<PropertyWrapper> properties = ComponentProcessor.getInstance()
|
||||
.extractProperties(object.getClass());
|
||||
Map<String, PropertyWrapper> propertyCache = new HashMap<String, PropertyWrapper>();
|
||||
// Override with default values if available.
|
||||
for (PropertyWrapper property : properties) {
|
||||
propertyCache.put(property.getName(), property);
|
||||
Object defaultValue = ConfigurationManager.getInstance()
|
||||
.readObject(
|
||||
Presenter.DEFAULTS_KEY_PREFIX
|
||||
+ object.getClass().getName() + ":"
|
||||
+ property.getName(), null);
|
||||
if (defaultValue != null) {
|
||||
property.setValue(defaultValue);
|
||||
property.writeTo(object);
|
||||
}
|
||||
}
|
||||
if (template != null) {
|
||||
for (Map.Entry<String, Object> pair : template.getValues()
|
||||
.entrySet()) {
|
||||
PropertyWrapper property = propertyCache.get(pair.getKey());
|
||||
if (property == null) {
|
||||
LOG.warn("Cannot find property " + pair.getKey());
|
||||
} else {
|
||||
LOG.debug("Filling value from template for "
|
||||
+ pair.getKey());
|
||||
property.setValue(pair.getValue());
|
||||
property.writeTo(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses stored control points from the template to shape component.
|
||||
*
|
||||
* @param component
|
||||
* @param template
|
||||
*/
|
||||
public void loadComponentShapeFromTemplate(IDIYComponent<?> component,
|
||||
Template template) {
|
||||
if (template != null
|
||||
&& template.getPoints() != null
|
||||
&& template.getPoints().size() >= component
|
||||
.getControlPointCount()) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
Point p = new Point(component.getControlPoint(0));
|
||||
p.translate(template.getPoints().get(i).x, template.getPoints()
|
||||
.get(i).y);
|
||||
component.setControlPoint(p, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
|| propertyWrapper.getType().getName().equals(
|
||||
OrientationHV.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 {
|
||||
for (IDIYComponent<?> component : this.componentSlot) {
|
||||
angleProperty.readFrom(component);
|
||||
Object value = angleProperty.getValue();
|
||||
if (value instanceof Orientation) {
|
||||
angleProperty
|
||||
.setValue(Orientation.values()[(((Orientation) value)
|
||||
.ordinal() + 1)
|
||||
% Orientation.values().length]);
|
||||
} else if (value instanceof OrientationHV) {
|
||||
angleProperty
|
||||
.setValue(OrientationHV.values()[(((OrientationHV) value)
|
||||
.ordinal() + 1)
|
||||
% OrientationHV.values().length]);
|
||||
}
|
||||
angleProperty.writeTo(component);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Error trying to rotate the component", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user