diff --git a/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java b/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java index 6ed8628e..08fa9467 100644 --- a/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java +++ b/diylc/diylc-core/src/org/diylc/components/AbstractComponent.java @@ -62,7 +62,8 @@ public abstract class AbstractComponent implements IDIYComponent { public static Color LABEL_COLOR = Color.black; public static Color LABEL_COLOR_SELECTED = Color.red; public static Font LABEL_FONT = new Font("Tahoma", Font.PLAIN, 14); - public static Color METAL_COLOR = Color.decode("#759DAF"); + public static Color METAL_COLOR = Color.decode("#759DAF"); + public static Color LIGHT_METAL_COLOR = Color.decode("#EEEEEE"); public static Color COPPER_COLOR = Color.decode("#DA8A67"); @EditableProperty(defaultable = false) diff --git a/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java b/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java index 81e267c2..09eaf0b2 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java +++ b/diylc/diylc-core/src/org/diylc/presenter/G2DWrapper.java @@ -403,11 +403,11 @@ class G2DWrapper extends Graphics2D implements IDrawingObserver { @Override public void setStroke(Stroke s) { - if (this.zoom > 1 && s.getClass() == BasicStroke.class) { + if (this.zoom > 1 && s instanceof BasicStroke) { BasicStroke bs = (BasicStroke) s; // make thin lines even thinner to compensate for zoom factor if (bs.getLineWidth() <= 2) - s = ObjectCache.getInstance().fetchBasicStroke((float) (bs.getLineWidth() / zoom)); + s = ObjectCache.getInstance().fetchStroke((float) (bs.getLineWidth() / zoom), bs.getDashArray(), bs.getDashPhase()); } canvasGraphics.setStroke(s); } diff --git a/diylc/diylc-core/src/org/diylc/utils/Constants.java b/diylc/diylc-core/src/org/diylc/utils/Constants.java index aebd686e..654fff3c 100644 --- a/diylc/diylc-core/src/org/diylc/utils/Constants.java +++ b/diylc/diylc-core/src/org/diylc/utils/Constants.java @@ -36,7 +36,7 @@ public class Constants { public static Color CANVAS_COLOR = Color.white; public static final Stroke DASHED_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10f, - new float[] {2.0f}, 0.0f); + new float[] {2.0f, 4.0f}, 0.0f); public static final Theme DEFAULT_THEME = new Theme("Light", Constants.CANVAS_COLOR, new Color(240, 240, 240), Color.black); diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index 0a8bc225..8df580fe 100644 Binary files a/diylc/diylc-library/lib/diylc-core.jar and b/diylc/diylc-library/lib/diylc-core.jar differ diff --git a/diylc/diylc-library/src/org/diylc/components/chassis/ChassisPanel.java b/diylc/diylc-library/src/org/diylc/components/chassis/ChassisPanel.java new file mode 100644 index 00000000..a43098c3 --- /dev/null +++ b/diylc/diylc-library/src/org/diylc/components/chassis/ChassisPanel.java @@ -0,0 +1,97 @@ +/* + + 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.chassis; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; + +import org.diylc.common.ObjectCache; +import org.diylc.common.SimpleComponentTransformer; +import org.diylc.components.shapes.AbstractShape; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; + +@ComponentDescriptor(name = "Chassis Panel", author = "Branislav Stojkovic", category = "Electromechanical", + instanceNamePrefix = "CP", description = "One side of a chassis, with or withouth rounded edges", + zOrder = IDIYComponent.CHASSIS, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false, + transformer = SimpleComponentTransformer.class) +public class ChassisPanel extends AbstractShape { + + private static final long serialVersionUID = 1L; + + protected Size edgeRadius = new Size(0d, SizeUnit.mm); + + public ChassisPanel() { + this.color = LIGHT_METAL_COLOR; + this.borderColor = LIGHT_METAL_COLOR.darker(); + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); + int radius = (int) edgeRadius.convertToPixels(); + if (componentState != ComponentState.DRAGGING) { + Composite oldComposite = g2d.getComposite(); + if (alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); + } + g2d.setColor(color); + g2d.fillRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius, + radius); + g2d.setComposite(oldComposite); + } + // Do not track any changes that follow because the whole rect has been + // tracked so far. + drawingObserver.stopTracking(); + g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : borderColor); + g2d.drawRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius, + radius); + } + + @EditableProperty(name = "Radius") + public Size getEdgeRadius() { + return edgeRadius; + } + + public void setEdgeRadius(Size edgeRadius) { + this.edgeRadius = edgeRadius; + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int factor = 32 / width; + g2d.setColor(LIGHT_METAL_COLOR); + g2d.fillRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor); + g2d.setColor(LIGHT_METAL_COLOR.darker()); + g2d.drawRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor); + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/chassis/EllipticalCutout.java b/diylc/diylc-library/src/org/diylc/components/chassis/EllipticalCutout.java new file mode 100644 index 00000000..d1521142 --- /dev/null +++ b/diylc/diylc-library/src/org/diylc/components/chassis/EllipticalCutout.java @@ -0,0 +1,75 @@ +/* + * + * 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.chassis; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; + +import org.diylc.common.ObjectCache; +import org.diylc.common.SimpleComponentTransformer; +import org.diylc.components.shapes.AbstractShape; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; + +@ComponentDescriptor(name = "Elliptical Cutout", author = "Branislav Stojkovic", category = "Electromechanical", + instanceNamePrefix = "ELC", description = "Elliptical chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1, + bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class) +public class EllipticalCutout extends AbstractShape { + + private static final long serialVersionUID = 1L; + + public EllipticalCutout() { + this.borderColor = LIGHT_METAL_COLOR.darker(); + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); + + if (componentState != ComponentState.DRAGGING) { + Composite oldComposite = g2d.getComposite(); + if (alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); + } + g2d.setColor(color); + g2d.fillOval(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); + g2d.setComposite(oldComposite); + } + // Do not track any changes that follow because the whole oval has been + // tracked so far. + drawingObserver.stopTracking(); + g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : borderColor); + g2d.drawOval(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y); + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int factor = 32 / width; + g2d.setColor(COLOR); + g2d.fillOval(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor); + g2d.setColor(LIGHT_METAL_COLOR.darker()); + g2d.drawOval(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor); + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/chassis/PolygonalCutout.java b/diylc/diylc-library/src/org/diylc/components/chassis/PolygonalCutout.java new file mode 100644 index 00000000..23dc1164 --- /dev/null +++ b/diylc/diylc-library/src/org/diylc/components/chassis/PolygonalCutout.java @@ -0,0 +1,125 @@ +/* + * + * 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.chassis; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Point; +import java.util.Arrays; + +import org.diylc.common.ObjectCache; +import org.diylc.common.SimpleComponentTransformer; +import org.diylc.components.shapes.AbstractShape; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; + +@ComponentDescriptor(name = "Polygonal Cutout", author = "Branislav Stojkovic", category = "Electromechanical", + instanceNamePrefix = "POLYC", description = "Polygonal chassis cutout", zOrder = IDIYComponent.CHASSIS + 0.1, + bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, transformer = SimpleComponentTransformer.class) +public class PolygonalCutout extends AbstractShape { + + private static final long serialVersionUID = 1L; + + protected PointCount pointCount = PointCount._4; + + public PolygonalCutout() { + super(); + this.borderColor = LIGHT_METAL_COLOR.darker(); + this.controlPoints = + new Point[] {new Point(0, 0), new Point(0, (int) DEFAULT_HEIGHT.convertToPixels()), + new Point((int) DEFAULT_WIDTH.convertToPixels(), (int) DEFAULT_HEIGHT.convertToPixels()), + new Point((int) DEFAULT_WIDTH.convertToPixels(), 0)}; + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); + g2d.setColor(color); + int[] xPoints = new int[controlPoints.length]; + int[] yPoints = new int[controlPoints.length]; + for (int i = 0; i < controlPoints.length; i++) { + xPoints[i] = controlPoints[i].x; + yPoints[i] = controlPoints[i].y; + } + + Composite oldComposite = g2d.getComposite(); + if (this.alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance(3, 1.0F * this.alpha / MAX_ALPHA)); + } + g2d.fillPolygon(xPoints, yPoints, controlPoints.length); + g2d.setComposite(oldComposite); + + // Do not track any changes that follow because the whole board has been + // tracked so far. + drawingObserver.stopTracking(); + Color lineColor = + componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : borderColor; + g2d.setColor(lineColor); + g2d.drawPolygon(xPoints, yPoints, controlPoints.length); + } + + @EditableProperty(name = "Edges") + public PointCount getPointCount() { + return pointCount; + } + + public void setPointCount(PointCount pointCount) { + if (this.pointCount == pointCount) + return; + int oldPointCount = Integer.parseInt(this.pointCount.toString()); + int newPointCount = Integer.parseInt(pointCount.toString()); + this.controlPoints = Arrays.copyOf(this.controlPoints, newPointCount); + if (oldPointCount < newPointCount) { + this.controlPoints[newPointCount - 1] = this.controlPoints[oldPointCount - 1]; + for (int i = oldPointCount - 1; i < newPointCount - 1; i++) { + this.controlPoints[i] = + new Point((this.controlPoints[i - 1].x + this.controlPoints[newPointCount - 1].x) / 2, + (this.controlPoints[i - 1].y + this.controlPoints[newPointCount - 1].y) / 2); + } + } + this.pointCount = pointCount; + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int factor = 32 / width; + g2d.setColor(COLOR); + int[] x = {2 / factor, width - 2 / factor, width - 4 / factor, 3 / factor}; + int[] y = {4 / factor, 2 / factor, height - 5 / factor, height - 2 / factor}; + g2d.fillPolygon(x, y, 4); + g2d.setColor(LIGHT_METAL_COLOR.darker()); + g2d.drawPolygon(x, y, 4); + } + + public enum PointCount { + _3, _4, _5, _6, _7, _8; + + public String toString() { + return name().substring(1); + }; + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/chassis/RectangularCutout.java b/diylc/diylc-library/src/org/diylc/components/chassis/RectangularCutout.java new file mode 100644 index 00000000..310acfc1 --- /dev/null +++ b/diylc/diylc-library/src/org/diylc/components/chassis/RectangularCutout.java @@ -0,0 +1,92 @@ +/* + * + * 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.chassis; + +import java.awt.AlphaComposite; +import java.awt.Composite; +import java.awt.Graphics2D; + +import org.diylc.common.ObjectCache; +import org.diylc.common.SimpleComponentTransformer; +import org.diylc.components.shapes.AbstractShape; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; + +@ComponentDescriptor(name = "Rectangular Cutout", author = "Branislav Stojkovic", category = "Electromechanical", + instanceNamePrefix = "RECTC", description = "Rectangular chassis cutout, with or without rounded edges", + zOrder = IDIYComponent.CHASSIS + 0.1, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false, + transformer = SimpleComponentTransformer.class) +public class RectangularCutout extends AbstractShape { + + private static final long serialVersionUID = 1L; + + protected Size edgeRadius = new Size(0d, SizeUnit.mm); + + public RectangularCutout() { + this.borderColor = LIGHT_METAL_COLOR.darker(); + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke((int) borderThickness.convertToPixels())); + int radius = (int) edgeRadius.convertToPixels(); + if (componentState != ComponentState.DRAGGING) { + Composite oldComposite = g2d.getComposite(); + if (alpha < MAX_ALPHA) { + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA)); + } + g2d.setColor(color); + g2d.fillRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius, + radius); + g2d.setComposite(oldComposite); + } + // Do not track any changes that follow because the whole rect has been + // tracked so far. + drawingObserver.stopTracking(); + g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : borderColor); + g2d.drawRoundRect(firstPoint.x, firstPoint.y, secondPoint.x - firstPoint.x, secondPoint.y - firstPoint.y, radius, + radius); + } + + @EditableProperty(name = "Radius") + public Size getEdgeRadius() { + return edgeRadius; + } + + public void setEdgeRadius(Size edgeRadius) { + this.edgeRadius = edgeRadius; + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int factor = 32 / width; + g2d.setColor(COLOR); + g2d.fillRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor); + g2d.setColor(LIGHT_METAL_COLOR.darker()); + g2d.drawRect(2 / factor, 4 / factor, width - 4 / factor, height - 8 / factor); + } +} 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 0fc799a2..7765d3b6 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/Line.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/Line.java @@ -71,10 +71,10 @@ public class Line extends AbstractLeadedComponent { stroke = ObjectCache.getInstance().fetchBasicStroke(thickness); break; case DASHED: - stroke = ObjectCache.getInstance().fetchStroke(thickness, new float[] {thickness * 2}, thickness * 4); + 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 * 3}, 0); + stroke = ObjectCache.getInstance().fetchStroke(thickness, new float[] {thickness, thickness * 5}, 0); break; } g2d.setStroke(stroke); diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/Turret.java b/diylc/diylc-library/src/org/diylc/components/connectivity/Turret.java index d19b3287..e0416d91 100644 --- a/diylc/diylc-library/src/org/diylc/components/connectivity/Turret.java +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/Turret.java @@ -41,7 +41,7 @@ import org.diylc.core.measures.SizeUnit; import org.diylc.utils.Constants; @ComponentDescriptor(name = "Turret Lug", category = "Connectivity", author = "Branislav Stojkovic", - description = "Turret terminal lug", instanceNamePrefix = "Eyelet", stretchable = false, + description = "Turret terminal lug", instanceNamePrefix = "Turret", stretchable = false, zOrder = IDIYComponent.TRACE + 0.1, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false, keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, transformer = SimpleComponentTransformer.class) public class Turret extends AbstractComponent { diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index 0a8bc225..8df580fe 100644 Binary files a/diylc/diylc-swing/lib/diylc-core.jar and b/diylc/diylc-swing/lib/diylc-core.jar differ diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index d6548915..cf79fc80 100644 Binary files a/diylc/diylc-swing/library/main.jar and b/diylc/diylc-swing/library/main.jar differ diff --git a/diylc/diylc-swing/update.xml b/diylc/diylc-swing/update.xml index dcfd503d..fc1daf34 100644 --- a/diylc/diylc-swing/update.xml +++ b/diylc/diylc-swing/update.xml @@ -1959,13 +1959,21 @@ 44 0 - 2018-12-17 00:00:00.000 CET + 2018-12-18 00:00:00.000 CET + + NEW_FEATURE + Added few chassis-related components under "Electromechanical" category + IMPROVEMENT Change mouse cursor when in "Highlight Connected Areas" mode to avoid confusion + + BUG_FIX + Thin dashed and dotted lines turn to solid when zommed in + https://github.com/bancika/diy-layout-creator/releases