diff --git a/diylc/diylc-library/src/org/diylc/components/connectivity/TerminalStrip.java b/diylc/diylc-library/src/org/diylc/components/connectivity/TerminalStrip.java new file mode 100644 index 00000000..f4469911 --- /dev/null +++ b/diylc/diylc-library/src/org/diylc/components/connectivity/TerminalStrip.java @@ -0,0 +1,428 @@ +package org.diylc.components.connectivity; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.geom.Area; +import java.awt.geom.Ellipse2D; +import java.awt.geom.RoundRectangle2D; + +import org.diylc.appframework.miscutils.ConfigurationManager; +import org.diylc.common.IPlugInPort; +import org.diylc.common.ObjectCache; +import org.diylc.common.Orientation; +import org.diylc.components.AbstractTransparentComponent; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.Theme; +import org.diylc.core.VisibilityPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.annotations.KeywordPolicy; +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 = "Connectivity", + instanceNamePrefix = "TS", description = "Row of terminals for point-to-point construction", stretchable = false, + zOrder = IDIYComponent.BOARD, keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME) +public class TerminalStrip extends AbstractTransparentComponent { + + private static final long serialVersionUID = 1L; + + public static Color BOARD_COLOR = Color.decode("#CD8500"); + public static Color BORDER_COLOR = BOARD_COLOR.darker(); + public static Color TERMINAL_COLOR = Color.decode("#C3E4ED"); + 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 Point[] controlPoints = new Point[] {new Point(0, 0)}; + private Color boardColor = BOARD_COLOR; + private Color borderColor = BORDER_COLOR; + 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") + public Size getTerminalSpacing() { + return terminalSpacing; + } + + public void setTerminalSpacing(Size pinSpacing) { + this.terminalSpacing = pinSpacing; + updateControlPoints(); + // Reset body shape; + body = null; + } + + @EditableProperty(name = "Hole spacing") + 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") + 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 Point 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(Point point, int index) { + controlPoints[index].setLocation(point); + body = null; + } + + private void updateControlPoints() { + Point firstPoint = controlPoints[0]; + controlPoints = new Point[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 Point(firstPoint.x + dx1, firstPoint.y + dy1); + controlPoints[i + getTerminalCount()] = new Point(firstPoint.x + dx2, firstPoint.y + dy2); + if (centerHole) + controlPoints[i + 2 * getTerminalCount()] = new Point(firstPoint.x + cx, firstPoint.y + cy); + } + } + + public Area[] getBody() { + if (body == null) { + body = new Area[2]; + int x = controlPoints[0].x; + int y = controlPoints[0].y; + 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; + Area terminals = 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; + + terminals = new Area(); + for (int i = 0; i < getTerminalCount(); i++) { + Point p1 = getControlPoint(i); + Point p2 = getControlPoint(i + getTerminalCount()); + if (p2.x < p1.x || p2.y < p1.y) { + Point p = p1; + p1 = p2; + p2 = p; + } + + Area terminal = + new Area(new RoundRectangle2D.Double(p1.x - holeSize, p1.y - holeSize, p2.x - p1.x + holeSize * 2, p2.y + - p1.y + holeSize * 2, holeSize, holeSize)); + + terminal.subtract(new Area(new Ellipse2D.Double(p1.x - holeSize / 2, p1.y - holeSize / 2, holeSize, holeSize))); + terminal.subtract(new Area(new Ellipse2D.Double(p2.x - holeSize / 2, p2.y - holeSize / 2, holeSize, holeSize))); + if (centerHole) { + Point p3 = getControlPoint(i + 2 * getTerminalCount()); + Area centerHole = + new Area(new Ellipse2D.Double(p3.x - holeSize / 2, p3.y - holeSize / 2, holeSize, holeSize)); + terminal.subtract(centerHole); + bodyArea.subtract(centerHole); + } + + terminals.add(terminal); + } + body[1] = terminals; + } + return body; + } + + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + if (checkPointsClipped(g2d.getClip())) { + return; + } + Area mainArea = getBody()[0]; + Area terminalArea = getBody()[1]; + + 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 + : getBorderColor(); + } + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); + + g2d.setColor(finalBorderColor); + g2d.draw(mainArea); + + g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : TERMINAL_COLOR); + g2d.fill(terminalArea); + + 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); + g2d.draw(terminalArea); + + 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(BORDER_COLOR); + 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; + } + + @EditableProperty(name = "Border") + public Color getBorderColor() { + if (borderColor == null) { + borderColor = BORDER_COLOR; + } + return borderColor; + } + + public void setBorderColor(Color borderColor) { + this.borderColor = borderColor; + } +} diff --git a/diylc/diylc-library/src/org/diylc/components/misc/BatterySymbol.java b/diylc/diylc-library/src/org/diylc/components/misc/BatterySymbol.java index 4da124d8..0e761415 100644 --- a/diylc/diylc-library/src/org/diylc/components/misc/BatterySymbol.java +++ b/diylc/diylc-library/src/org/diylc/components/misc/BatterySymbol.java @@ -13,92 +13,103 @@ import org.diylc.core.measures.Size; import org.diylc.core.measures.SizeUnit; import org.diylc.core.measures.VoltageUnit; -@ComponentDescriptor(name = "Battery (schematic symbol)", author = "N9XYP", category = "Schematics", creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "B", description = "Battery schematic symbol", zOrder = IDIYComponent.COMPONENT) +@ComponentDescriptor(name = "Battery (schematic symbol)", author = "N9XYP", category = "Schematics", + creationMethod = CreationMethod.POINT_BY_POINT, instanceNamePrefix = "B", description = "Battery schematic symbol", + zOrder = IDIYComponent.COMPONENT) public class BatterySymbol extends AbstractSchematicLeadedSymbol { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private String value = "Battery"; - - public static Size DEFAULT_LENGTH = new Size(0.05, SizeUnit.in); // plate spacing - public static Size DEFAULT_WIDTH = new Size(0.15, SizeUnit.in); // plate size - - private org.diylc.core.measures.Voltage voltageNew = new org.diylc.core.measures.Voltage(9d, VoltageUnit.V); - // sets battery voltage to 9V - + private String value = "Battery"; - @Override - public String getValueForDisplay() { - return getValue().toString() + (getVoltageNew() == null ? "" : " " + getVoltageNew().toString()); - } + public static Size DEFAULT_LENGTH = new Size(0.05, SizeUnit.in); // plate spacing + public static Size DEFAULT_WIDTH = new Size(0.15, SizeUnit.in); // plate size + + private org.diylc.core.measures.Voltage voltageNew = new org.diylc.core.measures.Voltage(9d, VoltageUnit.V); + + // sets battery voltage to 9V - @EditableProperty - public String getValue() { - return value; - } + @Override + public String getValueForDisplay() { + return getValue().toString() + (getVoltageNew() == null ? "" : " " + getVoltageNew().toString()); + } - public void setValue(String value) { - this.value = value; - } - @EditableProperty(name = "Voltage") - public org.diylc.core.measures.Voltage getVoltageNew() { - return voltageNew; - } + @EditableProperty + public String getValue() { + return value; + } - public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) { - this.voltageNew = voltageNew; - } - + public void setValue(String value) { + this.value = value; + } - @Override - protected Size getDefaultWidth() { - return DEFAULT_WIDTH; - } - - @Override - protected Size getDefaultLength() { - return DEFAULT_LENGTH; - } + @EditableProperty(name = "Voltage") + public org.diylc.core.measures.Voltage getVoltageNew() { + return voltageNew; + } - @Override - protected Shape getBodyShape() { - GeneralPath polyline = new GeneralPath(); - double length = getLength().convertToPixels(); // plate spacing - double width = getWidth().convertToPixels(); // plate size - polyline.moveTo(0, 0); // start point - polyline.lineTo(0, width); // draw first plate (positive) - // 2nd plate width = w/4 + w/2 + w/4 - // w - w/4 = w/2 pixels - polyline.moveTo(length, width / 4); // start 2nd plate - polyline.lineTo(length, width - width / 4); // draw second plate w/2 pixels (negative) - return polyline; - } + public void setVoltageNew(org.diylc.core.measures.Voltage voltageNew) { + this.voltageNew = voltageNew; + } - @Override - protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) { - // Draw + sign. - g2d.setColor(getBorderColor()); - int plusSize = getClosestOdd(getWidth().convertToPixels() / 4); // 1/4 length of plus sign - int x = -plusSize; // center point - int y = plusSize; // end point - g2d.drawLine(x - plusSize / 2, y - plusSize, x + plusSize / 2, y - plusSize); // line from X-center point +- 1/2 length about y-center - g2d.drawLine(x, y - plusSize / 2, x, y - plusSize * 3 / 2); // line from y-center point +- 1/2 length about x-center - } - public void drawIcon(Graphics2D g2d, int width, int height) { - g2d.rotate(-Math.PI / 4, width / 2, height / 2); - g2d.setColor(COLOR); - g2d.drawLine(0, height / 2, 13, height / 2); // draw leads - g2d.drawLine(width - 13, height / 2, width, height / 2); - g2d.setColor(COLOR); - g2d.drawLine(14, height / 2 - 6, 14, height / 2 + 6); // pos plate - g2d.drawLine(width - 14, height / 2 - 3, width - 14, height / 2 + 3); // neg plate - // plus sign - g2d.drawLine(height / 2 - 4, height / 2 - 5, height / 2 - 8, height / 2 - 5); - g2d.drawLine(height / 2 - 6, height / 2 - 3, height / 2 - 6, height / 2 - 7); - } + @Override + protected Size getDefaultWidth() { + return DEFAULT_WIDTH; + } - -} \ No newline at end of file + @Override + protected Size getDefaultLength() { + return DEFAULT_LENGTH; + } + + @Override + protected Shape getBodyShape() { + GeneralPath polyline = new GeneralPath(); + double length = getLength().convertToPixels(); // plate spacing + double width = getWidth().convertToPixels(); // plate size + polyline.moveTo(0, 0); // start point + polyline.lineTo(0, width); // draw first plate (positive) + // 2nd plate width = w/4 + w/2 + w/4 + // w - w/4 = w/2 pixels + polyline.moveTo(length, width / 4); // start 2nd plate + polyline.lineTo(length, width - width / 4); // draw second plate w/2 pixels (negative) + return polyline; + } + + @Override + protected void decorateComponentBody(Graphics2D g2d, boolean outlineMode) { + // Draw + sign. + g2d.setColor(getBorderColor()); + int plusSize = getClosestOdd(getWidth().convertToPixels() / 4); // 1/4 length of plus sign + int x = -plusSize; // center point + int y = plusSize; // end point + g2d.drawLine(x - plusSize / 2, y - plusSize, x + plusSize / 2, y - plusSize); // line from + // X-center point + // +- 1/2 length + // about y-center + g2d.drawLine(x, y - plusSize / 2, x, y - plusSize * 3 / 2); // line from y-center point +- 1/2 + // length about x-center + } + + public void drawIcon(Graphics2D g2d, int width, int height) { + g2d.rotate(-Math.PI / 4, width / 2, height / 2); + g2d.setColor(COLOR); + g2d.drawLine(0, height / 2, 13 * width / 32, height / 2); // draw leads + g2d.drawLine(width - 13 * width / 32, height / 2, width, height / 2); + g2d.setColor(COLOR); + g2d.drawLine(14 * width / 32, height / 2 - 6 * width / 32, 14 * width / 32, height / 2 + 6 * width / 32); // pos + // plate + g2d.drawLine(width - 14 * width / 32, height / 2 - 3, width - 14 * width / 32, height / 2 + 3 * width / 32); // neg + // plate + // plus sign + g2d.drawLine(height / 2 - 4 * width / 32, height / 2 - 5 * width / 32, height / 2 - 8 * width / 32, height / 2 - 5 + * width / 32); + g2d.drawLine(height / 2 - 6 * width / 32, height / 2 - 3 * width / 32, height / 2 - 6 * width / 32, height / 2 - 7 + * width / 32); + } + + +} diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index e6feb815..87619af7 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 138d01bd..43fab339 100644 --- a/diylc/diylc-swing/update.xml +++ b/diylc/diylc-swing/update.xml @@ -1405,10 +1405,14 @@ 2016-11-12 20:00:00.000 CET - + NEW_FEATURE - Battery schematic symbol + Terminal strip component added + + + NEW_FEATURE + Battery schematic symbol added https://github.com/bancika/diy-layout-creator/releases