mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
merged changes
This commit is contained in:
@@ -35,19 +35,9 @@ public enum Orientation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public double toDegrees() {
|
public double toDegrees() {
|
||||||
switch (this) {
|
if (this == DEFAULT)
|
||||||
case DEFAULT:
|
|
||||||
return 0;
|
|
||||||
case _180:
|
|
||||||
return 180;
|
|
||||||
case _270:
|
|
||||||
return 270;
|
|
||||||
case _90:
|
|
||||||
return 90;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
return Integer.parseInt(name().replace("_", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
public double toRadians() {
|
public double toRadians() {
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
*/
|
||||||
|
package org.diylc.common;
|
||||||
|
|
||||||
|
public enum Orientation45 {
|
||||||
|
|
||||||
|
DEFAULT, _45, _90, _135, _180, _225, _270, _315;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if (this == DEFAULT) {
|
||||||
|
return "Default";
|
||||||
|
} else {
|
||||||
|
return name().replace("_", "") + " degrees clockwise";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double toDegrees() {
|
||||||
|
if (this == DEFAULT)
|
||||||
|
return 0;
|
||||||
|
return Integer.parseInt(name().replace("_", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
public double toRadians() {
|
||||||
|
return Math.toRadians(toDegrees());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,7 +72,7 @@ public enum IconLoader {
|
|||||||
BufferedImage img = null;
|
BufferedImage img = null;
|
||||||
try {
|
try {
|
||||||
img = ImageIO.read(getClass().getResourceAsStream("/images/" + name));
|
img = ImageIO.read(getClass().getResourceAsStream("/images/" + name));
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
Logger.getLogger(IconLoader.class).error("Couldn't find file: " + name);
|
Logger.getLogger(IconLoader.class).error("Couldn't find file: " + name);
|
||||||
}
|
}
|
||||||
return img;
|
return img;
|
||||||
|
|||||||
+2
-2
@@ -27,9 +27,9 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
|
|
||||||
public abstract class NetlistAnalyzer {
|
public abstract class AbstractNetlistAnalyzer {
|
||||||
|
|
||||||
public NetlistAnalyzer() {
|
public AbstractNetlistAnalyzer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Summary> summarize(List<Netlist> netlists, Node preferredOutput)
|
public List<Summary> summarize(List<Netlist> netlists, Node preferredOutput)
|
||||||
@@ -23,6 +23,7 @@ import java.util.Collections;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
|
|
||||||
@@ -59,10 +60,6 @@ public class Netlist implements Comparable<Netlist> {
|
|||||||
return switchSetup;
|
return switchSetup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void done() {
|
|
||||||
Collections.sort(switchSetup);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
@@ -88,10 +85,15 @@ public class Netlist implements Comparable<Netlist> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSwitchSetupString() {
|
||||||
|
return getSwitchSetup().isEmpty() ? "[ ALL ]" : "[ " +
|
||||||
|
getSwitchSetup().stream().map(x -> x.toString()).collect(Collectors.joining(",")) + " ]";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("Switch setup: ").append(getSwitchSetup()).append("\n\n");
|
sb.append("Switch setup: ").append(getSwitchSetupString()).append("\n\n");
|
||||||
List<Group> list = getSortedGroups();
|
List<Group> list = getSortedGroups();
|
||||||
for (Group g : list) {
|
for (Group g : list) {
|
||||||
sb.append("\t").append(g).append("\n");
|
sb.append("\t").append(g).append("\n");
|
||||||
|
|||||||
@@ -19,15 +19,7 @@ package org.diylc.netlist;
|
|||||||
|
|
||||||
import java.awt.geom.Area;
|
import java.awt.geom.Area;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
@@ -191,10 +183,29 @@ public class NetlistBuilder {
|
|||||||
// sort everything alphabetically
|
// sort everything alphabetically
|
||||||
List<Netlist> netlists = new ArrayList<Netlist>(result.keySet());
|
List<Netlist> netlists = new ArrayList<Netlist>(result.keySet());
|
||||||
Collections.sort(netlists);
|
Collections.sort(netlists);
|
||||||
|
netlists.forEach(netlist -> cleanupRedundantSwitches(netlist.getSwitchSetup()));
|
||||||
|
|
||||||
return netlists;
|
return netlists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void cleanupRedundantSwitches(List<SwitchSetup> switchSetups) {
|
||||||
|
Map<ISwitch, Set<Integer>> positionCountMap = new HashMap<>();
|
||||||
|
switchSetups.forEach(s -> s.getPositions().forEach(pos -> {
|
||||||
|
positionCountMap.computeIfAbsent(pos.getSwitch(), k -> new HashSet<Integer>()).add(pos.getPosition());
|
||||||
|
}));
|
||||||
|
// find switches that are here in all the positions, meaning that they don't affect the circuit
|
||||||
|
Set<ISwitch> switchesToPrune = positionCountMap.entrySet().stream()
|
||||||
|
.filter(e -> e.getKey().getPositionCount() == e.getValue().size())
|
||||||
|
.map(x -> x.getKey())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
switchSetups.forEach(s -> s.getPositions().removeIf(x -> switchesToPrune.contains(x.getSwitch())));
|
||||||
|
switchSetups.removeIf(x -> x.getPositions().isEmpty());
|
||||||
|
HashSet<SwitchSetup> uniqueSetups = new HashSet<>(switchSetups);
|
||||||
|
switchSetups.clear();
|
||||||
|
switchSetups.addAll(uniqueSetups);
|
||||||
|
switchSetups.sort(Comparator.comparing(x -> x.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
public static Netlist buildNetlist(List<IDIYComponent<?>> components, Collection<Node> nodes,
|
public static Netlist buildNetlist(List<IDIYComponent<?>> components, Collection<Node> nodes,
|
||||||
Collection<ContinuityArea> continuityAreas, Collection<Connection> connections) {
|
Collection<ContinuityArea> continuityAreas, Collection<Connection> connections) {
|
||||||
ImmutableGraph<ProjectGraphNode> graph = buildGraph(nodes, continuityAreas, connections);
|
ImmutableGraph<ProjectGraphNode> graph = buildGraph(nodes, continuityAreas, connections);
|
||||||
|
|||||||
@@ -172,10 +172,10 @@ public class Tree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String toAsciiString() {
|
public String toAsciiString() {
|
||||||
return String.join("<br>", toAscii());
|
return String.join("<br>", toAsciiLines());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> toAscii() {
|
private List<String> toAsciiLines() {
|
||||||
if (leaf != null) {
|
if (leaf != null) {
|
||||||
return Arrays.asList(TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH,
|
return Arrays.asList(TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH,
|
||||||
1) + " " + leaf.toHTML() + " " + TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, 1));
|
1) + " " + leaf.toHTML() + " " + TreeAsciiUtil.generateString(TreeAsciiUtil.BOXH, 1));
|
||||||
@@ -184,7 +184,7 @@ public class Tree {
|
|||||||
List<Tree> children = getOrderedChildren();
|
List<Tree> children = getOrderedChildren();
|
||||||
|
|
||||||
List<List<String>> childrenAscii =
|
List<List<String>> childrenAscii =
|
||||||
children.stream().map(c -> c.toAscii()).collect(Collectors.toList());
|
children.stream().map(c -> c.toAsciiLines()).collect(Collectors.toList());
|
||||||
|
|
||||||
if (TreeConnectionType.Series.equals(connectionType)) {
|
if (TreeConnectionType.Series.equals(connectionType)) {
|
||||||
return TreeAsciiUtil.concatenateMultiLineSerial(
|
return TreeAsciiUtil.concatenateMultiLineSerial(
|
||||||
|
|||||||
@@ -36,11 +36,7 @@ import org.apache.log4j.Logger;
|
|||||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||||
|
|
||||||
import org.diylc.clipboard.ComponentTransferable;
|
import org.diylc.clipboard.ComponentTransferable;
|
||||||
import org.diylc.common.ComponentType;
|
import org.diylc.common.*;
|
||||||
import org.diylc.common.IPlugInPort;
|
|
||||||
import org.diylc.common.Orientation;
|
|
||||||
import org.diylc.common.OrientationHV;
|
|
||||||
import org.diylc.common.PropertyWrapper;
|
|
||||||
import org.diylc.core.Angle;
|
import org.diylc.core.Angle;
|
||||||
import org.diylc.core.CreationMethod;
|
import org.diylc.core.CreationMethod;
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
@@ -437,6 +433,7 @@ public class InstantiationManager {
|
|||||||
for (PropertyWrapper propertyWrapper : properties) {
|
for (PropertyWrapper propertyWrapper : properties) {
|
||||||
if (propertyWrapper.getType().getName().equals(Orientation.class.getName())
|
if (propertyWrapper.getType().getName().equals(Orientation.class.getName())
|
||||||
|| propertyWrapper.getType().getName().equals(OrientationHV.class.getName())
|
|| propertyWrapper.getType().getName().equals(OrientationHV.class.getName())
|
||||||
|
|| propertyWrapper.getType().getName().equals(Orientation45.class.getName())
|
||||||
|| propertyWrapper.getName().equalsIgnoreCase("angle")) {
|
|| propertyWrapper.getName().equalsIgnoreCase("angle")) {
|
||||||
angleProperty = propertyWrapper;
|
angleProperty = propertyWrapper;
|
||||||
break;
|
break;
|
||||||
@@ -456,6 +453,9 @@ public class InstantiationManager {
|
|||||||
} else if (value instanceof OrientationHV) {
|
} else if (value instanceof OrientationHV) {
|
||||||
angleProperty.setValue(OrientationHV.values()[(((OrientationHV) value).ordinal() + 1)
|
angleProperty.setValue(OrientationHV.values()[(((OrientationHV) value).ordinal() + 1)
|
||||||
% OrientationHV.values().length]);
|
% OrientationHV.values().length]);
|
||||||
|
} else if (value instanceof Orientation45) {
|
||||||
|
angleProperty.setValue(Orientation45.values()[(((Orientation45) value).ordinal() + 1)
|
||||||
|
% Orientation45.values().length]);
|
||||||
} else if (value instanceof Angle) {
|
} else if (value instanceof Angle) {
|
||||||
Angle angle = (Angle) angleProperty.getValue();
|
Angle angle = (Angle) angleProperty.getValue();
|
||||||
Angle newAngle = angle.rotate(1);
|
Angle newAngle = angle.rotate(1);
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import java.io.File;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -50,7 +49,6 @@ import javax.swing.JOptionPane;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.diylc.appframework.miscutils.IConfigListener;
|
import org.diylc.appframework.miscutils.IConfigListener;
|
||||||
import org.diylc.appframework.miscutils.IConfigurationManager;
|
import org.diylc.appframework.miscutils.IConfigurationManager;
|
||||||
import org.diylc.appframework.miscutils.JarScanner;
|
|
||||||
import org.diylc.appframework.miscutils.Utils;
|
import org.diylc.appframework.miscutils.Utils;
|
||||||
import org.diylc.appframework.simplemq.MessageDispatcher;
|
import org.diylc.appframework.simplemq.MessageDispatcher;
|
||||||
import org.diylc.appframework.update.Version;
|
import org.diylc.appframework.update.Version;
|
||||||
@@ -88,7 +86,7 @@ import org.diylc.core.measures.SizeUnit;
|
|||||||
import org.diylc.lang.LangUtil;
|
import org.diylc.lang.LangUtil;
|
||||||
import org.diylc.netlist.INetlistParser;
|
import org.diylc.netlist.INetlistParser;
|
||||||
import org.diylc.netlist.Netlist;
|
import org.diylc.netlist.Netlist;
|
||||||
import org.diylc.netlist.NetlistAnalyzer;
|
import org.diylc.netlist.AbstractNetlistAnalyzer;
|
||||||
import org.diylc.netlist.NetlistBuilder;
|
import org.diylc.netlist.NetlistBuilder;
|
||||||
import org.diylc.netlist.NetlistException;
|
import org.diylc.netlist.NetlistException;
|
||||||
import org.diylc.serialization.ProjectFileManager;
|
import org.diylc.serialization.ProjectFileManager;
|
||||||
@@ -2030,7 +2028,7 @@ public class Presenter implements IPlugInPort, IConfigListener {
|
|||||||
if (netlists == null)
|
if (netlists == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<Set<IDIYComponent<?>>> allGroups = NetlistAnalyzer.extractComponentGroups(netlists);
|
List<Set<IDIYComponent<?>>> allGroups = AbstractNetlistAnalyzer.extractComponentGroups(netlists);
|
||||||
// Find control points of all selected components and all types
|
// Find control points of all selected components and all types
|
||||||
Set<String> selectedNamePrefixes = new HashSet<String>();
|
Set<String> selectedNamePrefixes = new HashSet<String>();
|
||||||
if (expansionMode == ExpansionMode.SAME_TYPE) {
|
if (expansionMode == ExpansionMode.SAME_TYPE) {
|
||||||
|
|||||||
@@ -56,4 +56,15 @@ public class TreeAsciiUtilTest {
|
|||||||
// assertEquals("yy-yyy", result.get(1));
|
// assertEquals("yy-yyy", result.get(1));
|
||||||
// assertEquals(" aaa", result.get(2));
|
// assertEquals(" aaa", result.get(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleParallel() {
|
||||||
|
List<String> result = TreeAsciiUtil.concatenateMultiLineParallel(
|
||||||
|
Arrays.asList(Arrays.asList("xx"), Arrays.asList("yy")));
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(3, result.size());
|
||||||
|
assertEquals(" ┌xx┐ ", result.get(0));
|
||||||
|
assertEquals("─┤ ├─", result.get(1));
|
||||||
|
assertEquals(" └yy┘ ", result.get(2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+243
@@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.diylc.components.connectivity;
|
||||||
|
|
||||||
|
import java.awt.AlphaComposite;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Composite;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Shape;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
|
||||||
|
import org.diylc.common.ObjectCache;
|
||||||
|
import org.diylc.common.Orientation45;
|
||||||
|
import org.diylc.components.AbstractTransparentComponent;
|
||||||
|
import org.diylc.components.transform.SimpleComponentTransformer;
|
||||||
|
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 = "Multimeter Probe", category = "Connectivity",
|
||||||
|
author = "Branislav Stojkovic", description = "Multimeter Probe", instanceNamePrefix = "Probe",
|
||||||
|
zOrder = IDIYComponent.TEXT, bomPolicy = BomPolicy.NEVER_SHOW, autoEdit = false,
|
||||||
|
keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME, transformer = SimpleComponentTransformer.class,
|
||||||
|
enableCache = true)
|
||||||
|
public class MultimeterProbe extends AbstractTransparentComponent<Color> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static Size PROBE_DIAMETER = new Size(0.05d, SizeUnit.in);
|
||||||
|
public static Size PROBE_LENGTH = new Size(0.4d, SizeUnit.in);
|
||||||
|
public static Color PROBE_COLOR = METAL_COLOR;
|
||||||
|
public static Size HANDLE_DIAMETER = new Size(0.2d, SizeUnit.in);
|
||||||
|
public static Size HANDLE_LENGTH = new Size(0.4d, SizeUnit.in);
|
||||||
|
public static Color HANDLE_COLOR = Color.red;
|
||||||
|
|
||||||
|
private Point2D.Double point = new Point2D.Double(0, 0);
|
||||||
|
private Color handleColor = HANDLE_COLOR;
|
||||||
|
private Orientation45 orientation = Orientation45._315;
|
||||||
|
|
||||||
|
private transient Shape[] body = null;
|
||||||
|
|
||||||
|
public MultimeterProbe() {
|
||||||
|
this.alpha = (byte) (MAX_ALPHA / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode,
|
||||||
|
Project project, IDrawingObserver drawingObserver) {
|
||||||
|
|
||||||
|
Shape[] shapes = getBody();
|
||||||
|
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1f));
|
||||||
|
|
||||||
|
if (!outlineMode) {
|
||||||
|
Composite oldComposite = g2d.getComposite();
|
||||||
|
if (alpha < MAX_ALPHA) {
|
||||||
|
g2d.setComposite(
|
||||||
|
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f * alpha / MAX_ALPHA));
|
||||||
|
}
|
||||||
|
g2d.setColor(PROBE_COLOR);
|
||||||
|
g2d.fill(shapes[0]);
|
||||||
|
g2d.setColor(handleColor);
|
||||||
|
g2d.fill(shapes[1]);
|
||||||
|
g2d.setComposite(oldComposite);
|
||||||
|
}
|
||||||
|
g2d.setColor(
|
||||||
|
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||||
|
? SELECTION_COLOR
|
||||||
|
: handleColor.darker());
|
||||||
|
g2d.draw(shapes[1]);
|
||||||
|
g2d.setColor(
|
||||||
|
componentState == ComponentState.SELECTED || componentState == ComponentState.DRAGGING
|
||||||
|
? SELECTION_COLOR
|
||||||
|
: PROBE_COLOR.darker());
|
||||||
|
g2d.draw(shapes[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||||
|
double probeDiameter = 2;
|
||||||
|
double probeLength = height / 2 + 2;
|
||||||
|
double handleDiameter = width / 4;
|
||||||
|
double handleLength = height / 2 + 2;
|
||||||
|
double x = 2;
|
||||||
|
double y = height - 2;
|
||||||
|
Shape probe = buildProbeShape(probeDiameter, probeLength, x, y);
|
||||||
|
Shape handle = buildHandleShape(probeDiameter, probeLength, handleDiameter, handleLength, x, y);
|
||||||
|
|
||||||
|
double theta = Math.PI / 4;
|
||||||
|
AffineTransform tx = AffineTransform.getRotateInstance(theta, x, y);
|
||||||
|
probe = tx.createTransformedShape(probe);
|
||||||
|
handle = tx.createTransformedShape(handle);
|
||||||
|
|
||||||
|
g2d.setColor(PROBE_COLOR);
|
||||||
|
g2d.fill(probe);
|
||||||
|
g2d.setColor(HANDLE_COLOR);
|
||||||
|
g2d.fill(handle);
|
||||||
|
|
||||||
|
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1));
|
||||||
|
g2d.setColor(PROBE_COLOR.darker());
|
||||||
|
g2d.draw(probe);
|
||||||
|
g2d.setColor(HANDLE_COLOR.darker());
|
||||||
|
g2d.draw(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shape[] getBody() {
|
||||||
|
if (body == null) {
|
||||||
|
double probeDiameter = PROBE_DIAMETER.convertToPixels();
|
||||||
|
double probeLength = PROBE_LENGTH.convertToPixels();
|
||||||
|
double handleDiameter = HANDLE_DIAMETER.convertToPixels();
|
||||||
|
double handleLength = HANDLE_LENGTH.convertToPixels();
|
||||||
|
double x = point.getX();
|
||||||
|
double y = point.getY();
|
||||||
|
body = new Shape[2];
|
||||||
|
Path2D probe = buildProbeShape(probeDiameter, probeLength, x, y);
|
||||||
|
body[0] = probe;
|
||||||
|
Path2D handle =
|
||||||
|
buildHandleShape(probeDiameter, probeLength, handleDiameter, handleLength, x, y);
|
||||||
|
body[1] = handle;
|
||||||
|
|
||||||
|
double theta = orientation.toRadians();
|
||||||
|
if (theta != 0) {
|
||||||
|
AffineTransform tx = AffineTransform.getRotateInstance(theta, x, y);
|
||||||
|
body[0] = tx.createTransformedShape(body[0]);
|
||||||
|
body[1] = tx.createTransformedShape(body[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path2D buildHandleShape(double probeDiameter, double probeLength, double handleDiameter,
|
||||||
|
double handleLength, double x, double y) {
|
||||||
|
Path2D handle = new Path2D.Double();
|
||||||
|
handle.moveTo(x + probeDiameter, y - probeLength);
|
||||||
|
handle.lineTo(x + handleDiameter / 2, y - handleLength - probeLength);
|
||||||
|
handle.lineTo(x - handleDiameter / 2, y - handleLength - probeLength);
|
||||||
|
handle.lineTo(x - probeDiameter, y - probeLength);
|
||||||
|
handle.moveTo(x + probeDiameter, y - probeLength);
|
||||||
|
handle.closePath();
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path2D buildProbeShape(double probeDiameter, double probeLength, double x, double y) {
|
||||||
|
Path2D probe = new Path2D.Double();
|
||||||
|
probe.moveTo(x, y);
|
||||||
|
probe.lineTo(x - probeDiameter / 2, y - probeDiameter);
|
||||||
|
probe.lineTo(x - probeDiameter / 2, y - probeLength);
|
||||||
|
probe.lineTo(x + probeDiameter / 2, y - probeLength);
|
||||||
|
probe.lineTo(x + probeDiameter / 2, y - probeDiameter);
|
||||||
|
probe.lineTo(x, y);
|
||||||
|
probe.closePath();
|
||||||
|
return probe;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getControlPointCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isControlPointSticky(int index) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VisibilityPolicy getControlPointVisibilityPolicy(int index) {
|
||||||
|
return VisibilityPolicy.NEVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Point2D getControlPoint(int index) {
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setControlPoint(Point2D point, int index) {
|
||||||
|
this.point.setLocation(point);
|
||||||
|
this.body = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@EditableProperty(name = "Color")
|
||||||
|
public Color getValue() {
|
||||||
|
return handleColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(Color color) {
|
||||||
|
this.handleColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EditableProperty(name = "Angle")
|
||||||
|
public Orientation45 getOrientation() {
|
||||||
|
return orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOrientation(Orientation45 orientation) {
|
||||||
|
this.orientation = orientation;
|
||||||
|
this.body = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getControlPointNodeName(int index) {
|
||||||
|
return "Tip";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rectangle2D getCachingBounds() {
|
||||||
|
Shape[] shapes = getBody();
|
||||||
|
Rectangle2D bounds1 = shapes[0].getBounds2D();
|
||||||
|
Rectangle2D bounds2 = shapes[1].getBounds2D();
|
||||||
|
double minX = Math.min(bounds1.getMinX(), bounds2.getMinX());
|
||||||
|
double minY = Math.min(bounds1.getMinY(), bounds2.getMinY());
|
||||||
|
double maxX = Math.max(bounds1.getMaxX(), bounds2.getMaxX());
|
||||||
|
double maxY = Math.max(bounds1.getMaxY(), bounds2.getMaxY());
|
||||||
|
return new Rectangle2D.Double(minX - 1, minY - 1, maxX - minX + 2, maxY - minY + 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,17 +46,9 @@ import org.diylc.components.passive.RadialFilmCapacitor;
|
|||||||
import org.diylc.components.passive.RadialMicaCapacitor;
|
import org.diylc.components.passive.RadialMicaCapacitor;
|
||||||
import org.diylc.components.passive.Resistor;
|
import org.diylc.components.passive.Resistor;
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
import org.diylc.netlist.Netlist;
|
|
||||||
import org.diylc.netlist.NetlistAnalyzer;
|
|
||||||
import org.diylc.netlist.Node;
|
|
||||||
import org.diylc.netlist.Summary;
|
|
||||||
import org.diylc.netlist.Tree;
|
|
||||||
import org.diylc.netlist.TreeConnectionType;
|
|
||||||
import org.diylc.netlist.TreeException;
|
|
||||||
import org.diylc.netlist.TreeLeaf;
|
|
||||||
import org.diylc.netlist.Tree.ITreeWalker;
|
import org.diylc.netlist.Tree.ITreeWalker;
|
||||||
|
|
||||||
public class GuitarDiagramAnalyzer extends NetlistAnalyzer implements INetlistAnalyzer {
|
public class GuitarDiagramAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer {
|
||||||
|
|
||||||
private static Set<String> JACK_TYPES = new HashSet<String>();
|
private static Set<String> JACK_TYPES = new HashSet<String>();
|
||||||
private static Set<String> POT_TYPES = new HashSet<String>();
|
private static Set<String> POT_TYPES = new HashSet<String>();
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.diylc.netlist;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import org.diylc.common.INetlistAnalyzer;
|
||||||
|
import org.diylc.components.connectivity.MultimeterProbe;
|
||||||
|
|
||||||
|
public class MultimeterAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Virtual Multimeter";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getShortName() {
|
||||||
|
return "multimeter";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIconName() {
|
||||||
|
return "Multimeter";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFontName() {
|
||||||
|
return new JLabel().getFont().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Summary summarize(Netlist netlist, Node preferredOutput) throws TreeException {
|
||||||
|
Tree tree = constructTree(netlist);
|
||||||
|
|
||||||
|
if (tree == null) {
|
||||||
|
return new Summary(netlist, "No components found connecting the two multimeter probes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> notes = new ArrayList<String>();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
String asciiTree = tree.toAsciiString();
|
||||||
|
|
||||||
|
sb.append("<br><br>")
|
||||||
|
.append("<font face='Courier New'>")
|
||||||
|
.append(asciiTree)
|
||||||
|
.append("</font>");
|
||||||
|
if (!notes.isEmpty()) {
|
||||||
|
Collections.sort(notes);
|
||||||
|
sb.append("<br><br>");
|
||||||
|
for (String v : notes) {
|
||||||
|
sb.append(v).append("<br>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Summary(netlist, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tree constructTree(Netlist netlist) throws TreeException {
|
||||||
|
List<Node> probeNodes = find(Set.of(MultimeterProbe.class.getCanonicalName()), null, netlist);
|
||||||
|
|
||||||
|
if (probeNodes.isEmpty()) {
|
||||||
|
throw new TreeException("No multimeter probes are placed on the circuit.");
|
||||||
|
} else if (probeNodes.size() != 2) {
|
||||||
|
throw new TreeException(
|
||||||
|
"Place exactly two multimeter probes on the circuit in order to run the analysis.");
|
||||||
|
} else {
|
||||||
|
return constructTreeBetween(netlist, probeNodes.get(0), probeNodes.get(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,14 +27,8 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import org.diylc.common.INetlistAnalyzer;
|
import org.diylc.common.INetlistAnalyzer;
|
||||||
import org.diylc.core.IDIYComponent;
|
import org.diylc.core.IDIYComponent;
|
||||||
import org.diylc.netlist.Group;
|
|
||||||
import org.diylc.netlist.Netlist;
|
|
||||||
import org.diylc.netlist.NetlistAnalyzer;
|
|
||||||
import org.diylc.netlist.Node;
|
|
||||||
import org.diylc.netlist.Summary;
|
|
||||||
import org.diylc.netlist.TreeException;
|
|
||||||
|
|
||||||
public class SpiceAnalyzer extends NetlistAnalyzer implements INetlistAnalyzer {
|
public class SpiceAnalyzer extends AbstractNetlistAnalyzer implements INetlistAnalyzer {
|
||||||
|
|
||||||
public SpiceAnalyzer() {
|
public SpiceAnalyzer() {
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ import org.diylc.netlist.Netlist;
|
|||||||
import org.diylc.netlist.Tree;
|
import org.diylc.netlist.Tree;
|
||||||
import org.diylc.netlist.TreeException;
|
import org.diylc.netlist.TreeException;
|
||||||
|
|
||||||
public class GuitarNetlistAnalyzerTests {
|
public class GuitarAbstractNetlistAnalyzerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOneSinglePickup() throws TreeException {
|
public void testOneSinglePickup() throws TreeException {
|
||||||
@@ -71,7 +71,7 @@ public enum IconLoader {
|
|||||||
SnapToComponents("snap_to_components.png"), SnapToNone("snap_to_none.png"), TraceProximity("trace_proximity.png"),
|
SnapToComponents("snap_to_components.png"), SnapToNone("snap_to_none.png"), TraceProximity("trace_proximity.png"),
|
||||||
ComponentLarge("component_large.png"), ImportNetlist("import_netlist.png"), SplashIC("splash_ic.png"),
|
ComponentLarge("component_large.png"), ImportNetlist("import_netlist.png"), SplashIC("splash_ic.png"),
|
||||||
ComponentPreferences("component_preferences.png"), ComponentReplace("component_replace.png"), Barcode("barcode.png"),
|
ComponentPreferences("component_preferences.png"), ComponentReplace("component_replace.png"), Barcode("barcode.png"),
|
||||||
DocumentGerber("document_gerber.png"), DocumentX2("document_x2.png"), Export("export.png");
|
DocumentGerber("document_gerber.png"), DocumentX2("document_x2.png"), Export("export.png"), Multimeter("multimeter.png");
|
||||||
|
|
||||||
protected String name;
|
protected String name;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 864 B |
Reference in New Issue
Block a user