From e1c30b93ec3c012feef98927786fde679b51b24e Mon Sep 17 00:00:00 2001 From: Branislav Stojkovic Date: Tue, 18 Dec 2018 00:20:33 +0100 Subject: [PATCH] added dashed/dotted lines added 5 and 7-point curves --- .../src/org/diylc/common/LineStyle.java | 32 + .../src/org/diylc/common/ObjectCache.java | 110 ++- .../components/AbstractCurvedComponent.java | 587 ++++++----- .../components/AbstractLeadedComponent.java | 909 +++++++++--------- .../src/org/diylc/presenter/G2DWrapper.java | 13 +- diylc/diylc-library/lib/diylc-core.jar | Bin 245424 -> 248206 bytes .../diylc/components/boards/EyeletBoard.java | 2 +- .../components/connectivity/CurvedTrace.java | 208 ++-- .../components/connectivity/HookupWire.java | 194 ++-- .../diylc/components/connectivity/Jumper.java | 17 +- .../diylc/components/connectivity/Line.java | 35 +- diylc/diylc-swing/build.xml | 2 +- diylc/diylc-swing/lib/diylc-core.jar | Bin 245424 -> 248206 bytes diylc/diylc-swing/library/main.jar | Bin 431110 -> 433362 bytes diylc/diylc-swing/update.xml | 12 +- 15 files changed, 1150 insertions(+), 971 deletions(-) create mode 100644 diylc/diylc-core/src/org/diylc/common/LineStyle.java diff --git a/diylc/diylc-core/src/org/diylc/common/LineStyle.java b/diylc/diylc-core/src/org/diylc/common/LineStyle.java new file mode 100644 index 00000000..ae19e84e --- /dev/null +++ b/diylc/diylc-core/src/org/diylc/common/LineStyle.java @@ -0,0 +1,32 @@ +/* + + 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 . + +*/ +package org.diylc.common; + +public enum LineStyle { + + SOLID, DASHED, DOTTED; + + @Override + public String toString() { + return name().substring(0, 1) + name().substring(1).toLowerCase(); + } +} diff --git a/diylc/diylc-core/src/org/diylc/common/ObjectCache.java b/diylc/diylc-core/src/org/diylc/common/ObjectCache.java index 6ea25d57..f6a67504 100644 --- a/diylc/diylc-core/src/org/diylc/common/ObjectCache.java +++ b/diylc/diylc-core/src/org/diylc/common/ObjectCache.java @@ -1,58 +1,66 @@ /* + * + * 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 + * . + */ +package org.diylc.common; - DIY Layout Creator (DIYLC). - Copyright (c) 2009-2018 held jointly by the individual authors. +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Stroke; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; - This file is part of DIYLC. +/** + * Repository for object that may be reused, such as {@link Stroke} or {@link AlphaComposite}. + * + * @author Branislav Stojkovic + */ +public class ObjectCache { - 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. + private static ObjectCache instance; - 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. + public static ObjectCache getInstance() { + if (instance == null) { + instance = new ObjectCache(); + } + return instance; + } - You should have received a copy of the GNU General Public License - along with DIYLC. If not, see . + private ObjectCache() {} -*/ -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 basicStrokeMap = new HashMap(); - - public Stroke fetchBasicStroke(float 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; - } -} + private Map basicStrokeMap = new HashMap(); + private Map dashStrokeMap = new HashMap(); + + public Stroke fetchBasicStroke(float 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; + } + + public Stroke fetchStroke(float width, float[] dash, float phase) { + String key = width + "|" + Arrays.toString(dash) + "|" + phase; + if (dashStrokeMap.containsKey(key)) { + return dashStrokeMap.get(key); + } + Stroke stroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0, dash, phase); + dashStrokeMap.put(key, stroke); + return stroke; + } +} diff --git a/diylc/diylc-core/src/org/diylc/components/AbstractCurvedComponent.java b/diylc/diylc-core/src/org/diylc/components/AbstractCurvedComponent.java index 1d5b040f..58c27a0c 100644 --- a/diylc/diylc-core/src/org/diylc/components/AbstractCurvedComponent.java +++ b/diylc/diylc-core/src/org/diylc/components/AbstractCurvedComponent.java @@ -1,262 +1,339 @@ /* + * + * 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 + * . + */ +package org.diylc.components; - DIY Layout Creator (DIYLC). - Copyright (c) 2009-2018 held jointly by the individual authors. +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 java.awt.geom.Path2D; - This file is part of DIYLC. +import org.diylc.common.LineStyle; +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; - 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. +public abstract class AbstractCurvedComponent extends AbstractTransparentComponent { - 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. + private static final long serialVersionUID = 1L; - You should have received a copy of the GNU General Public License - along with DIYLC. If not, see . + public static Color GUIDELINE_COLOR = Color.blue; + public static Size DEFAULT_SIZE = new Size(1d, SizeUnit.in); -*/ -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 extends AbstractTransparentComponent { - - 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, IDrawingObserver drawingObserver); - - /** - * @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, drawingObserver); - 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(name="Color") - public Color getLeadColor() { - return color; - } - - public void setLeadColor(Color color) { - this.color = color; - } - - enum PointCount { - TWO, THREE, FOUR; - - @Override - public String toString() { - return name().substring(0, 1) + name().substring(1).toLowerCase(); - } - } -} + // for backward compatibility + protected Point[] controlPoints = null; + + protected Point[] controlPoints2 = 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; + protected LineStyle style = LineStyle.SOLID; + protected Boolean smooth = true; + + private int lastUpdatePointIndex = -1; + + /** + * Draws the specified curve onto graphics. + * + * @param curve + * @param g2d + * @param componentState + * @param theme + */ + protected abstract void drawCurve(Path2D curve, Graphics2D g2d, ComponentState componentState, + IDrawingObserver drawingObserver); + + /** + * @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; + } + + Point[] p = getControlPoints(); + + // smoothen the curve if needed + if (getSmooth() && lastUpdatePointIndex >= 0) { + if (getPointCount() == PointCount.FIVE && (lastUpdatePointIndex == 1 || lastUpdatePointIndex == 2)) { + p[3] = findThirdPoint(p[2], p[1]); + } + if (getPointCount() == PointCount.FIVE && lastUpdatePointIndex == 3) { + p[1] = findThirdPoint(p[2], p[3]); + } + if (getPointCount() == PointCount.SEVEN && (lastUpdatePointIndex == 2 || lastUpdatePointIndex == 3)) { + p[4] = findThirdPoint(p[3], p[2]); + } + if (getPointCount() == PointCount.SEVEN && lastUpdatePointIndex == 4) { + p[2] = findThirdPoint(p[3], p[4]); + } + lastUpdatePointIndex = -1; + } + + if (componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING) { + // Do not track guidelines. + drawingObserver.stopTracking(); + g2d.setStroke(Constants.DASHED_STROKE); + g2d.setColor(GUIDELINE_COLOR); + for (int i = 0; i < p.length - 1; i++) { + g2d.drawLine(p[i].x, p[i].y, p[i + 1].x, p[i + 1].y); + } + drawingObserver.startTracking(); + } + + Path2D path = new Path2D.Double(); + path.moveTo(p[0].x, p[0].y); + if (getPointCount() == PointCount.TWO) { + path.lineTo(p[1].x, p[1].y); + } else if (getPointCount() == PointCount.THREE) { + path.quadTo(p[1].x, p[1].y, p[2].x, p[2].y); + } else if (getPointCount() == PointCount.FOUR) { + path.curveTo(p[1].x, p[1].y, p[2].x, p[2].y, p[3].x, p[3].y); + } else if (getPointCount() == PointCount.FIVE) { + path.quadTo(p[1].x, p[1].y, p[2].x, p[2].y); + path.quadTo(p[3].x, p[3].y, p[4].x, p[4].y); + } else if (getPointCount() == PointCount.SEVEN) { + path.curveTo(p[1].x, p[1].y, p[2].x, p[2].y, p[3].x, p[3].y); + path.curveTo(p[4].x, p[4].y, p[5].x, p[5].y, p[6].x, p[6].y); + } + + Composite oldComposite = g2d.getComposite(); + if (alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); + } + + drawCurve(path, g2d, componentState, drawingObserver); + + g2d.setComposite(oldComposite); + } + + @EditableProperty(name = "Point Count") + public PointCount getPointCount() { + if (pointCount == null) { + pointCount = PointCount.FOUR; + } + return pointCount; + } + + protected Point[] getControlPoints() { + if (this.controlPoints != null) { + // ensure backward compatibility by copying points from the old structure to the new one + switch (getPointCount()) { + case TWO: + this.controlPoints2 = new Point[2]; + this.controlPoints2[0] = this.controlPoints[0]; + this.controlPoints2[1] = this.controlPoints[3]; + break; + case THREE: + this.controlPoints2 = new Point[3]; + this.controlPoints2[0] = this.controlPoints[0]; + this.controlPoints2[1] = this.controlPoints[1]; + this.controlPoints2[2] = this.controlPoints[3]; + break; + case FOUR: + this.controlPoints2 = new Point[4]; + this.controlPoints2[0] = this.controlPoints[0]; + this.controlPoints2[1] = this.controlPoints[1]; + this.controlPoints2[2] = this.controlPoints[2]; + this.controlPoints2[3] = this.controlPoints[3]; + break; + default: // shouldn't happen + this.controlPoints2 = this.controlPoints; + } + // we don't need old points anymore + this.controlPoints = null; + } + return this.controlPoints2; + } + + public void setPointCount(PointCount pointCount) { + Point[] p = getControlPoints(); + Point[] newPoints = new Point[pointCount.count]; + newPoints[0] = p[0]; + newPoints[pointCount.count - 1] = p[p.length - 1]; + + if (pointCount == PointCount.THREE) { + newPoints[1] = + new Point((newPoints[pointCount.count - 1].x + newPoints[0].x) / 2, + (newPoints[pointCount.count - 1].y + newPoints[0].y) / 2); + } else if (pointCount == PointCount.FOUR) { + newPoints[1] = + new Point((newPoints[pointCount.count - 1].x + newPoints[0].x) / 2, + (newPoints[pointCount.count - 1].y + newPoints[0].y) / 2); + newPoints[2] = + new Point((newPoints[pointCount.count - 1].x + newPoints[0].x) / 2, + (newPoints[pointCount.count - 1].y + newPoints[0].y) / 2); + } else if (pointCount == PointCount.FIVE) { + newPoints[2] = + new Point((newPoints[pointCount.count - 1].x + newPoints[0].x) / 2, + (newPoints[pointCount.count - 1].y + newPoints[0].y) / 2); + newPoints[1] = new Point((newPoints[2].x + newPoints[0].x) / 2, (newPoints[2].y + newPoints[0].y) / 2); + newPoints[3] = + new Point((newPoints[pointCount.count - 1].x + newPoints[2].x) / 2, + (newPoints[pointCount.count - 1].y + newPoints[2].y) / 2); + } else if (pointCount == PointCount.SEVEN) { + newPoints[3] = + new Point((newPoints[pointCount.count - 1].x + newPoints[0].x) / 2, + (newPoints[pointCount.count - 1].y + newPoints[0].y) / 2); + newPoints[2] = new Point((newPoints[3].x + newPoints[0].x) / 2, (newPoints[3].y + newPoints[0].y) / 2); + newPoints[1] = new Point((newPoints[3].x + newPoints[0].x) / 2, (newPoints[3].y + newPoints[0].y) / 2); + newPoints[4] = + new Point((newPoints[pointCount.count - 1].x + newPoints[3].x) / 2, + (newPoints[pointCount.count - 1].y + newPoints[3].y) / 2); + newPoints[5] = + new Point((newPoints[pointCount.count - 1].x + newPoints[3].x) / 2, + (newPoints[pointCount.count - 1].y + newPoints[3].y) / 2); + } + + this.controlPoints2 = newPoints; + this.pointCount = pointCount; + } + + @Override + public int getControlPointCount() { + return getControlPoints().length; + } + + @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) { + return index > 0 && index < getControlPointCount() - 1; + } + + @Override + public Point getControlPoint(int index) { + return getControlPoints()[index]; + } + + @Override + public void setControlPoint(Point point, int index) { + Point[] p = getControlPoints(); + p[index].setLocation(point); + this.lastUpdatePointIndex = index; + // if (getSmooth()) { + // if (getPointCount() == PointCount.FIVE && (index == 1 || index == 2)) { + // p[3] = findThirdPoint(p[2], p[1]); + // } + // if (getPointCount() == PointCount.FIVE && index == 3) { + // p[1] = findThirdPoint(p[2], p[3]); + // } + // if (getPointCount() == PointCount.SEVEN && (index == 2 || index == 3)) { + // p[4] = findThirdPoint(p[3], p[2]); + // } + // if (getPointCount() == PointCount.SEVEN && index == 4) { + // p[2] = findThirdPoint(p[3], p[4]); + // } + // } + } + + private Point findThirdPoint(Point p0, Point p) { + return new Point(2 * p0.x - p.x, 2 * p0.y - p.y); + } + + @EditableProperty(name = "Color") + public Color getLeadColor() { + return color; + } + + public void setLeadColor(Color color) { + this.color = color; + } + + @EditableProperty(name = "Style") + public LineStyle getStyle() { + if (style == null) + style = LineStyle.SOLID; + return style; + } + + public void setStyle(LineStyle style) { + this.style = style; + } + + @EditableProperty + public Boolean getSmooth() { + if (smooth == null) + this.smooth = true; + return this.smooth; + } + + public void setSmooth(Boolean smooth) { + this.smooth = smooth; + // make the current curve smooth if needed + // Point[] p = getControlPoints(); + // if (smooth) { + // if (getPointCount() == PointCount.FIVE) { + // p[3] = findThirdPoint(p[2], p[1]); + // } + // if (getPointCount() == PointCount.SEVEN) { + // p[4] = findThirdPoint(p[3], p[2]); + // } + // } + } + + enum PointCount { + TWO(2), THREE(3), FOUR(4), FIVE(5), SEVEN(7); + + private int count; + + private PointCount(int count) { + this.count = count; + } + + @Override + public String toString() { + return name().substring(0, 1) + name().substring(1).toLowerCase(); + } + } +} diff --git a/diylc/diylc-core/src/org/diylc/components/AbstractLeadedComponent.java b/diylc/diylc-core/src/org/diylc/components/AbstractLeadedComponent.java index f1202ae6..9dd8c536 100644 --- a/diylc/diylc-core/src/org/diylc/components/AbstractLeadedComponent.java +++ b/diylc/diylc-core/src/org/diylc/components/AbstractLeadedComponent.java @@ -1,26 +1,22 @@ /* + * + * 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 + * . + */ +package org.diylc.components; - 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 . - -*/ -package org.diylc.components; - import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; @@ -29,6 +25,7 @@ import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; +import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; @@ -36,6 +33,7 @@ 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.LineStyle; import org.diylc.common.ObjectCache; import org.diylc.core.ComponentState; import org.diylc.core.IDrawingObserver; @@ -46,450 +44,439 @@ 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 extends AbstractTransparentComponent { - - 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. - } + +/** + * 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 extends AbstractTransparentComponent { + + 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. + } } - + protected boolean IsCopperArea() { return false; - } - - @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, drawingObserver, IsCopperArea()); - } 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, drawingObserver, false); - } - } 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)); - // } - float leadThickness = getLeadThickness(); - double leadLength = (distance - calculatePinSpacing(shapeRect)) / 2; - - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness)); - Color leadColor = shouldShadeLeads() ? - getLeadColorForPainting(componentState).darker() : - getLeadColorForPainting(componentState); - g2d.setColor(leadColor); - drawLeads(g2d, theta, leadLength); - - if (shouldShadeLeads()) { - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2)); - leadColor = getLeadColorForPainting(componentState); - g2d.setColor(leadColor); - drawLeads(g2d, theta, 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) { - 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(project.getFont()); - 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) textRect.getWidth()); - // Adjust label angle if needed to make sure that it's readable. - if ((theta >= Math.PI / 2 && theta <= Math.PI) || (theta < -Math.PI / 2 && theta > -Math.PI)) { - g2d.rotate(Math.PI, length / 2, width / 2); - offset = -offset; - } - g2d.drawString(label, (int) (length - textRect.getWidth()) / 2 + offset, - calculateLabelYCoordinate(shapeRect, textRect, fontMetrics)); - g2d.setTransform(oldTransform); - } - } - - private void drawLeads(Graphics2D g2d, double theta, double leadLength) { - int endX = (int) (points[0].x + Math.cos(theta) * leadLength); - int endY = (int) (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) (points[1].y + Math.sin(theta - Math.PI) * leadLength); - g2d.drawLine(points[1].x, points[1].y, endX, endY); - } - + } + + @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, drawingObserver, IsCopperArea()); + } 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, drawingObserver, false); + } + } 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)); + // } + float leadThickness = getLeadThickness(); + double leadLength = (distance - calculatePinSpacing(shapeRect)) / 2; + + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness)); + Color leadColor = + shouldShadeLeads() ? getLeadColorForPainting(componentState).darker() + : getLeadColorForPainting(componentState); + g2d.setColor(leadColor); + drawLeads(g2d, theta, leadLength); + + if (shouldShadeLeads()) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(leadThickness - 2)); + leadColor = getLeadColorForPainting(componentState); + g2d.setColor(leadColor); + drawLeads(g2d, theta, 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) { + 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); + + // Draw label. + g2d.setFont(project.getFont()); + 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) textRect.getWidth()); + // Adjust label angle if needed to make sure that it's readable. + if ((theta >= Math.PI / 2 && theta <= Math.PI) || (theta < -Math.PI / 2 && theta > -Math.PI)) { + g2d.rotate(Math.PI, length / 2, width / 2); + offset = -offset; + } + g2d.drawString(label, (int) (length - textRect.getWidth()) / 2 + offset, + calculateLabelYCoordinate(shapeRect, textRect, fontMetrics)); + g2d.setTransform(oldTransform); + } + } + + private void drawLeads(Graphics2D g2d, double theta, double leadLength) { + int endX = (int) (points[0].x + Math.cos(theta) * leadLength); + int endY = (int) (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) (points[1].y + Math.sin(theta - Math.PI) * leadLength); + g2d.drawLine(points[1].x, points[1].y, endX, endY); + } + private void drawLead(Graphics2D g2d, ComponentState componentState, IDrawingObserver observer, boolean isCopperArea) { if (isCopperArea) - observer.startTrackingContinuityArea(true); - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(getLeadThickness())); - Color leadColor = - shouldShadeLeads() ? getLeadColorForPainting(componentState).darker() : getLeadColorForPainting(componentState); - g2d.setColor(leadColor); + observer.startTrackingContinuityArea(true); + + float thickness = getLeadThickness(); + Stroke stroke = null; + switch (getStyle()) { + case SOLID: + stroke = ObjectCache.getInstance().fetchBasicStroke(thickness); + break; + case DASHED: + stroke = + ObjectCache.getInstance().fetchStroke(thickness, new float[] {thickness * 2, thickness * 4}, thickness * 4); + break; + case DOTTED: + stroke = ObjectCache.getInstance().fetchStroke(thickness, new float[] {thickness / 4, thickness * 4}, 0); + break; + } + + g2d.setStroke(stroke); + 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 (isCopperArea) - observer.stopTrackingContinuityArea(); - - 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 true if shape rect should be used to center the component or false - * to place the component relative to length and width values. - */ - protected boolean useShapeRectAsPosition() { - return true; - } - - /** - * @return default lead thickness. Override this method to change it. - */ - protected float getLeadThickness() { - return getClosestOdd(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; - } -} + observer.stopTrackingContinuityArea(); + + if (shouldShadeLeads()) { + switch (getStyle()) { + case SOLID: + stroke = ObjectCache.getInstance().fetchBasicStroke(thickness - 2); + break; + case DASHED: + stroke = + ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness * 2, thickness * 4}, + thickness * 4); + break; + case DOTTED: + stroke = ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness / 4, thickness * 4}, 0); + break; + } + g2d.setStroke(stroke); + leadColor = getLeadColorForPainting(componentState); + g2d.setColor(leadColor); + g2d.drawLine(points[0].x, points[0].y, points[1].x, points[1].y); + } + } + + protected LineStyle getStyle() { + return LineStyle.SOLID; + } + + 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 true if shape rect should be used to center the component or false + * to place the component relative to length and width values. + */ + protected boolean useShapeRectAsPosition() { + return true; + } + + /** + * @return default lead thickness. Override this method to change it. + */ + protected float getLeadThickness() { + return getClosestOdd(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; + } +} diff --git a/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java b/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java index a3c1515e..81e267c2 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java +++ b/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java @@ -200,8 +200,17 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver { if (!drawingComponent || !trackingAllowed || s.equals(lastShape)) { return; } - - appendShape(getStroke().createStrokedShape(s)); + Stroke stroke = getStroke(); + if (stroke instanceof BasicStroke) { + BasicStroke bstroke = (BasicStroke) stroke; + if (bstroke.getLineWidth() < 3) { + appendShape(ObjectCache.getInstance().fetchBasicStroke(3).createStrokedShape(s)); + } else { + appendShape(getStroke().createStrokedShape(s)); + } + } else { + appendShape(getStroke().createStrokedShape(s)); + } } @Override diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index be9d92c82fa89cfbeffa3c469ffeb83e61f56eaa..3dfcd2f7b4806d79f1162e8c89684a2004cbc6f8 100644 GIT binary patch delta 24456 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 delta 21791 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 X>k=&{Bf3R}1HUb1gW+O1JTd$SzW^y^ diff --git a/diylc/diylc-library/src/org/diylc/components/boards/EyeletBoard.java b/diylc/diylc-library/src/org/diylc/components/boards/EyeletBoard.java index 6da1220e..a1a9fab0 100644 --- a/diylc/diylc-library/src/org/diylc/components/boards/EyeletBoard.java +++ b/diylc/diylc-library/src/org/diylc/components/boards/EyeletBoard.java @@ -48,7 +48,7 @@ public class EyeletBoard extends AbstractBoard { private static final long serialVersionUID = 1L; - public static Color BOARD_COLOR = Color.decode("#CCFFCC"); + public static Color BOARD_COLOR = Color.decode("#E3EAB4"); public static Color BORDER_COLOR = BOARD_COLOR.darker(); public static Color EYELET_COLOR = Color.decode("#C3E4ED"); diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/CurvedTrace.java b/diylc/diylc-library/src/org/diylc/components/connectivity/CurvedTrace.java index 9d5f8388..59419ed8 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/CurvedTrace.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/CurvedTrace.java @@ -1,112 +1,108 @@ /* + * + * 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 + * . + */ +package org.diylc.components.connectivity; - DIY Layout Creator (DIYLC). - Copyright (c) 2009-2018 held jointly by the individual authors. +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.Path2D; - 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 . - -*/ -package org.diylc.components.connectivity; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.CubicCurve2D; - -import org.diylc.common.SimpleComponentTransformer; -import org.diylc.common.ObjectCache; -import org.diylc.common.PCBLayer; -import org.diylc.components.AbstractCurvedComponent; -import org.diylc.core.ComponentState; -import org.diylc.core.IDIYComponent; +import org.diylc.common.ObjectCache; +import org.diylc.common.PCBLayer; +import org.diylc.common.SimpleComponentTransformer; +import org.diylc.components.AbstractCurvedComponent; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; -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; - -@ComponentDescriptor(name = "Curved Trace", author = "Branislav Stojkovic", category = "Connectivity", - instanceNamePrefix = "Trace", description = "Curved copper trace with two control points", - zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, - keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB", transformer = SimpleComponentTransformer.class) -public class CurvedTrace extends AbstractCurvedComponent { - - private static final long serialVersionUID = 1L; - - public static Color COLOR = Color.black; - public static Size SIZE = new Size(1d, SizeUnit.mm); - - protected Size size = SIZE; - private PCBLayer layer = PCBLayer._1; - - @Override - protected Color getDefaultColor() { - return COLOR; - } - - @Override - protected void drawCurve(CubicCurve2D curve, Graphics2D g2d, ComponentState componentState, IDrawingObserver drawingObserver) { - float thickness = (float) size.convertToPixels(); - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness)); - Color curveColor = - componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR - : color; +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; + +@ComponentDescriptor(name = "Curved Trace", author = "Branislav Stojkovic", category = "Connectivity", + instanceNamePrefix = "Trace", description = "Curved copper trace with two control points", + zOrder = IDIYComponent.TRACE, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, + keywordPolicy = KeywordPolicy.SHOW_TAG, keywordTag = "PCB", transformer = SimpleComponentTransformer.class) +public class CurvedTrace extends AbstractCurvedComponent { + + private static final long serialVersionUID = 1L; + + public static Color COLOR = Color.black; + public static Size SIZE = new Size(1d, SizeUnit.mm); + + protected Size size = SIZE; + private PCBLayer layer = PCBLayer._1; + + @Override + protected Color getDefaultColor() { + return COLOR; + } + + @Override + protected void drawCurve(Path2D curve, Graphics2D g2d, ComponentState componentState, IDrawingObserver drawingObserver) { + float thickness = (float) size.convertToPixels(); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness)); + Color curveColor = + componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : color; g2d.setColor(curveColor); - drawingObserver.startTrackingContinuityArea(true); + drawingObserver.startTrackingContinuityArea(true); g2d.draw(curve); - drawingObserver.stopTrackingContinuityArea(); - } - - @EditableProperty(name = "Width") - public Size getThickness() { - return size; - } - - public void setThickness(Size size) { - this.size = size; - } - - @EditableProperty - public PCBLayer getLayer() { - if (layer == null) { - layer = PCBLayer._1; - } - return layer; - } - - public void setLayer(PCBLayer layer) { - this.layer = layer; - } - - @Override - public Void getValue() { - return null; - } - - @Override - public void setValue(Void value) {} - - @Override - public Byte getAlpha() { - return super.getAlpha(); - } - - @Override - public void setAlpha(Byte alpha) { - super.setAlpha(alpha); - } -} + drawingObserver.stopTrackingContinuityArea(); + } + + @EditableProperty(name = "Width") + public Size getThickness() { + return size; + } + + public void setThickness(Size size) { + this.size = size; + } + + @EditableProperty + public PCBLayer getLayer() { + if (layer == null) { + layer = PCBLayer._1; + } + return layer; + } + + public void setLayer(PCBLayer layer) { + this.layer = layer; + } + + @Override + public Void getValue() { + return null; + } + + @Override + public void setValue(Void value) {} + + @Override + public Byte getAlpha() { + return super.getAlpha(); + } + + @Override + public void setAlpha(Byte alpha) { + super.setAlpha(alpha); + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/HookupWire.java b/diylc/diylc-library/src/org/diylc/components/connectivity/HookupWire.java index b1d6dd9c..f5fa2d07 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/HookupWire.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/HookupWire.java @@ -1,90 +1,112 @@ /* + * + * 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 + * . + */ +package org.diylc.components.connectivity; - DIY Layout Creator (DIYLC). - Copyright (c) 2009-2018 held jointly by the individual authors. +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Stroke; +import java.awt.geom.Path2D; - 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 . - -*/ -package org.diylc.components.connectivity; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.geom.CubicCurve2D; - -import org.diylc.common.ObjectCache; -import org.diylc.common.SimpleComponentTransformer; -import org.diylc.components.AbstractCurvedComponent; -import org.diylc.core.ComponentState; -import org.diylc.core.IDIYComponent; +import org.diylc.common.ObjectCache; +import org.diylc.common.SimpleComponentTransformer; +import org.diylc.components.AbstractCurvedComponent; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; import org.diylc.core.IDrawingObserver; -import org.diylc.core.annotations.BomPolicy; -import org.diylc.core.annotations.ComponentDescriptor; -import org.diylc.core.annotations.EditableProperty; -import org.diylc.utils.Constants; - -@ComponentDescriptor(name = "Hookup Wire", author = "Branislav Stojkovic", category = "Connectivity", - instanceNamePrefix = "W", description = "Flexible wire with two control points", zOrder = IDIYComponent.COMPONENT, - flexibleZOrder = true, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, - transformer = SimpleComponentTransformer.class, continuity = true) -public class HookupWire extends AbstractCurvedComponent { - - private static final long serialVersionUID = 1L; - - public static Color COLOR = Color.green; - public static double INSULATION_THICKNESS_PCT = 0.3; - - protected AWG gauge = AWG._22; - - @Override - protected Color getDefaultColor() { - return COLOR; - } - - @Override - protected void drawCurve(CubicCurve2D curve, Graphics2D g2d, ComponentState componentState, IDrawingObserver drawingObserver) { - int thickness = - (int) (Math.pow(Math.E, -1.12436 - 0.11594 * gauge.getValue()) * Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT)); - Color curveColor = - componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR - : color.darker(); - g2d.setColor(curveColor); - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness)); - g2d.draw(curve); - if (componentState == ComponentState.NORMAL) { - g2d.setColor(color); - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(thickness - 2)); - g2d.draw(curve); - } - } - - @EditableProperty(name = "AWG") - public AWG getGauge() { - return gauge; - } - - public void setGauge(AWG gauge) { - this.gauge = gauge; - } - - @Override - public Void getValue() { - return null; - } - - @Override - public void setValue(Void value) {} -} +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.utils.Constants; + +@ComponentDescriptor(name = "Hookup Wire", author = "Branislav Stojkovic", category = "Connectivity", + instanceNamePrefix = "W", description = "Flexible wire with two control points", zOrder = IDIYComponent.COMPONENT, + flexibleZOrder = true, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, + transformer = SimpleComponentTransformer.class, continuity = true) +public class HookupWire extends AbstractCurvedComponent { + + private static final long serialVersionUID = 1L; + + public static Color COLOR = Color.green; + public static double INSULATION_THICKNESS_PCT = 0.3; + + protected AWG gauge = AWG._22; + + @Override + protected Color getDefaultColor() { + return COLOR; + } + + @Override + protected void drawCurve(Path2D curve, Graphics2D g2d, ComponentState componentState, IDrawingObserver drawingObserver) { + int thickness = + (int) (Math.pow(Math.E, -1.12436 - 0.11594 * gauge.getValue()) * Constants.PIXELS_PER_INCH * (1 + 2 * INSULATION_THICKNESS_PCT)); + Color curveColor = + componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : color.darker(); + g2d.setColor(curveColor); + Stroke stroke = null; + switch (getStyle()) { + case SOLID: + stroke = ObjectCache.getInstance().fetchBasicStroke(thickness); + break; + case DASHED: + stroke = + ObjectCache.getInstance().fetchStroke(thickness, new float[] {thickness * 2, thickness * 3}, thickness * 4); + break; + case DOTTED: + stroke = ObjectCache.getInstance().fetchStroke(thickness, new float[] {thickness / 4, thickness * 3}, 0); + break; + } + g2d.setStroke(stroke); + g2d.draw(curve); + if (componentState == ComponentState.NORMAL) { + g2d.setColor(color); + switch (getStyle()) { + case SOLID: + stroke = ObjectCache.getInstance().fetchBasicStroke(thickness - 2); + break; + case DASHED: + stroke = + ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness * 2, thickness * 3}, + thickness * 4); + break; + case DOTTED: + stroke = ObjectCache.getInstance().fetchStroke(thickness - 2, new float[] {thickness / 4, thickness * 3}, 0); + } + g2d.setStroke(stroke); + g2d.draw(curve); + } + } + + @EditableProperty(name = "AWG") + public AWG getGauge() { + return gauge; + } + + public void setGauge(AWG gauge) { + this.gauge = gauge; + } + + @Override + public Void getValue() { + return null; + } + + @Override + public void setValue(Void value) {} +} diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/Jumper.java b/diylc/diylc-library/src/org/diylc/components/connectivity/Jumper.java index 95670911..c2c6b64d 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/Jumper.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/Jumper.java @@ -24,8 +24,9 @@ package org.diylc.components.connectivity; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Shape; - + import org.diylc.common.Display; +import org.diylc.common.LineStyle; import org.diylc.common.ObjectCache; import org.diylc.common.SimpleComponentTransformer; import org.diylc.components.AbstractLeadedComponent; @@ -48,7 +49,8 @@ public class Jumper extends AbstractLeadedComponent { public static Color COLOR = Color.blue; @Deprecated - private Color color; + private Color color; + protected LineStyle style = LineStyle.SOLID; public Jumper() { super(); @@ -78,6 +80,17 @@ public class Jumper extends AbstractLeadedComponent { this.leadColor = color; } return super.getLeadColor(); + } + + @EditableProperty(name = "Style") + public LineStyle getStyle() { + if (style == null) + style = LineStyle.SOLID; + return style; + } + + public void setStyle(LineStyle style) { + this.style = style; } public Color getBodyColor() { diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/Line.java b/diylc/diylc-library/src/org/diylc/components/connectivity/Line.java index 2d8427fc..0fc799a2 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/Line.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/Line.java @@ -24,8 +24,10 @@ package org.diylc.components.connectivity; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Shape; - +import java.awt.Stroke; + import org.diylc.common.Display; +import org.diylc.common.LineStyle; import org.diylc.common.ObjectCache; import org.diylc.common.SimpleComponentTransformer; import org.diylc.components.AbstractLeadedComponent; @@ -49,7 +51,8 @@ public class Line extends AbstractLeadedComponent { public static Color COLOR = Color.black; - private Color color = COLOR; + private Color color = COLOR; + protected LineStyle style = LineStyle.SOLID; @Override public void drawIcon(Graphics2D g2d, int width, int height) { @@ -60,8 +63,21 @@ public class Line extends AbstractLeadedComponent { @Override public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, - IDrawingObserver drawingObserver) { - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); + IDrawingObserver drawingObserver) { + float thickness = 1f; + Stroke stroke = null; + switch (getStyle()) { + case SOLID: + stroke = ObjectCache.getInstance().fetchBasicStroke(thickness); + break; + case DASHED: + stroke = ObjectCache.getInstance().fetchStroke(thickness, new float[] {thickness * 2}, thickness * 4); + break; + case DOTTED: + stroke = ObjectCache.getInstance().fetchStroke(thickness, new float[] {thickness / 4, thickness * 3}, 0); + break; + } + g2d.setStroke(stroke); g2d.setColor(color); g2d.drawLine(getControlPoint(0).x, getControlPoint(0).y, getControlPoint(1).x, getControlPoint(1).y); } @@ -84,6 +100,17 @@ public class Line extends AbstractLeadedComponent { public void setColor(Color color) { this.color = color; + } + + @EditableProperty(name = "Style") + public LineStyle getStyle() { + if (style == null) + style = LineStyle.SOLID; + return style; + } + + public void setStyle(LineStyle style) { + this.style = style; } public Color getBodyColor() { diff --git a/diylc/diylc-swing/build.xml b/diylc/diylc-swing/build.xml index 0cf3f168..9c64b72c 100644 --- a/diylc/diylc-swing/build.xml +++ b/diylc/diylc-swing/build.xml @@ -7,7 +7,7 @@ - + diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index be9d92c82fa89cfbeffa3c469ffeb83e61f56eaa..3dfcd2f7b4806d79f1162e8c89684a2004cbc6f8 100644 GIT binary patch delta 24456 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 delta 21791 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 X>k=&{Bf3R}1HUb1gW+O1JTd$SzW^y^ diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index e970987c002b766fe9e7ae3601fc67c997ca0214..d65489150a25afda8632b48a51b1c55ac0cc918d 100644 GIT binary patch delta 20218 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 Nz>jMUz`=v{{{aw&Waa<> delta 17969 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 eG#EgW1;YijWn)f~zQB8d*Q5-t?<2BPHv diff --git a/diylc/diylc-swing/update.xml b/diylc/diylc-swing/update.xml index f0c793cc..99834eb1 100644 --- a/diylc/diylc-swing/update.xml +++ b/diylc/diylc-swing/update.xml @@ -1932,12 +1932,20 @@ 3 - 42 - 2 + 43 + 0 2018-12-17 00:00:00.000 CET + + NEW_FEATURE + Added "Dashed" and "Dotted" style to "Hookup Wire", "Jumper" and "Line" components + + + NEW_FEATURE + Added five and seven control point options to curved components for more flexibility (literally) + NEW_FEATURE Added "Turret Lug" component