From 1768dbabfc3b9fa0e1b379dfd55b8c7a14f7a490 Mon Sep 17 00:00:00 2001 From: bancika Date: Mon, 30 Mar 2020 13:56:52 +0200 Subject: [PATCH] added proto board --- .../src/org/diylc/presenter/update.xml | 12 +- .../diylc/components/boards/ProtoBoard.java | 655 ++++++++++++++++++ diylc/diylc-swing/library/main.jar | Bin 635802 -> 645128 bytes 3 files changed, 665 insertions(+), 2 deletions(-) create mode 100644 diylc/diylc-library/src/org/diylc/components/boards/ProtoBoard.java diff --git a/diylc/diylc-core/src/org/diylc/presenter/update.xml b/diylc/diylc-core/src/org/diylc/presenter/update.xml index 55b83e75..7bd6d63e 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/update.xml +++ b/diylc/diylc-core/src/org/diylc/presenter/update.xml @@ -2777,7 +2777,11 @@ NEW_FEATURE Added "Dot Spacing" property in project settings that shows dots on every N-th grid line intersection - + + + NEW_FEATURE + Added "P-0+o (Proto) Board" component by Kristian BlÃ¥sol + BUG_FIX Issues with circuit analysis introduced in version 4.0.1. Wires and jumpers are made non-conductive by mistake. @@ -2796,8 +2800,12 @@ BUG_FIX - Humbucker doesn't render second coil poles properly in certain scenarios + "Humbucker Pickup" doesn't render second coil poles properly in certain scenarios + + BUG_FIX + Minor fix in tracking conductive areas + https://github.com/bancika/diy-layout-creator/releases diff --git a/diylc/diylc-library/src/org/diylc/components/boards/ProtoBoard.java b/diylc/diylc-library/src/org/diylc/components/boards/ProtoBoard.java new file mode 100644 index 00000000..b254adfa --- /dev/null +++ b/diylc/diylc-library/src/org/diylc/components/boards/ProtoBoard.java @@ -0,0 +1,655 @@ +/* + + 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.Color; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.geom.AffineTransform; + +import org.diylc.awt.StringUtils; +import org.diylc.common.HorizontalAlignment; +import org.diylc.common.ObjectCache; +import org.diylc.common.Orientation; +import org.diylc.common.VerticalAlignment; +import org.diylc.components.AbstractComponent; +import org.diylc.core.ComponentState; +import org.diylc.core.IDIYComponent; +import org.diylc.core.IDrawingObserver; +import org.diylc.core.Project; +import org.diylc.core.VisibilityPolicy; +import org.diylc.core.annotations.BomPolicy; +import org.diylc.core.annotations.ComponentDescriptor; +import org.diylc.core.annotations.EditableProperty; +import org.diylc.core.annotations.KeywordPolicy; +import org.diylc.core.measures.Size; +import org.diylc.core.measures.SizeUnit; + +@ComponentDescriptor(name = "P-0+o (Proto) Board", category = "Boards", author = "Branislav Stojkovic", + description = "A prototyping board for modular synths, central bus with V+ GND and V-", instanceNamePrefix = "BB", + zOrder = IDIYComponent.BOARD, bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, autoEdit = false, + keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME) +public class ProtoBoard extends AbstractComponent { + + private static final long serialVersionUID = 1L; + + public static Color FILL_COLOR = Color.decode("#0B3B0B"); + public static Color BORDER_COLOR = FILL_COLOR.darker(); + public static Size SPACING = new Size(0.1d, SizeUnit.in); + public static Color SELECTION_COLOR = Color.red; + public static Color PAD_COLOR = Color.decode("#D2D2D2"); + public static Color UNDERSIDE_PAD_COLOR = Color.decode("#A8A8DA"); + public static Color UNDERSIDE_LINE_COLOR = Color.decode("#CDCDFF"); + public static Color HOLE_COLOR = Color.black; + + public static float COORDINATE_FONT_SIZE = 9f; + public static Color COORDINATE_COLOR = Color.gray.brighter(); + + public static Color SEPARATOR_COLOR = Color.white; + public static Color SCREEN_COLOR = Color.decode("#CAD4CA"); + + public static Size PAD_SIZE = new Size(2d, SizeUnit.mm); + public static int ROW_COUNT = 33; + + public static Size WIDTH_SIZE = new Size(2d, SizeUnit.in); + public static Size LENGTH_SIZE = new Size(4d, SizeUnit.in); + + private static int[] SEGMENTS = new int[] { 2, 3, 3, 3, 3, 2 }; + private static int[] SEGMENTS_SUM = new int[] { 0, 2, 5, 8, 11, 14 }; + private static int[] GAPS = new int[] { 1, 0, 2, 0, 0, 0 }; + private static int[] SEGMENTS_STARTS = new int[] { 0, 3, 6, 11, 14, 17 }; + + protected Point point = new Point(0, 0); + + protected PowerStripPosition powerStripPosition; + protected Orientation orientation; + protected Boolean markUndersidePads = true; + + @SuppressWarnings("incomplete-switch") + @Override + public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, + IDrawingObserver drawingObserver) { + if (checkPointsClipped(g2d.getClip())) { + return; + } + + // adjust the angle + double theta = 0; + switch (getOrientation()) { + case _90: + theta = Math.PI / 2; + break; + case _180: + theta = Math.PI; + break; + case _270: + theta = Math.PI * 3 / 2; + break; + } + if (theta != 0) { + g2d.rotate(theta, point.x, point.y); + } + + double spacing = SPACING.convertToPixels(); + + // draw body + g2d.setColor(FILL_COLOR); + int width = (int) WIDTH_SIZE.convertToPixels(); + int length = (int) LENGTH_SIZE.convertToPixels(); + + g2d.fillRect(point.x, point.y, width, length); + g2d.setColor(componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING ? SELECTION_COLOR + : BORDER_COLOR); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); + g2d.drawRect(point.x, point.y, width, length); + + drawingObserver.stopTracking(); + + int padSize = getClosestOdd(PAD_SIZE.convertToPixels()); + int holeSize = getClosestOdd(padSize / 2); + + g2d.setFont(LABEL_FONT.deriveFont(COORDINATE_FONT_SIZE)); + + int xOffset = 1; + int yOffset = 5; + + g2d.setColor(PAD_COLOR.brighter()); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(padSize / 4)); + + drawingObserver.startTrackingContinuityArea(true); + + // draw segment connectors + for (int y = 0; y < ROW_COUNT; y++) { + for (int segment = 0; segment < SEGMENTS.length; segment++) { + drawingObserver.setContinuityMarker("SEGMENT=" + segment + ";ROW=" + y); + g2d.drawLine((int) (point.x + (xOffset + SEGMENTS_STARTS[segment]) * spacing), + (int) (point.y + (yOffset + y) * spacing), + (int) (point.x + (xOffset + SEGMENTS_STARTS[segment] + SEGMENTS[segment] - 1) * spacing), + (int) (point.y + (yOffset + y) * spacing)); + } + } + drawingObserver.setContinuityMarker(null); + + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(padSize / 4)); + + // draw central mini pad connectors, top row + for (int y = 0; y < ROW_COUNT; y++) { + // top row + g2d.drawLine((int) (point.x + (1 + SEGMENTS_SUM[3]) * spacing), (int) (point.y + (yOffset + y - 0.25d) * spacing + 1), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing), (int) (point.y + (yOffset + y - 0.25d) * spacing + 1)); + g2d.drawLine((int) (point.x + (1 + SEGMENTS_SUM[3] + 3) * spacing), (int) (point.y + (yOffset + y - 0.25d) * spacing + 1), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 2.5) * spacing), (int) (point.y + (yOffset + y - 0.25d) * spacing + 1)); + } + + g2d.setColor(getMarkUndersidePads() ? UNDERSIDE_LINE_COLOR : PAD_COLOR.brighter()); + + // bottom row. + for (int y = 0; y < ROW_COUNT; y++) { + g2d.drawLine((int) (point.x + (1 + SEGMENTS_SUM[3]) * spacing), (int) (point.y + (yOffset + y + 0.25d) * spacing + 1), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1) * spacing), (int) (point.y + (yOffset + y + 0.25d) * spacing + 1)); + g2d.drawLine((int) (point.x + (1 + SEGMENTS_SUM[3] + 3) * spacing), (int) (point.y + (yOffset + y + 0.25d) * spacing + 1), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 2) * spacing), (int) (point.y + (yOffset + y + 0.25d) * spacing + 1)); + } + + // vertical ground line + g2d.drawLine((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing), (int) (point.y + (yOffset - 1.5) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing), (int) (point.y + (yOffset + ROW_COUNT + 0.5) * spacing)); + + g2d.setColor(PAD_COLOR.brighter()); + + // traces to top and bottom 3 pads + g2d.drawPolyline(new int[] { + (int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.2) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.2) * spacing)}, + new int[] { + (int) (point.y + (yOffset - 1.5) * spacing), + (int) (point.y + (yOffset - 1) * spacing), + (int) (point.y + (yOffset - 0.3) * spacing)}, 3); + g2d.drawPolyline(new int[] { + (int) (point.x + (1 + SEGMENTS_SUM[3] + 2.5) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.8) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.8) * spacing)}, + new int[] { + (int) (point.y + (yOffset - 1.5) * spacing), + (int) (point.y + (yOffset - 1) * spacing), + (int) (point.y + (yOffset - 0.3) * spacing)}, 3); + + g2d.drawPolyline(new int[] { + (int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.2) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.2) * spacing)}, + new int[] { + (int) (point.y + (yOffset + ROW_COUNT + 0.5) * spacing), + (int) (point.y + (yOffset + ROW_COUNT) * spacing), + (int) (point.y + (yOffset + ROW_COUNT - 0.35) * spacing)}, 3); + g2d.drawPolyline(new int[] { + (int) (point.x + (1 + SEGMENTS_SUM[3] + 2.5) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.8) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.8) * spacing)}, + new int[] { + (int) (point.y + (yOffset + ROW_COUNT + 0.5) * spacing), + (int) (point.y + (yOffset + ROW_COUNT) * spacing), + (int) (point.y + (yOffset + ROW_COUNT - 0.35) * spacing)}, 3); + + drawingObserver.stopTrackingContinuityArea(); + + int miniPadSize = getClosestOdd((2d * spacing - 6) / 5); + + // draw top mini pad traces + g2d.setColor(PAD_COLOR.brighter()); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(padSize / 4)); + drawingObserver.startTrackingContinuityArea(true); + g2d.drawLine((int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing), (int) (point.y + 1 * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing), (int) (point.y + 3.5 * spacing)); + g2d.drawLine((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing + miniPadSize / 2), (int) (point.y + 1 * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing + miniPadSize / 2), (int) (point.y + 3.5 * spacing)); + g2d.drawLine((int) (point.x + (1 + SEGMENTS_SUM[3] + 2.5) * spacing), (int) (point.y + 1 * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 2.5) * spacing), (int) (point.y + 3.5 * spacing)); + drawingObserver.stopTrackingContinuityArea(); + + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); + + // vertical separators + g2d.setColor(SEPARATOR_COLOR); + + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2)); + + g2d.drawLine((int) (point.x + (1 + SEGMENTS_STARTS[2] - 0.5) * spacing), (int) (point.y + (yOffset - 1) * spacing), + (int) (point.x + (1 + SEGMENTS_STARTS[2] - 0.5) * spacing), (int) (point.y + (yOffset + ROW_COUNT -0.5) * spacing)); + g2d.drawLine((int) (point.x + (1 + SEGMENTS_STARTS[4] - 0.5) * spacing), (int) (point.y + (yOffset - 1) * spacing), + (int) (point.x + (1 + SEGMENTS_STARTS[4] - 0.5) * spacing), (int) (point.y + (yOffset + ROW_COUNT -0.5) * spacing)); + g2d.fillRect((int) (point.x + (1 + SEGMENTS_STARTS[1] - 1.25) * spacing), (int) (point.y + (yOffset - 1) * spacing), + (int)(0.5 * spacing), (int) ((ROW_COUNT + 0.5) * spacing)); + + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); + + // draw main pads + for (int segment = 0; segment < SEGMENTS.length; segment++) { + for (int y = 0; y < ROW_COUNT; y++) { + for (int x = 0; x < SEGMENTS[segment]; x++) { + int padX = (int) (point.x + (xOffset + x) * spacing); + int padY = (int) (point.y + (yOffset + y) * spacing); + + drawingObserver.startTrackingContinuityArea(true); + drawingObserver.setContinuityMarker("SEGMENT=" + segment + ";ROW=" + y); + + g2d.setColor(PAD_COLOR); + if ((segment == 2 && x == 2) || (segment == 3 && x == 0)) + g2d.fillRect(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + else + g2d.fillOval(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + + drawingObserver.setContinuityMarker(null); + + drawingObserver.stopTrackingContinuityArea(); + + g2d.setColor(PAD_COLOR.darker()); + if ((segment == 2 && x == 2) || (segment == 3 && x == 0)) + g2d.drawRect(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + else + g2d.drawOval(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + + g2d.setColor(HOLE_COLOR); + g2d.fillOval(padX - holeSize / 2, padY - holeSize / 2, holeSize, holeSize); + + // Draw horizontal labels + if (y == 0) { + g2d.setColor(COORDINATE_COLOR); + StringUtils.drawCenteredText(g2d, Integer.toString(SEGMENTS_SUM[segment] + x + 1), padX, (int) (point.y + (yOffset - 1) * spacing) - 1, + HorizontalAlignment.CENTER, VerticalAlignment.TOP); + } + } + } + + xOffset += SEGMENTS[segment] + GAPS[segment]; + } + + // Draw top and bottom 3 pads + for (int y = 0; y < 2; y++) { + g2d.setColor(SEPARATOR_COLOR); + g2d.drawRect((int) (point.x + (1 + SEGMENTS_SUM[3]) * spacing), (int) (point.y + (yOffset - 2 + y * (ROW_COUNT + 2)) * spacing), + (int)(3 * spacing), (int)spacing); + + drawingObserver.startTrackingContinuityArea(true); + + for (int x = 0; x < 3; x++) { + int padX = (int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5 + x) * spacing); + int padY = (int) (point.y + (yOffset - 1.5 + y * (ROW_COUNT + 2)) * spacing); + + g2d.setColor(PAD_COLOR); + + if (x == 0) + drawingObserver.setContinuityMarker("columnA"); + else if (x == 2) + drawingObserver.setContinuityMarker("columnC"); + + if (x == 2) + g2d.fillRect(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + else + g2d.fillOval(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + + drawingObserver.setContinuityMarker(null); + + g2d.setColor(PAD_COLOR.darker()); + if (x == 2) + g2d.drawRect(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + else + g2d.drawOval(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + g2d.setColor(HOLE_COLOR); + g2d.fillOval(padX - holeSize / 2, padY - holeSize / 2, holeSize, holeSize); + } + + drawingObserver.stopTrackingContinuityArea(); + } + + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2)); + + g2d.setColor(SCREEN_COLOR); + g2d.fillRect((int) (point.x + width - 1.5 * spacing), point.y + 2, (int) (spacing), (int) (2 * spacing)); + g2d.setColor(SEPARATOR_COLOR); + g2d.drawRect((int) (point.x + width - 5.5 * spacing), point.y + 2, (int) (5 * spacing), (int) (2 * spacing)); + + g2d.drawLine((int) (point.x + width - 5.5 * spacing), (int) (point.y + 2 * spacing) + 8, + (int) (point.x + width - 5.5 * spacing), (int) (point.y + 3.5 * spacing)); + g2d.drawLine((int) (point.x + width - 4.5 * spacing), (int) (point.y + 2 * spacing + 8), + (int) (point.x + width - 4.5 * spacing), (int) (point.y + 3.5 * spacing)); + g2d.drawLine((int) (point.x + width - 1.5 * spacing), (int) (point.y + 2 * spacing + 8), + (int) (point.x + width - 1.5 * spacing), (int) (point.y + 3.5 * spacing)); + + g2d.setColor(PAD_COLOR.brighter()); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(padSize / 4)); + + drawingObserver.startTrackingContinuityArea(true); + + // Draw two horizontal connections in the top-right section + g2d.drawLine((int) (point.x + width - 4 * spacing), (int) (point.y + 0.5 * spacing), (int) (point.x + width - (2) * spacing), (int) (point.y + 0.5 * spacing)); + g2d.drawLine((int) (point.x + width - 4 * spacing), (int) (point.y + 1.5 * spacing), (int) (point.x + width - (2) * spacing), (int) (point.y + 1.5 * spacing)); + + // Draw top-right pads + for (int x = 0; x < 6; x++) { + int padX = (int) (point.x + width - (x + 1) * spacing); + + g2d.setColor(PAD_COLOR.brighter()); + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(padSize / 4)); + g2d.drawLine(padX, (int) (point.y + 0.5 * spacing), padX, (int) (point.y + 3 * spacing)); + + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); + + for (int y = 0; y < 3; y++) { + + int padY = (int) (point.y + (y + (y == 2 ? 0.5 : 0) + 0.5) * spacing); + + if (x == 0) + drawingObserver.setContinuityMarker("-12V"); + else if (x == 4) + drawingObserver.setContinuityMarker("+12V"); + else if (x == 5) + drawingObserver.setContinuityMarker("+5V"); + else + drawingObserver.setContinuityMarker("GND"); + + g2d.setColor(PAD_COLOR); + if (x >= 4) + g2d.fillRect(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + else + g2d.fillOval(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + + drawingObserver.setContinuityMarker(null); + + g2d.setColor(PAD_COLOR.darker()); + if (x >= 4) + g2d.drawRect(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + else + g2d.drawOval(padX - padSize / 2, padY - padSize / 2, padSize, padSize); + g2d.setColor(HOLE_COLOR); + g2d.fillOval(padX - holeSize / 2, padY - holeSize / 2, holeSize, holeSize); + } + } + + drawingObserver.stopTrackingContinuityArea(); + + // draw top mini pads + g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1)); + for (int y = 0; y < 4; y++) { + int padY = (int) (point.y + (0.5 * y + 1) * spacing); + int[] padXs = new int[] {(int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing - miniPadSize - 2), (int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing), + (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) - miniPadSize / 2 - 2, (int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) + miniPadSize / 2 + 1, + (int) (point.x + (1 + SEGMENTS_SUM[3] + 2.5) * spacing), (int) (point.x + (1 + SEGMENTS_SUM[3] + 2.5) * spacing + miniPadSize + 2)}; + + for (int i = 0; i < padXs.length; i++) { + int padX = padXs[i]; + drawingObserver.startTrackingContinuityArea(true); + + if (i == 0 || i == 2 || i == 5) { + switch (y) { + case 0: drawingObserver.setContinuityMarker("+5V"); + break; + case 1: drawingObserver.setContinuityMarker("+12V"); + break; + case 2: drawingObserver.setContinuityMarker("GND"); + break; + case 3: drawingObserver.setContinuityMarker("-12V"); + break; + } + } + + g2d.setColor(PAD_COLOR); + g2d.fillRect(padX - miniPadSize / 2, padY - miniPadSize / 2, miniPadSize, miniPadSize); + + drawingObserver.setContinuityMarker(null); + + drawingObserver.stopTrackingContinuityArea(); + g2d.setColor(PAD_COLOR.darker()); + g2d.drawRect(padX - miniPadSize / 2, padY - miniPadSize / 2, miniPadSize, miniPadSize); + } + } + + g2d.setColor(COORDINATE_COLOR); + + // Draw top labels + StringUtils.drawCenteredText(g2d, "+5V", (int) (point.x + (1 + SEGMENTS_SUM[3] - 0.3) * spacing), (int) (point.y + 1 * spacing) + 1, + HorizontalAlignment.RIGHT, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "+12V", (int) (point.x + (1 + SEGMENTS_SUM[3] - 0.3) * spacing), (int) (point.y + 1.5 * spacing) + 1, + HorizontalAlignment.RIGHT, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "GND", (int) (point.x + (1 + SEGMENTS_SUM[3] - 0.3) * spacing), (int) (point.y + 2 * spacing) + 1, + HorizontalAlignment.RIGHT, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, "-12V", (int) (point.x + (1 + SEGMENTS_SUM[3] - 0.3) * spacing), (int) (point.y + 2.5 * spacing) + 1, + HorizontalAlignment.RIGHT, VerticalAlignment.CENTER); + + // Draw top-right labels + int labelY = (int) (point.y + 3.3 * spacing); + StringUtils.drawCenteredText(g2d, "+5V", (int) (point.x + width - 6 * spacing), labelY, HorizontalAlignment.CENTER, VerticalAlignment.TOP); + StringUtils.drawCenteredText(g2d, "+", (int) (point.x + width - 5 * spacing) - 6, labelY, HorizontalAlignment.CENTER, VerticalAlignment.TOP); + StringUtils.drawCenteredText(g2d, " 12V", (int) (point.x + width - 5 * spacing) + 2, labelY, HorizontalAlignment.CENTER, VerticalAlignment.TOP); + StringUtils.drawCenteredText(g2d, "GND", (int) (point.x + width - 3 * spacing), labelY, HorizontalAlignment.CENTER, VerticalAlignment.TOP); + StringUtils.drawCenteredText(g2d, "-12V", (int) (point.x + width - 1 * spacing), labelY, HorizontalAlignment.CENTER, VerticalAlignment.TOP); + + // Draw vertical labels + byte A = "A".getBytes()[0]; + byte a = "a".getBytes()[0]; + for (int y = 0; y < ROW_COUNT; y++) { + int padY = (int) (point.y + (yOffset + y) * spacing); + String label; + if (y >= 26) + label = new String(new byte[] {(byte) (a + y - 26)}); + else + label = new String(new byte[] {(byte) (A + y)}); + StringUtils.drawCenteredText(g2d, label, (int) (point.x + spacing * 0.35), padY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + StringUtils.drawCenteredText(g2d, label, (int) (point.x + width - spacing * 0.35), padY, HorizontalAlignment.CENTER, VerticalAlignment.CENTER); + } + + g2d.setColor(PAD_COLOR.brighter()); + g2d.setFont(LABEL_FONT.deriveFont(COORDINATE_FONT_SIZE + 2)); + + StringUtils.drawCenteredText(g2d, "P-0+o by:\nKristian Blåsol 2019", (int) (point.x + width * 0.70d), (int) (point.y + (yOffset + ROW_COUNT + 0.4) * spacing), + HorizontalAlignment.LEFT, VerticalAlignment.TOP); + + // draw central mini pads + for (int y = 0; y < ROW_COUNT; y++) { + g2d.setColor(PAD_COLOR); + + drawingObserver.startTrackingContinuityArea(true); + + // top row + g2d.fillRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing) + 1, (int) (point.y + (yOffset + y - 0.5d) * spacing + 2), miniPadSize, miniPadSize); + drawingObserver.setContinuityMarker("columnA"); + g2d.fillRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing) + miniPadSize + 3, (int) (point.y + (yOffset + y - 0.5d) * spacing + 2), miniPadSize, miniPadSize); + drawingObserver.setContinuityMarker("columnC"); + g2d.fillRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) + 3, (int) (point.y + (yOffset + y - 0.5d) * spacing + 2), miniPadSize, miniPadSize); + drawingObserver.setContinuityMarker(null); + g2d.fillRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) + miniPadSize + 5, (int) (point.y + (yOffset + y - 0.5d) * spacing + 2), miniPadSize, miniPadSize); + + drawingObserver.stopTrackingContinuityArea(); + + g2d.setColor(PAD_COLOR.darker()); + g2d.drawRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing) + 1, (int) (point.y + (yOffset + y - 0.5d) * spacing + 2), miniPadSize, miniPadSize); + g2d.drawRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 0.5) * spacing) + miniPadSize + 3, (int) (point.y + (yOffset + y - 0.5d) * spacing + 2), miniPadSize, miniPadSize); + + g2d.setColor(getMarkUndersidePads() ? UNDERSIDE_PAD_COLOR : PAD_COLOR); + + drawingObserver.startTrackingContinuityArea(true); + + // bottom row + + g2d.fillRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) - miniPadSize / 2, (int) (point.y + (yOffset + y + 0.5d) * spacing - 1 - miniPadSize), miniPadSize, miniPadSize); +// drawingObserver.setContinuityMarker("columnB"); + g2d.fillRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) - miniPadSize * 3 / 2 - 2, (int) (point.y + (yOffset + y + 0.5d) * spacing - 1 - miniPadSize), miniPadSize, miniPadSize); +// drawingObserver.setContinuityMarker("null"); + g2d.fillRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) + miniPadSize / 2 + 3, (int) (point.y + (yOffset + y + 0.5d) * spacing - 1 - miniPadSize), miniPadSize, miniPadSize); + + drawingObserver.stopTrackingContinuityArea(); + + g2d.setColor((getMarkUndersidePads() ? UNDERSIDE_PAD_COLOR : PAD_COLOR).darker()); + + g2d.drawRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) + 3, (int) (point.y + (yOffset + y - 0.5d) * spacing + 2), miniPadSize, miniPadSize); + g2d.drawRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) + miniPadSize + 5, (int) (point.y + (yOffset + y - 0.5d) * spacing + 2), miniPadSize, miniPadSize); + + g2d.drawRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) - miniPadSize / 2, (int) (point.y + (yOffset + y + 0.5d) * spacing - 1 - miniPadSize), miniPadSize, miniPadSize); + g2d.drawRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) - miniPadSize * 3 / 2 - 2, (int) (point.y + (yOffset + y + 0.5d) * spacing - 1 - miniPadSize), miniPadSize, miniPadSize); + g2d.drawRect((int) (point.x + (1 + SEGMENTS_SUM[3] + 1.5) * spacing) + miniPadSize / 2 + 3, (int) (point.y + (yOffset + y + 0.5d) * spacing - 1 - miniPadSize), miniPadSize, miniPadSize); + } + } + + @Override + public void drawIcon(Graphics2D g2d, int width, int height) { + int factor = 32 / width; + int arc = 4 / factor; + g2d.setColor(FILL_COLOR); + g2d.fillRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor); + g2d.setColor(BORDER_COLOR); + g2d.drawRect(2 / factor, 2 / factor, width - 4 / factor, height - 4 / factor); + + g2d.setColor(PAD_COLOR); + g2d.fillRoundRect(width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor), + getClosestOdd(5.0 / factor), arc, arc); + g2d.setColor(BORDER_COLOR); + g2d.drawRoundRect(width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor), + getClosestOdd(5.0 / factor), arc, arc); + + g2d.setColor(PAD_COLOR); + g2d.fillRoundRect(2 * width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor), + getClosestOdd(5.0 / factor), arc, arc); + g2d.setColor(BORDER_COLOR); + g2d.drawRoundRect(2 * width / 3 - 2 / factor, width / 3 - 2 / factor, getClosestOdd(5.0 / factor), + getClosestOdd(5.0 / factor), arc, arc); + + g2d.setColor(PAD_COLOR); + g2d.fillRoundRect(width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor), + getClosestOdd(5.0 / factor), arc, arc); + g2d.setColor(BORDER_COLOR); + g2d.drawRoundRect(width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor), + getClosestOdd(5.0 / factor), arc, arc); + + g2d.setColor(PAD_COLOR); + g2d.fillRoundRect(2 * width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor), + getClosestOdd(5.0 / factor), arc, arc); + g2d.setColor(BORDER_COLOR); + g2d.drawRoundRect(2 * width / 3 - 2 / factor, 2 * width / 3 - 2 / factor, getClosestOdd(5.0 / factor), + getClosestOdd(5.0 / factor), arc, arc); + } + + @EditableProperty + public Orientation getOrientation() { + if (orientation == null) + orientation = Orientation.DEFAULT; + return orientation; + } + + public void setOrientation(Orientation orientation) { + this.orientation = orientation; + } + + @EditableProperty(name = "Power Strip") + public PowerStripPosition getPowerStripPosition() { + if (powerStripPosition == null) + powerStripPosition = PowerStripPosition.Inline; + return powerStripPosition; + } + + public void setPowerStripPosition(PowerStripPosition powerStripPosition) { + this.powerStripPosition = powerStripPosition; + } + + @EditableProperty(name = "Mark Underside Pads") + public Boolean getMarkUndersidePads() { + return markUndersidePads; + } + + public void setMarkUndersidePads(Boolean markUndersidePads) { + this.markUndersidePads = markUndersidePads; + } + + @Override + public int getControlPointCount() { + return 2; + } + + @Override + public boolean canPointMoveFreely(int pointIndex) { + return false; + } + + @SuppressWarnings("incomplete-switch") + @Override + public Point getControlPoint(int index) { + if (index == 0) + return point; + + // create a synthetic second control point for clipping check and to make sure that we cannot drag the right side of the board off the screen + + // adjust the angle + double theta = 0; + switch (getOrientation()) { + case _90: + theta = Math.PI / 2; + break; + case _180: + theta = Math.PI; + break; + case _270: + theta = Math.PI * 3 / 2; + break; + } + int width = (int) WIDTH_SIZE.convertToPixels(); + int length = (int) LENGTH_SIZE.convertToPixels(); + Point secondPoint = new Point((int) (point.x + width), (int) (point.y + length)); + if (theta != 0) { + AffineTransform tx = AffineTransform.getRotateInstance(theta, point.x, point.y); + tx.transform(secondPoint, secondPoint); + } + return secondPoint; + } + + @Override + public boolean isControlPointSticky(int index) { + return false; + } + + @Override + public VisibilityPolicy getControlPointVisibilityPolicy(int index) { + return VisibilityPolicy.NEVER; + } + + @Override + public void setControlPoint(Point point, int index) { + if (index == 0) + this.point.setLocation(point); + } + + @Override + public Void getValue() { + return null; + } + + @Override + public void setValue(Void value) {} + + @Override + public String getControlPointNodeName(int index) { + return null; + } + + public enum PowerStripPosition { + Inline, Offset + } +} diff --git a/diylc/diylc-swing/library/main.jar b/diylc/diylc-swing/library/main.jar index efa8e7bbeaacc93623cb63d9fc4a33037cfeac1f..81a548d4beaf18f72df29a42e0d2a819ce6593de 100644 GIT binary patch delta 28129 zcmZ6z19W83(kL9;wrv|Tv29xu+a25Li6^#=i8bNGw(U%k3Ete~{@?fB-)r@%TD42N zPMv+aPwmLt zvGq2?_@d6?+J1P~f3bE`7eQy%jSHRkH>q|%6&7L9_T_{LTHoN>K*$HJ{~x9JnJ z=WrgkjFx}q&~@eSm3<#QkJi=M*q)YkgDM_Qd$T({Mx zV7IVa%OfkS)fB?cI%_1@{);vNoM$y@x`;2G_I!Zdy@SX#d5@(U#pND8S`|cxqs)ag z#zN|NQ1h>Oq~s5F2K{zw7;DC@+?dH>;%oDcut3gnvLe!0jH&}OYy{=mydVVl(49!6 z7XFSj+=RK*_g$()>TrB}@AJwUA!);JYDb&XN8!nM+IeUsnOIz@=q^7ZVj!>_k?vkc zIwSxZdM7Yv>|~M&LW#qUfs@}O>X1VW#oS|R$j~fGaog@7r^!dah|_xxkF@^=_lYxv zI^p4G=Ziq1tp}*+=<|u$z7rqARl^*&;+dqOQn!tnk}8&=I;D1h-S|Z_L%IVk6%t1m zJ}Gy{?==(g;3!FCJj4UC`o5YagV`%YCK*FF^L?A|ChupUS;P-{2~?NZGl&0gA%Fq- zPoj*3eOZwL0|7aJ05Xd~;V0Fh0o!$8agr~an8D@@8%UZ-!9MPfW*ayE7Az2uQkLYv zLULfO4lFEy$<)@^#U)z@-bih5{%!K&r;kT+rdjgY0cdFeDi~_PkGuep4HWz&DKNC! z(1{Bw?d7wf^?hw!8*!^9lRWj1a=W@HJ3Dw#un6_la`n>!jf#04-HHcuVjJRam{EYm z#k!<>G6>?qYJ z3#$Fg9bLnbNV`3Pl_g;kSRxOrRvD)%ckra!l z4QdFWHj;0oMf4(X(4LC!z1&DHLwn3YRGt@7c`@E~DW;j*j&iOz;v5apE#xn-Ypc=X zvEyWbNwan*Q=|G63r}PomTuFmXM?&XWwQeb={;1w9=AaMZ^#z{F!pKlbnBWiiy>=;78Xl1;fdm2aD@^^|Ebtl%Ki-OPU-j zfZ}QQ*e;phnIfcsLZ+igiC5*=E(sbd_?mmk71P8o09_uu2*^ItSbNI71&J3TL(L`h z>n3QfN7%_yVYDj<;3K(mvG$spqS0}pDmIe1X^xU@Bz5abO~wkPh=!@E%WYKq!oh-g zXX}&A6rN&{rCnt`69Izc0ZYotg7`fmAbJPmVP)ZY5|cCf1jdp(oLn%qtLOPg%M5

