diff --git a/diylc/diylc-core/src/org/diylc/netlist/NetlistBuilder.java b/diylc/diylc-core/src/org/diylc/netlist/NetlistBuilder.java index 6acfa74e..a7818f55 100644 --- a/diylc/diylc-core/src/org/diylc/netlist/NetlistBuilder.java +++ b/diylc/diylc-core/src/org/diylc/netlist/NetlistBuilder.java @@ -22,7 +22,6 @@ import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; diff --git a/diylc/diylc-core/src/org/diylc/presenter/update.xml b/diylc/diylc-core/src/org/diylc/presenter/update.xml index a5668f5f..ee4719cb 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/update.xml +++ b/diylc/diylc-core/src/org/diylc/presenter/update.xml @@ -4194,6 +4194,10 @@ IMPROVEMENT Potentiometer bodies are no longer considered as conductive surfaces to avoid unwanted shorts + + IMPROVEMENT + Improved conductivity tracking of Terminal Strip + BUG_FIX Do not apply any user-default property values when creating a standard datasheet model (e.g. a capacitor) diff --git a/diylc/diylc-library/lib/diylc-core.jar b/diylc/diylc-library/lib/diylc-core.jar index 8cebd825..55f2232b 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/boards/TerminalStrip.java b/diylc/diylc-library/src/org/diylc/components/boards/TerminalStrip.java index 713a2814..8793416f 100644 --- a/diylc/diylc-library/src/org/diylc/components/boards/TerminalStrip.java +++ b/diylc/diylc-library/src/org/diylc/components/boards/TerminalStrip.java @@ -1,26 +1,23 @@ /* + * + * 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.boards; - 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.boards; - import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; @@ -49,399 +46,419 @@ import org.diylc.core.annotations.PositiveNonZeroMeasureValidator; import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; import org.diylc.utils.Constants; - -@ComponentDescriptor(name = "Terminal Strip", author = "Branislav Stojkovic", category = "Boards", - instanceNamePrefix = "TS", description = "Row of terminals for point-to-point construction", - zOrder = IDIYComponent.BOARD, keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, transformer = TerminalStripTransformer.class) -public class TerminalStrip extends AbstractTransparentComponent implements IContinuity { - - private static final long serialVersionUID = 1L; - - public static Color BOARD_COLOR = PHENOLIC_DARK_COLOR; - public static Color TERMINAL_COLOR = Color.lightGray; - public static Color TERMINAL_BORDER_COLOR = TERMINAL_COLOR.darker(); - public static int EDGE_RADIUS = 2; - public static Size HOLE_SIZE = new Size(0.06d, SizeUnit.in); - public static Size MOUNTING_HOLE_SIZE = new Size(0.07d, SizeUnit.in); - - private String value = ""; - private Orientation orientation = Orientation.DEFAULT; - private int terminalCount = 10; - private Size boardWidth = new Size(0.35d, SizeUnit.in); - private Size terminalSpacing = new Size(0.25d, SizeUnit.in); - private Size holeSpacing = new Size(0.5d, SizeUnit.in); - private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)}; + +@ComponentDescriptor(name = "Terminal Strip", author = "Branislav Stojkovic", category = "Boards", + instanceNamePrefix = "TS", description = "Row of terminals for point-to-point construction", + zOrder = IDIYComponent.BOARD, keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, + transformer = TerminalStripTransformer.class) +public class TerminalStrip extends AbstractTransparentComponent implements IContinuity { + + private static final long serialVersionUID = 1L; + + public static Color BOARD_COLOR = PHENOLIC_DARK_COLOR; + public static Color TERMINAL_COLOR = Color.lightGray; + public static Color TERMINAL_BORDER_COLOR = TERMINAL_COLOR.darker(); + public static int EDGE_RADIUS = 2; + public static Size HOLE_SIZE = new Size(0.06d, SizeUnit.in); + public static Size MOUNTING_HOLE_SIZE = new Size(0.07d, SizeUnit.in); + + private String value = ""; + private Orientation orientation = Orientation.DEFAULT; + private int terminalCount = 10; + private Size boardWidth = new Size(0.35d, SizeUnit.in); + private Size terminalSpacing = new Size(0.25d, SizeUnit.in); + private Size holeSpacing = new Size(0.5d, SizeUnit.in); + private Point2D[] controlPoints = new Point2D[] {new Point2D.Double(0, 0)}; private Color boardColor = BOARD_COLOR; @SuppressWarnings("unused") - @Deprecated - private transient Color borderColor; - private boolean centerHole = false; - - transient private Area[] body; - - public TerminalStrip() { - super(); - updateControlPoints(); - } - - @EditableProperty - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - @EditableProperty - public Orientation getOrientation() { - return orientation; - } - - public void setOrientation(Orientation orientation) { - this.orientation = orientation; - updateControlPoints(); - // Reset body shape. - body = null; - } - - @EditableProperty(name = "Terminals") - public int getTerminalCount() { - return terminalCount; - } - - public void setTerminalCount(int terminalCount) { - this.terminalCount = terminalCount; - updateControlPoints(); - // Reset body shape; - body = null; - } - - @EditableProperty(name = "Terminal Spacing", validatorClass = PositiveNonZeroMeasureValidator.class) - public Size getTerminalSpacing() { - return terminalSpacing; - } - - public void setTerminalSpacing(Size pinSpacing) { - this.terminalSpacing = pinSpacing; - updateControlPoints(); - // Reset body shape; - body = null; - } - - @EditableProperty(name = "Hole Spacing", validatorClass = PositiveNonZeroMeasureValidator.class) - public Size getHoleSpacing() { - return holeSpacing; - } - - public void setHoleSpacing(Size rowSpacing) { - this.holeSpacing = rowSpacing; - updateControlPoints(); - // Reset body shape; - body = null; - } - - @EditableProperty(name = "Center Terminal") - public boolean getCenterHole() { - return centerHole; - } - - public void setCenterHole(boolean centerHole) { - this.centerHole = centerHole; - updateControlPoints(); - // Reset body shape; - body = null; - } - - @EditableProperty(name = "Board Width", validatorClass = PositiveNonZeroMeasureValidator.class) - public Size getBoardWidth() { - return boardWidth; - } - - public void setBoardWidth(Size boardWidth) { - this.boardWidth = boardWidth; - // Reset body shape; - body = null; - } - - @Override - public int getControlPointCount() { - return controlPoints.length; - } - - @Override - public Point2D getControlPoint(int index) { - return controlPoints[index]; - } - - @Override - public boolean isControlPointSticky(int index) { - return true; - } - - @Override - public VisibilityPolicy getControlPointVisibilityPolicy(int index) { - return VisibilityPolicy.NEVER; - } - - @Override - public void setControlPoint(Point2D point, int index) { - controlPoints[index].setLocation(point); - body = null; - } - - private void updateControlPoints() { - Point2D firstPoint = controlPoints[0]; - controlPoints = new Point2D[getTerminalCount() * (getCenterHole() ? 3 : 2)]; - controlPoints[0] = firstPoint; - int pinSpacing = (int) this.terminalSpacing.convertToPixels(); - int rowSpacing = (int) this.holeSpacing.convertToPixels(); - // Update control points. - int dx1; - int dy1; - int dx2; - int dy2; - int cx; - int cy; - for (int i = 0; i < getTerminalCount(); i++) { - switch (orientation) { - case DEFAULT: - dx1 = 0; - dy1 = i * pinSpacing; - dx2 = rowSpacing; - dy2 = i * pinSpacing; - cx = rowSpacing / 2; - cy = i * pinSpacing; - break; - case _90: - dx1 = -i * pinSpacing; - dy1 = 0; - dx2 = -i * pinSpacing; - dy2 = rowSpacing; - cx = -i * pinSpacing; - cy = rowSpacing / 2; - break; - case _180: - dx1 = 0; - dy1 = -i * pinSpacing; - dx2 = -rowSpacing; - dy2 = -i * pinSpacing; - cx = -rowSpacing / 2; - cy = -i * pinSpacing; - break; - case _270: - dx1 = i * pinSpacing; - dy1 = 0; - dx2 = i * pinSpacing; - dy2 = -rowSpacing; - cx = i * pinSpacing; - cy = -rowSpacing / 2; - break; - default: - throw new RuntimeException("Unexpected orientation: " + orientation); - } - controlPoints[i] = new Point2D.Double(firstPoint.getX() + dx1, firstPoint.getY() + dy1); - controlPoints[i + getTerminalCount()] = new Point2D.Double(firstPoint.getX() + dx2, firstPoint.getY() + dy2); - if (centerHole) - controlPoints[i + 2 * getTerminalCount()] = new Point2D.Double(firstPoint.getX() + cx, firstPoint.getY() + cy); - } - } - - public Area[] getBody() { - if (body == null) { - body = new Area[1 + getTerminalCount()]; - double x = controlPoints[0].getX(); - double y = controlPoints[0].getY(); - int width; - int height; - int holeSize = (int) HOLE_SIZE.convertToPixels(); - int terminalSpacing = (int) getTerminalSpacing().convertToPixels(); - int holeSpacing = (int) getHoleSpacing().convertToPixels(); - int boardWidth = (int) getBoardWidth().convertToPixels(); - int boardLength = (getTerminalCount() - 1) * terminalSpacing + 2 * boardWidth; - Area indentation = null; - - int mountingHoleSize = getClosestOdd(MOUNTING_HOLE_SIZE.convertToPixels()); - switch (orientation) { - case DEFAULT: - width = boardWidth; - height = boardLength; - x += holeSpacing / 2 - boardWidth / 2; - y -= boardWidth; - indentation = - new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize / 2, y + boardWidth / 2 - - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize)); - indentation.add(new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize / 2, y + boardLength - - boardWidth / 2, mountingHoleSize, mountingHoleSize))); - break; - case _90: - width = boardLength; - height = boardWidth; - x += boardWidth - boardLength; - y += holeSpacing / 2 - boardWidth / 2; - indentation = - new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize, y + boardWidth / 2 - - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize)); - indentation.add(new Area(new Ellipse2D.Double(x + boardLength - boardWidth / 2, y + boardWidth / 2 - - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize))); - break; - case _180: - width = boardWidth; - height = boardLength; - x -= holeSpacing / 2 + boardWidth / 2; - y += boardWidth - boardLength; - indentation = - new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize / 2, y + boardWidth / 2 - - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize)); - indentation.add(new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize / 2, y + boardLength - - boardWidth / 2, mountingHoleSize, mountingHoleSize))); - break; - case _270: - width = boardLength; - height = boardWidth; - x -= boardWidth; - y -= holeSpacing / 2 + boardWidth / 2; - indentation = - new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize, y + boardWidth / 2 - - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize)); - indentation.add(new Area(new Ellipse2D.Double(x + boardLength - boardWidth / 2, y + boardWidth / 2 - - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize))); - break; - default: - throw new RuntimeException("Unexpected orientation: " + orientation); - } - Area bodyArea = new Area(new RoundRectangle2D.Double(x, y, width, height, EDGE_RADIUS, EDGE_RADIUS)); - bodyArea.subtract(indentation); - body[0] = bodyArea; - - - for (int i = 0; i < getTerminalCount(); i++) { - Point2D p1 = getControlPoint(i); - Point2D p2 = getControlPoint(i + getTerminalCount()); - if (p2.getX() < p1.getX() || p2.getY() < p1.getY()) { - Point2D p = p1; - p1 = p2; - p2 = p; - } - - Area terminal = - new Area(new RoundRectangle2D.Double(p1.getX() - holeSize, p1.getY() - holeSize, p2.getX() - p1.getX() + holeSize * 2, p2.getY() - - p1.getY() + holeSize * 2, holeSize, holeSize)); - - terminal.subtract(new Area(new Ellipse2D.Double(p1.getX() - holeSize / 2, p1.getY() - holeSize / 2, holeSize, holeSize))); - terminal.subtract(new Area(new Ellipse2D.Double(p2.getX() - holeSize / 2, p2.getY() - holeSize / 2, holeSize, holeSize))); - if (centerHole) { - Point2D p3 = getControlPoint(i + 2 * getTerminalCount()); - Area centerHole = - new Area(new Ellipse2D.Double(p3.getX() - holeSize / 2, p3.getY() - holeSize / 2, holeSize, holeSize)); - terminal.subtract(centerHole); - bodyArea.subtract(centerHole); - } - - body[1 + i] = terminal; - } - - } - return body; - } - - @Override - public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, - IDrawingObserver drawingObserver) { - if (checkPointsClipped(g2d.getClip())) { - return; - } - Area[] body = getBody(); - Area mainArea = getBody()[0]; - - 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 : getBoardColor()); - g2d.fill(mainArea); - - 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 - : getBoardColor().darker(); - } - g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); - - g2d.setColor(finalBorderColor); - g2d.draw(mainArea); - - g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : TERMINAL_COLOR); - drawingObserver.startTrackingContinuityArea(true); - for (int i = 1; i < body.length; i++) - g2d.fill(body[i]); - drawingObserver.stopTrackingContinuityArea(); - - Color finalTerminalBorderColor; - if (outlineMode) { - Theme theme = - (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME); - finalTerminalBorderColor = - componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR - : theme.getOutlineColor(); - } else { - finalTerminalBorderColor = - componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR - : TERMINAL_BORDER_COLOR; - } - - g2d.setColor(finalTerminalBorderColor); - for (int i = 1; i < body.length; i++) - g2d.draw(body[i]); - - g2d.setComposite(oldComposite); - } - - @Override - public void drawIcon(Graphics2D g2d, int width, int height) { - int radius = 6 * width / 32; - int holeSize = 3 * width / 32; - g2d.setColor(BOARD_COLOR); - g2d.fillRect(width / 4, 1, width / 2, height - 4); - g2d.setColor(BOARD_COLOR.darker()); - g2d.drawRect(width / 4, 1, width / 2, height - 4); - int terminalSize = getClosestOdd(height / 5); - Area terminal = - new Area(new RoundRectangle2D.Double(2 * width / 32, height / 5, width - 4 * width / 32, terminalSize, radius, - radius)); - terminal.subtract(new Area(new Ellipse2D.Double(2 * width / 32 + holeSize, height * 3 / 10 - holeSize / 2, holeSize, holeSize))); - terminal.subtract(new Area(new Ellipse2D.Double(width - 2 * width / 32 - holeSize * 2, height * 3 / 10 - holeSize / 2, holeSize, holeSize))); - - g2d.setColor(TERMINAL_COLOR); - g2d.fill(terminal); - g2d.setColor(TERMINAL_BORDER_COLOR); - g2d.draw(terminal); - g2d.translate(0, height * 2 / 5); - g2d.setColor(TERMINAL_COLOR); - g2d.fill(terminal); - g2d.setColor(TERMINAL_BORDER_COLOR); - g2d.draw(terminal); - } - - @EditableProperty(name = "Board") - public Color getBoardColor() { - if (boardColor == null) { - boardColor = BOARD_COLOR; - } - return boardColor; - } - - public void setBoardColor(Color bodyColor) { - this.boardColor = bodyColor; + @Deprecated + private transient Color borderColor; + private boolean centerHole = false; + + transient private Area[] body; + + public TerminalStrip() { + super(); + updateControlPoints(); } - + + @EditableProperty + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @EditableProperty + public Orientation getOrientation() { + return orientation; + } + + public void setOrientation(Orientation orientation) { + this.orientation = orientation; + updateControlPoints(); + // Reset body shape. + body = null; + } + + @EditableProperty(name = "Terminals") + public int getTerminalCount() { + return terminalCount; + } + + public void setTerminalCount(int terminalCount) { + this.terminalCount = terminalCount; + updateControlPoints(); + // Reset body shape; + body = null; + } + + @EditableProperty(name = "Terminal Spacing", + validatorClass = PositiveNonZeroMeasureValidator.class) + public Size getTerminalSpacing() { + return terminalSpacing; + } + + public void setTerminalSpacing(Size pinSpacing) { + this.terminalSpacing = pinSpacing; + updateControlPoints(); + // Reset body shape; + body = null; + } + + @EditableProperty(name = "Hole Spacing", validatorClass = PositiveNonZeroMeasureValidator.class) + public Size getHoleSpacing() { + return holeSpacing; + } + + public void setHoleSpacing(Size rowSpacing) { + this.holeSpacing = rowSpacing; + updateControlPoints(); + // Reset body shape; + body = null; + } + + @EditableProperty(name = "Center Terminal") + public boolean getCenterHole() { + return centerHole; + } + + public void setCenterHole(boolean centerHole) { + this.centerHole = centerHole; + updateControlPoints(); + // Reset body shape; + body = null; + } + + @EditableProperty(name = "Board Width", validatorClass = PositiveNonZeroMeasureValidator.class) + public Size getBoardWidth() { + return boardWidth; + } + + public void setBoardWidth(Size boardWidth) { + this.boardWidth = boardWidth; + // Reset body shape; + body = null; + } + + @Override + public int getControlPointCount() { + return controlPoints.length; + } + + @Override + public Point2D getControlPoint(int index) { + return controlPoints[index]; + } + + @Override + public boolean isControlPointSticky(int index) { + return true; + } + + @Override + public VisibilityPolicy getControlPointVisibilityPolicy(int index) { + return VisibilityPolicy.NEVER; + } + + @Override + public void setControlPoint(Point2D point, int index) { + controlPoints[index].setLocation(point); + body = null; + } + + private void updateControlPoints() { + Point2D firstPoint = controlPoints[0]; + controlPoints = new Point2D[getTerminalCount() * (getCenterHole() ? 3 : 2)]; + controlPoints[0] = firstPoint; + int pinSpacing = (int) this.terminalSpacing.convertToPixels(); + int rowSpacing = (int) this.holeSpacing.convertToPixels(); + // Update control points. + int dx1; + int dy1; + int dx2; + int dy2; + int cx; + int cy; + for (int i = 0; i < getTerminalCount(); i++) { + switch (orientation) { + case DEFAULT: + dx1 = 0; + dy1 = i * pinSpacing; + dx2 = rowSpacing; + dy2 = i * pinSpacing; + cx = rowSpacing / 2; + cy = i * pinSpacing; + break; + case _90: + dx1 = -i * pinSpacing; + dy1 = 0; + dx2 = -i * pinSpacing; + dy2 = rowSpacing; + cx = -i * pinSpacing; + cy = rowSpacing / 2; + break; + case _180: + dx1 = 0; + dy1 = -i * pinSpacing; + dx2 = -rowSpacing; + dy2 = -i * pinSpacing; + cx = -rowSpacing / 2; + cy = -i * pinSpacing; + break; + case _270: + dx1 = i * pinSpacing; + dy1 = 0; + dx2 = i * pinSpacing; + dy2 = -rowSpacing; + cx = i * pinSpacing; + cy = -rowSpacing / 2; + break; + default: + throw new RuntimeException("Unexpected orientation: " + orientation); + } + controlPoints[i] = new Point2D.Double(firstPoint.getX() + dx1, firstPoint.getY() + dy1); + controlPoints[i + getTerminalCount()] = + new Point2D.Double(firstPoint.getX() + dx2, firstPoint.getY() + dy2); + if (centerHole) + controlPoints[i + 2 * getTerminalCount()] = + new Point2D.Double(firstPoint.getX() + cx, firstPoint.getY() + cy); + } + } + + public Area[] getBody() { + if (body == null) { + body = new Area[1 + getTerminalCount() * 2]; + double x = controlPoints[0].getX(); + double y = controlPoints[0].getY(); + int width; + int height; + int holeSize = (int) HOLE_SIZE.convertToPixels(); + int terminalSpacing = (int) getTerminalSpacing().convertToPixels(); + int holeSpacing = (int) getHoleSpacing().convertToPixels(); + int boardWidth = (int) getBoardWidth().convertToPixels(); + int boardLength = (getTerminalCount() - 1) * terminalSpacing + 2 * boardWidth; + Area indentation = null; + + int mountingHoleSize = getClosestOdd(MOUNTING_HOLE_SIZE.convertToPixels()); + switch (orientation) { + case DEFAULT: + width = boardWidth; + height = boardLength; + x += holeSpacing / 2 - boardWidth / 2; + y -= boardWidth; + indentation = new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize / 2, + y + boardWidth / 2 - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize)); + indentation.add(new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize / 2, + y + boardLength - boardWidth / 2, mountingHoleSize, mountingHoleSize))); + break; + case _90: + width = boardLength; + height = boardWidth; + x += boardWidth - boardLength; + y += holeSpacing / 2 - boardWidth / 2; + indentation = new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize, + y + boardWidth / 2 - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize)); + indentation.add(new Area(new Ellipse2D.Double(x + boardLength - boardWidth / 2, + y + boardWidth / 2 - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize))); + break; + case _180: + width = boardWidth; + height = boardLength; + x -= holeSpacing / 2 + boardWidth / 2; + y += boardWidth - boardLength; + indentation = new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize / 2, + y + boardWidth / 2 - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize)); + indentation.add(new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize / 2, + y + boardLength - boardWidth / 2, mountingHoleSize, mountingHoleSize))); + break; + case _270: + width = boardLength; + height = boardWidth; + x -= boardWidth; + y -= holeSpacing / 2 + boardWidth / 2; + indentation = new Area(new Ellipse2D.Double(x + boardWidth / 2 - mountingHoleSize, + y + boardWidth / 2 - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize)); + indentation.add(new Area(new Ellipse2D.Double(x + boardLength - boardWidth / 2, + y + boardWidth / 2 - mountingHoleSize / 2, mountingHoleSize, mountingHoleSize))); + break; + default: + throw new RuntimeException("Unexpected orientation: " + orientation); + } + Area bodyArea = + new Area(new RoundRectangle2D.Double(x, y, width, height, EDGE_RADIUS, EDGE_RADIUS)); + bodyArea.subtract(indentation); + body[0] = bodyArea; + + + for (int i = 0; i < getTerminalCount(); i++) { + Point2D p1 = getControlPoint(i); + Point2D p2 = getControlPoint(i + getTerminalCount()); + if (p2.getX() < p1.getX() || p2.getY() < p1.getY()) { + Point2D p = p1; + p1 = p2; + p2 = p; + } + + Area terminal = new Area(new RoundRectangle2D.Double(p1.getX() - holeSize, + p1.getY() - holeSize, p2.getX() - p1.getX() + holeSize * 2, + p2.getY() - p1.getY() + holeSize * 2, holeSize, holeSize)); + + terminal.subtract(new Area(new Ellipse2D.Double(p1.getX() - holeSize / 2, + p1.getY() - holeSize / 2, holeSize, holeSize))); + terminal.subtract(new Area(new Ellipse2D.Double(p2.getX() - holeSize / 2, + p2.getY() - holeSize / 2, holeSize, holeSize))); + if (centerHole) { + Point2D p3 = getControlPoint(i + 2 * getTerminalCount()); + Area centerHole = new Area(new Ellipse2D.Double(p3.getX() - holeSize / 2, + p3.getY() - holeSize / 2, holeSize, holeSize)); + terminal.subtract(centerHole); + bodyArea.subtract(centerHole); + } + + body[1 + i] = terminal; + + body[1 + i + getTerminalCount()] = + new Area(new RoundRectangle2D.Double(p1.getX() - holeSize, p1.getY() - holeSize, + p2.getX() - p1.getX() + holeSize * 2, p2.getY() - p1.getY() + holeSize * 2, + holeSize, holeSize)); // save the terminal without holes for continuity tracking + } + + } + return body; + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, + Project project, IDrawingObserver drawingObserver) { + if (checkPointsClipped(g2d.getClip())) { + return; + } + Area[] body = getBody(); + Area mainArea = getBody()[0]; + + 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 : getBoardColor()); + g2d.fill(mainArea); + + 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 + : getBoardColor().darker(); + } + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); + + g2d.setColor(finalBorderColor); + g2d.draw(mainArea); + + + g2d.setColor(Constants.TRANSPARENT_COLOR); + drawingObserver.startTrackingContinuityArea(true); + for (int i = 0; i < getTerminalCount(); i++) + g2d.fill(body[i + getTerminalCount() + 1]); + drawingObserver.stopTrackingContinuityArea(); + + if (!outlineMode) { + g2d.setColor(TERMINAL_COLOR); + for (int i = 0; i < getTerminalCount(); i++) + g2d.fill(body[i + 1]); + } + + Color finalTerminalBorderColor; + if (outlineMode) { + Theme theme = (Theme) ConfigurationManager.getInstance().readObject(IPlugInPort.THEME_KEY, + Constants.DEFAULT_THEME); + finalTerminalBorderColor = + componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING + ? SELECTION_COLOR + : theme.getOutlineColor(); + } else { + finalTerminalBorderColor = + componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING + ? SELECTION_COLOR + : TERMINAL_BORDER_COLOR; + } + + g2d.setColor(finalTerminalBorderColor); + for (int i = 1; i < body.length; i++) + g2d.draw(body[i]); + + g2d.setComposite(oldComposite); + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int radius = 6 * width / 32; + int holeSize = 3 * width / 32; + g2d.setColor(BOARD_COLOR); + g2d.fillRect(width / 4, 1, width / 2, height - 4); + g2d.setColor(BOARD_COLOR.darker()); + g2d.drawRect(width / 4, 1, width / 2, height - 4); + int terminalSize = getClosestOdd(height / 5); + Area terminal = new Area(new RoundRectangle2D.Double(2 * width / 32, height / 5, + width - 4 * width / 32, terminalSize, radius, radius)); + terminal.subtract(new Area(new Ellipse2D.Double(2 * width / 32 + holeSize, + height * 3 / 10 - holeSize / 2, holeSize, holeSize))); + terminal.subtract(new Area(new Ellipse2D.Double(width - 2 * width / 32 - holeSize * 2, + height * 3 / 10 - holeSize / 2, holeSize, holeSize))); + + g2d.setColor(TERMINAL_COLOR); + g2d.fill(terminal); + g2d.setColor(TERMINAL_BORDER_COLOR); + g2d.draw(terminal); + g2d.translate(0, height * 2 / 5); + g2d.setColor(TERMINAL_COLOR); + g2d.fill(terminal); + g2d.setColor(TERMINAL_BORDER_COLOR); + g2d.draw(terminal); + } + + @EditableProperty(name = "Board") + public Color getBoardColor() { + if (boardColor == null) { + boardColor = BOARD_COLOR; + } + return boardColor; + } + + public void setBoardColor(Color bodyColor) { + this.boardColor = bodyColor; + } + @Override public String getControlPointNodeName(int index) { return "TerminalStrip" + index; @@ -451,9 +468,9 @@ public class TerminalStrip extends AbstractTransparentComponent implemen public boolean arePointsConnected(int index1, int index2) { return Math.abs(index1 - index2) == getTerminalCount(); } - + @Override public boolean canPointMoveFreely(int pointIndex) { return false; - } -} + } +} diff --git a/diylc/diylc-swing/lib/diylc-core.jar b/diylc/diylc-swing/lib/diylc-core.jar index 8cebd825..55f2232b 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 f2801c32..98849989 100644 Binary files a/diylc/diylc-swing/library/main.jar and b/diylc/diylc-swing/library/main.jar differ