From 66e29aa275cf62c070b1866956a259b7af756a80 Mon Sep 17 00:00:00 2001 From: bancika Date: Mon, 5 Dec 2016 17:44:56 +0100 Subject: [PATCH] added terminal strip --- .../connectivity/TerminalStrip.java | 428 ++++++++++++++++++ .../diylc/components/misc/BatterySymbol.java | 161 ++++--- diylc/diylc-swing/library/main.jar | Bin 316668 -> 323442 bytes diylc/diylc-swing/update.xml | 8 +- 4 files changed, 520 insertions(+), 77 deletions(-) create mode 100644 diylc/diylc-library/src/org/diylc/components/connectivity/TerminalStrip.java 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 e6feb815b39421e663bfe7109c38494ec49c8764..87619af764ac2ee13294babe6f96597a938b0049 100644 GIT binary patch delta 13948 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 G$o~V|KF?kN delta 7556 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 a;Olz`UHKmHi^dYMgf2RnvM-=)5&s9XZNE4G 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