improve continuity highlighting

massively simplified outline tracing
This commit is contained in:
Branislav Stojkovic
2018-12-16 01:47:30 +01:00
parent 58a4ff987f
commit 2cc916c8c1
10 changed files with 230 additions and 301 deletions
@@ -21,32 +21,31 @@
*/ */
package org.diylc.components; package org.diylc.components;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
import java.awt.Color; import java.awt.Color;
import java.awt.Composite; import java.awt.Composite;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Shape; import java.awt.Shape;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D; import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.Observable;
import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.Display; import org.diylc.common.Display;
import org.diylc.common.IPlugInPort; import org.diylc.common.IPlugInPort;
import org.diylc.common.ObjectCache; import org.diylc.common.ObjectCache;
import org.diylc.core.ComponentState; import org.diylc.core.ComponentState;
import org.diylc.core.IDrawingObserver; import org.diylc.core.IDrawingObserver;
import org.diylc.core.Project; import org.diylc.core.Project;
import org.diylc.core.Theme; import org.diylc.core.Theme;
import org.diylc.core.VisibilityPolicy; import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty; import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size; import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.SizeUnit;
import org.diylc.utils.Constants; import org.diylc.utils.Constants;
/** /**
* Base class for all leaded components such as resistors or capacitors. Has two control points and * Base class for all leaded components such as resistors or capacitors. Has two control points and
@@ -391,6 +391,10 @@ public class DrawingManager {
componentAreaMap.clear(); componentAreaMap.clear();
lastDrawnStateMap.clear(); lastDrawnStateMap.clear();
} }
public void clearContinuityArea() {
this.continuityArea = null;
}
public List<IDIYComponent<?>> findComponentsAt(Point point, Project project) { public List<IDIYComponent<?>> findComponentsAt(Point point, Project project) {
List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>(); List<IDIYComponent<?>> components = new ArrayList<IDIYComponent<?>>();
@@ -30,21 +30,18 @@ import java.awt.Paint;
import java.awt.Polygon; import java.awt.Polygon;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.RenderingHints.Key;
import java.awt.Shape; import java.awt.Shape;
import java.awt.Stroke; import java.awt.Stroke;
import java.awt.RenderingHints.Key;
import java.awt.font.FontRenderContext; import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector; import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D; import java.awt.geom.Arc2D;
import java.awt.geom.Area; import java.awt.geom.Area;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Ellipse2D; import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D; import java.awt.geom.Line2D;
import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.QuadCurve2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D; import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@@ -88,8 +85,8 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
private AffineTransform currentTx; private AffineTransform currentTx;
private AffineTransform initialTx; private AffineTransform initialTx;
private Area currentArea; private Area currentArea;
private List<Area> currentContinuityPositiveAreas; private List<Area> continuityPositiveAreas;
private List<Area> currentContinuityNegativeAreas; private List<Area> continuityNegativeAreas;
private Shape lastShape; private Shape lastShape;
private double zoom; private double zoom;
@@ -104,8 +101,8 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
this.canvasGraphics = canvasGraphics; this.canvasGraphics = canvasGraphics;
this.zoom = zoom; this.zoom = zoom;
currentArea = new Area(); currentArea = new Area();
currentContinuityPositiveAreas = new ArrayList<Area>(); continuityPositiveAreas = new ArrayList<Area>();
currentContinuityNegativeAreas = new ArrayList<Area>(); continuityNegativeAreas = new ArrayList<Area>();
currentTx = new AffineTransform(); currentTx = new AffineTransform();
} }
@@ -115,8 +112,8 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
public void startedDrawingComponent() { public void startedDrawingComponent() {
drawingComponent = true; drawingComponent = true;
currentArea = new Area(); currentArea = new Area();
currentContinuityPositiveAreas = new ArrayList<Area>(); continuityPositiveAreas = new ArrayList<Area>();
currentContinuityNegativeAreas = new ArrayList<Area>(); continuityNegativeAreas = new ArrayList<Area>();
originalStroke = canvasGraphics.getStroke(); originalStroke = canvasGraphics.getStroke();
originalColor = canvasGraphics.getColor(); originalColor = canvasGraphics.getColor();
originalTx = canvasGraphics.getTransform(); originalTx = canvasGraphics.getTransform();
@@ -140,7 +137,7 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
canvasGraphics.setTransform(originalTx); canvasGraphics.setTransform(originalTx);
canvasGraphics.setComposite(originalComposite); canvasGraphics.setComposite(originalComposite);
canvasGraphics.setFont(originalFont); canvasGraphics.setFont(originalFont);
return new ComponentArea(currentArea, currentContinuityPositiveAreas, currentContinuityNegativeAreas); return new ComponentArea(currentArea, continuityPositiveAreas, continuityNegativeAreas);
} }
@Override @Override
@@ -185,9 +182,9 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
if (trackingContinuityAllowed) { if (trackingContinuityAllowed) {
if (trackingContinuityPositive) if (trackingContinuityPositive)
currentContinuityPositiveAreas.add(area); continuityPositiveAreas.add(area);
else else
currentContinuityNegativeAreas.add(area); continuityNegativeAreas.add(area);
} }
lastShape = s; lastShape = s;
} }
@@ -203,95 +200,8 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver {
if (!drawingComponent || !trackingAllowed || s.equals(lastShape)) { if (!drawingComponent || !trackingAllowed || s.equals(lastShape)) {
return; 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();
}
}
/** appendShape(getStroke().createStrokedShape(s));
* 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 @Override
@@ -236,7 +236,8 @@ public class Presenter implements IPlugInPort {
public void loadProject(Project project, boolean freshStart) { public void loadProject(Project project, boolean freshStart) {
LOG.info(String.format("loadProject(%s, %s)", project.getTitle(), freshStart)); LOG.info(String.format("loadProject(%s, %s)", project.getTitle(), freshStart));
this.currentProject = project; this.currentProject = project;
drawingManager.clearComponentAreaMap(); drawingManager.clearComponentAreaMap();
drawingManager.clearContinuityArea();
updateSelection(EMPTY_SELECTION); updateSelection(EMPTY_SELECTION);
messageDispatcher.dispatchMessage(EventType.PROJECT_LOADED, project, freshStart); messageDispatcher.dispatchMessage(EventType.PROJECT_LOADED, project, freshStart);
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
@@ -597,7 +598,8 @@ public class Presenter implements IPlugInPort {
// Notify the listeners. // Notify the listeners.
if (!oldProject.equals(currentProject)) { if (!oldProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Add " messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Add "
+ componentTypeSlot.getName()); + componentTypeSlot.getName());
drawingManager.clearContinuityArea();
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
} }
} else if (ConfigurationManager.getInstance().readBoolean(HIGHLIGHT_CONTINUITY_AREA, false)) { } else if (ConfigurationManager.getInstance().readBoolean(HIGHLIGHT_CONTINUITY_AREA, false)) {
@@ -688,7 +690,8 @@ public class Presenter implements IPlugInPort {
return false; return false;
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
"Rotate Selection"); "Rotate Selection");
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
drawingManager.clearContinuityArea();
return true; return true;
} }
@@ -916,7 +919,8 @@ public class Presenter implements IPlugInPort {
Project oldProject = currentProject.clone(); Project oldProject = currentProject.clone();
moveComponents(controlPointMap, dx, dy, false); moveComponents(controlPointMap, dx, dy, false);
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Move Selection"); messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Move Selection");
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
drawingManager.clearContinuityArea();
} }
@Override @Override
@@ -1197,7 +1201,8 @@ public class Presenter implements IPlugInPort {
Project oldProject = currentProject.clone(); Project oldProject = currentProject.clone();
rotateComponents(this.selectedComponents, direction, isSnapToGrid()); rotateComponents(this.selectedComponents, direction, isSnapToGrid());
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
"Rotate Selection"); "Rotate Selection");
drawingManager.clearContinuityArea();
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
} }
} }
@@ -1307,7 +1312,8 @@ public class Presenter implements IPlugInPort {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
"Mirror Selection"); "Mirror Selection");
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
drawingManager.clearContinuityArea();
} }
} }
@@ -1419,7 +1425,8 @@ public class Presenter implements IPlugInPort {
// operation. // operation.
if (!preDragProject.equals(currentProject)) { if (!preDragProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, preDragProject, currentProject.clone(), "Drag"); messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, preDragProject, currentProject.clone(), "Drag");
drawingManager.clearContinuityArea();
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
} }
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
@@ -1468,7 +1475,8 @@ public class Presenter implements IPlugInPort {
updateSelection(newSelection); updateSelection(newSelection);
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Duplicate"); messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Duplicate");
drawingManager.clearContinuityArea();
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
} }
@@ -1488,7 +1496,8 @@ public class Presenter implements IPlugInPort {
drawingManager.invalidateComponent(component); drawingManager.invalidateComponent(component);
} }
currentProject.getComponents().removeAll(selectedComponents); currentProject.getComponents().removeAll(selectedComponents);
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Delete"); messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Delete");
drawingManager.clearContinuityArea();
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
updateSelection(EMPTY_SELECTION); updateSelection(EMPTY_SELECTION);
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
@@ -1527,7 +1536,7 @@ public class Presenter implements IPlugInPort {
// Notify the listeners. // Notify the listeners.
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
if (!oldProject.equals(currentProject)) { if (!oldProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Group"); messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Group");
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
} }
} }
@@ -1540,7 +1549,7 @@ public class Presenter implements IPlugInPort {
// Notify the listeners. // Notify the listeners.
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
if (!oldProject.equals(currentProject)) { if (!oldProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Ungroup"); messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Ungroup");
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
} }
} }
@@ -1618,7 +1627,7 @@ public class Presenter implements IPlugInPort {
} }
} }
if (!oldProject.equals(currentProject)) { if (!oldProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Send to Back"); messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), "Send to Back");
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
} }
@@ -1672,7 +1681,7 @@ public class Presenter implements IPlugInPort {
} }
if (!oldProject.equals(currentProject)) { if (!oldProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
"Bring to Front"); "Bring to Front");
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
} }
@@ -1984,7 +1993,8 @@ public class Presenter implements IPlugInPort {
// Notify the listeners. // Notify the listeners.
if (!oldProject.equals(currentProject)) { if (!oldProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
"Edit Selection"); "Edit Selection");
drawingManager.clearContinuityArea();
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
} }
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
@@ -2021,7 +2031,8 @@ public class Presenter implements IPlugInPort {
// Notify the listeners. // Notify the listeners.
if (!oldProject.equals(currentProject)) { if (!oldProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
"Edit Project"); "Edit Project");
drawingManager.clearContinuityArea();
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
} }
drawingManager.fireZoomChanged(); drawingManager.fireZoomChanged();
@@ -2199,7 +2210,8 @@ public class Presenter implements IPlugInPort {
// Notify the listeners. // Notify the listeners.
if (!oldProject.equals(currentProject)) { if (!oldProject.equals(currentProject)) {
messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(), messageDispatcher.dispatchMessage(EventType.PROJECT_MODIFIED, oldProject, currentProject.clone(),
"Edit Selection"); "Edit Selection");
drawingManager.clearContinuityArea();
projectFileManager.notifyFileChange(); projectFileManager.notifyFileChange();
} }
messageDispatcher.dispatchMessage(EventType.REPAINT); messageDispatcher.dispatchMessage(EventType.REPAINT);
Binary file not shown.
@@ -1,163 +1,165 @@
/* /*
*
* DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 held jointly by the individual authors.
*
* This file is part of DIYLC.
*
* DIYLC is free software: you can redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* DIYLC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with DIYLC. If not, see
* <http://www.gnu.org/licenses/>.
*/
package org.diylc.components.connectivity;
DIY Layout Creator (DIYLC). import java.awt.Color;
Copyright (c) 2009-2018 held jointly by the individual authors. import java.awt.Graphics2D;
import java.awt.Shape;
This file is part of DIYLC. import org.diylc.common.SimpleComponentTransformer;
import org.diylc.common.ObjectCache;
import org.diylc.common.PCBLayer;
import org.diylc.components.AbstractLeadedComponent;
import org.diylc.core.ComponentState;
import org.diylc.core.CreationMethod;
import org.diylc.core.IDIYComponent;
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy;
import org.diylc.core.annotations.ComponentDescriptor;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.annotations.KeywordPolicy;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
DIYLC is free software: you can redistribute it and/or modify @ComponentDescriptor(name = "Copper Trace", author = "Branislav Stojkovic", category = "Connectivity",
it under the terms of the GNU General Public License as published by creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "Trace",
the Free Software Foundation, either version 3 of the License, or description = "Straight copper trace", zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW,
(at your option) any later version. autoEdit = false, keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB",
transformer = SimpleComponentTransformer.class)
public class CopperTrace extends AbstractLeadedComponent<Void> {
DIYLC is distributed in the hope that it will be useful, private static final long serialVersionUID = 1L;
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License public static Size THICKNESS = new Size(1d, SizeUnit.mm);
along with DIYLC. If not, see <http://www.gnu.org/licenses/>. public static Color COLOR = Color.black;
*/ private Size thickness = THICKNESS;
package org.diylc.components.connectivity; private PCBLayer layer = PCBLayer._1;
import java.awt.Color; public CopperTrace() {
import java.awt.Graphics2D; super();
import java.awt.Shape; this.leadColor = COLOR;
}
import org.diylc.common.SimpleComponentTransformer;
import org.diylc.common.ObjectCache; @Override
import org.diylc.common.PCBLayer; public void drawIcon(Graphics2D g2d, int width, int height) {
import org.diylc.components.AbstractLeadedComponent; g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(3));
import org.diylc.core.ComponentState; g2d.setColor(COLOR);
import org.diylc.core.CreationMethod; g2d.drawLine(1, height - 2, width - 2, 1);
import org.diylc.core.IDIYComponent; }
import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.BomPolicy; @Override
import org.diylc.core.annotations.ComponentDescriptor; protected Color getLeadColorForPainting(ComponentState componentState) {
import org.diylc.core.annotations.EditableProperty; return componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
import org.diylc.core.annotations.KeywordPolicy; : getLeadColor();
import org.diylc.core.measures.Size; }
import org.diylc.core.measures.SizeUnit;
@Override
@ComponentDescriptor(name = "Copper Trace", author = "Branislav Stojkovic", category = "Connectivity", public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "Trace", return VisibilityPolicy.WHEN_SELECTED;
description = "Straight copper trace", zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW, }
autoEdit = false, keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB", transformer = SimpleComponentTransformer.class)
public class CopperTrace extends AbstractLeadedComponent<Void> { @Override
@EditableProperty(name = "Color")
private static final long serialVersionUID = 1L; public Color getLeadColor() {
return leadColor;
public static Size THICKNESS = new Size(1d, SizeUnit.mm); }
public static Color COLOR = Color.black;
@EditableProperty(name = "Width")
private Size thickness = THICKNESS; public Size getThickness() {
private PCBLayer layer = PCBLayer._1; return thickness;
}
public CopperTrace() {
super(); public void setThickness(Size thickness) {
this.leadColor = COLOR; this.thickness = thickness;
} }
@Override @EditableProperty
public void drawIcon(Graphics2D g2d, int width, int height) { public PCBLayer getLayer() {
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(3)); if (layer == null) {
g2d.setColor(COLOR); layer = PCBLayer._1;
g2d.drawLine(1, height - 2, width - 2, 1); }
} return layer;
}
@Override
protected Color getLeadColorForPainting(ComponentState componentState) { public void setLayer(PCBLayer layer) {
return componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR this.layer = layer;
: getLeadColor(); }
}
@Override
@Override protected float getLeadThickness() {
public VisibilityPolicy getControlPointVisibilityPolicy(int index) { return (float) getThickness().convertToPixels();
return VisibilityPolicy.WHEN_SELECTED; }
}
@Override
@Override protected boolean shouldShadeLeads() {
@EditableProperty(name = "Color") return false;
public Color getLeadColor() { }
return leadColor;
} public Color getBodyColor() {
return super.getBodyColor();
@EditableProperty(name = "Width") }
public Size getThickness() {
return thickness; @Override
} public Color getBorderColor() {
return super.getBorderColor();
public void setThickness(Size thickness) { }
this.thickness = thickness;
} @Override
public Byte getAlpha() {
@EditableProperty return super.getAlpha();
public PCBLayer getLayer() { }
if (layer == null) {
layer = PCBLayer._1; @Override
} public Size getLength() {
return layer; return super.getLength();
} }
public void setLayer(PCBLayer layer) { @Override
this.layer = layer; public Size getWidth() {
} return super.getWidth();
}
@Override
protected float getLeadThickness() { @Override
return (float) getThickness().convertToPixels(); public Void getValue() {
} return null;
}
@Override
protected boolean shouldShadeLeads() { @Override
return false; public void setValue(Void value) {}
}
@Override
public Color getBodyColor() { protected Shape getBodyShape() {
return super.getBodyColor(); return null;
} }
@Override @Override
public Color getBorderColor() { protected Size getDefaultWidth() {
return super.getBorderColor(); return null;
} }
@Override @Override
public Byte getAlpha() { protected Size getDefaultLength() {
return super.getAlpha(); return null;
} }
@Override @Override
public Size getLength() { protected boolean IsCopperArea() {
return super.getLength(); return true;
} }
}
@Override
public Size getWidth() {
return super.getWidth();
}
@Override
public Void getValue() {
return null;
}
@Override
public void setValue(Void value) {}
@Override
protected Shape getBodyShape() {
return null;
}
@Override
protected Size getDefaultWidth() {
return null;
}
@Override
protected Size getDefaultLength() {
return null;
}
}
@@ -66,8 +66,10 @@ public class Eyelet extends AbstractComponent<String> {
} }
int diameter = getClosestOdd((int) size.convertToPixels()); int diameter = getClosestOdd((int) size.convertToPixels());
int holeDiameter = getClosestOdd((int) holeSize.convertToPixels()); int holeDiameter = getClosestOdd((int) holeSize.convertToPixels());
g2d.setColor(color); g2d.setColor(color);
g2d.fillOval(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter); drawingObserver.startTrackingContinuityArea(true);
g2d.fillOval(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter);
drawingObserver.stopTrackingContinuityArea();
g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR
: color.darker()); : color.darker());
g2d.drawOval(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter); g2d.drawOval(point.x - diameter / 2, point.y - diameter / 2, diameter, diameter);
Binary file not shown.
Binary file not shown.
@@ -102,7 +102,7 @@ public class ConfigPlugin implements IPlugIn {
.createConfigAction(plugInPort, "Sticky Points", IPlugInPort.STICKY_POINTS_KEY, true), CONFIG_MENU); .createConfigAction(plugInPort, "Sticky Points", IPlugInPort.STICKY_POINTS_KEY, true), CONFIG_MENU);
swingUI.injectMenuAction( swingUI.injectMenuAction(
ActionFactory.getInstance() ActionFactory.getInstance()
.createConfigAction(plugInPort, "Highlighted Connected Areas", IPlugInPort.HIGHLIGHT_CONTINUITY_AREA, false), CONFIG_MENU); .createConfigAction(plugInPort, "Highlight Connected Areas", IPlugInPort.HIGHLIGHT_CONTINUITY_AREA, false), CONFIG_MENU);
File themeDir = new File("themes"); File themeDir = new File("themes");
if (themeDir.exists()) { if (themeDir.exists()) {