Ho;<>d21>0_)a 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�{}hfWrPs+u#>Ft1HB|s_tT(RMwtBiDw*t< z5b~z_nBdWaTH)@+P|YMS)bgvoO4VDj_9}yw{5m#sL|$<*$g_v^Cx?T##IL>tw>${= z%+HlLzxon@x56X*Bo8(og4YoI+*l>6WkTU?+qNW z+eXNa#QggNI*~yjZ(JTJIpD%5SSUo5@99UG!{M~_JDfMVDcqfrMfm$u0oxCO0PAcf z`+bsR%Q7_)Apc^aZNBOOnVs0;o(lZ*X@M%t3=1oQNGt<)DYH`gCL_NE-h3EJNyPS3 zhe37PW*N#agPcN;_GN(dD=;EZNK2Ch>=Vg{Ho?1Ce*uQ}102nimyUraSf{cwxWW=q z*NLbR=NT1#>|l=V%3*^eP}g#R(1lh|N;#DK0aE^$Lg71)zZ>~GP*(X@6>amS$z>y} z8TP4w{6@46tbqH%{3jCr=7QvdQ_jQUT35+ub1T74Kcko*?(#KHc^UiW?Jfr^?!*6H z3Tw(gVw+0T!;{#&zj0T_LU8{gaKE>LYj?ARyFY@cUsVZNfEZCw35sIi2fsk>jB8u; oHxTj<<_KFJK>?I;$Pw_7MSmQ71o>GxnK+q@o(AWz6!5+3|L9G6`v3p{ delta 18696 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 Hl(_!`-K~$K