📄 circuitchangejobs.java
字号:
ArcInst ai = (ArcInst)geom; if (!ai.isLinked()) continue; Point2D origHead = ai.getHeadLocation(); Point2D origTail = ai.getTailLocation(); Point2D arcHead = new Point2D.Double(origHead.getX(), origHead.getY()); Point2D arcTail = new Point2D.Double(origTail.getX(), origTail.getY()); DBMath.gridAlign(arcHead, alignment); DBMath.gridAlign(arcTail, alignment); double headXOff = arcHead.getX() - origHead.getX(); double headYOff = arcHead.getY() - origHead.getY(); double tailXOff = arcTail.getX() - origTail.getX(); double tailYOff = arcTail.getY() - origTail.getY(); if (headXOff == 0 && tailXOff == 0 && headYOff == 0 && tailYOff == 0) continue; if (!ai.headStillInPort(arcHead, false)) { if (!ai.headStillInPort(origHead, false)) continue; headXOff = headYOff = 0; } if (!ai.tailStillInPort(arcTail, false)) { if (!ai.tailStillInPort(origTail, false)) continue; tailXOff = tailYOff = 0; } // make sure an arc does not change angle int ang = ai.getAngle(); if (ang == 0 || ang == 1800) { // horizontal arc: both DY values must be the same if (headYOff != tailYOff) headYOff = tailYOff = 0; } else if (ang == 900 || ang == 2700) { // vertical arc: both DX values must be the same if (headXOff != tailXOff) headXOff = tailXOff = 0; } if (headXOff != 0 || tailXOff != 0 || headYOff != 0 || tailYOff != 0) { int constr = 0; if (ai.isRigid()) constr |= 1; if (ai.isFixedAngle()) constr |= 2; ai.setRigid(false); ai.setFixedAngle(false); ai.modify(headXOff, headYOff, tailXOff, tailYOff); adjustedArcs++; if ((constr & 1) != 0) ai.setRigid(true); if ((constr & 2) != 0) ai.setFixedAngle(true); } } // show results if (adjustedNodes == 0 && adjustedArcs == 0) System.out.println("No adjustments necessary"); else System.out.println("Adjusted " + adjustedNodes + " nodes and " + adjustedArcs + " arcs"); return true; } } public static class AlignNodes extends Job { private NodeInst [] nis; private double [] dCX; private double [] dCY; public AlignNodes(NodeInst [] nis, double [] dCX, double [] dCY) { super("Align objects", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.nis = nis; this.dCX = dCX; this.dCY = dCY; startJob(); } public boolean doIt() throws JobException { int numRemoved = 0; for(int i=0; i<nis.length; i++) { NodeInst ni = nis[i]; int res = cantEdit(ni.getParent(), ni, true, false, true); if (res < 0) return false; if (res > 0) { numRemoved++; nis[i] = null; } } if (numRemoved > 0) { // make a smaller list int newSize = nis.length - numRemoved; if (newSize == 0) return true; NodeInst [] nnis = new NodeInst[newSize]; double [] nCX = new double[newSize]; double [] nCY = new double[newSize]; int fill = 0; for(int i=0; i<nis.length; i++) { if (nis[i] == null) continue; nnis[fill] = nis[i]; nCX[fill] = dCX[i]; nCY[fill] = dCY[i]; fill++; } nis = nnis; dCX = nCX; dCY = nCY; } NodeInst.modifyInstances(nis, dCX, dCY, null, null); return true; } } /****************************** ARC MODIFICATION ******************************/ public enum ChangeArcEnum { RIGID("Rigid"), NONRIGID("Non-Rigid"), FIXEDANGLE("Fixed-Angle"), NONFIXEDANGLE("Not-Fixed-Angle"), DIRECTIONAL("Directional"), HEADEXTEND("extend the head end"), TAILEXTEND("extend the tail end"); private String name; ChangeArcEnum(String n) { name = n; } public String toString() { return name; } } public static class ChangeArcProperties extends Job { private Cell cell; private ChangeArcEnum how; private List<ElectricObject> objList; private boolean repaintContents, repaintAny; public ChangeArcProperties(Cell cell, ChangeArcEnum how, List<Highlight2> highlighted) { super("Align objects", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.cell = cell; this.how = how; this.objList = new ArrayList<ElectricObject>(); for(Highlight2 h : highlighted) { if (!h.isHighlightEOBJ()) continue; objList.add(h.getElectricObject()); } startJob(); } public boolean doIt() throws JobException { // make sure changing arcs is allowed if (CircuitChangeJobs.cantEdit(cell, null, true, false, true) != 0) return false; int numSet = 0, numUnset = 0; for(ElectricObject eobj : objList) { if (eobj instanceof ArcInst) { ArcInst ai = (ArcInst)eobj; switch (how) { case RIGID: if (!ai.isRigid()) { ai.setRigid(true); numSet++; } break; case NONRIGID: if (ai.isRigid()) { ai.setRigid(false); numSet++; } break; case FIXEDANGLE: if (!ai.isFixedAngle()) { ai.setFixedAngle(true); numSet++; } break; case NONFIXEDANGLE: if (ai.isFixedAngle()) { ai.setFixedAngle(false); numSet++; } break; case DIRECTIONAL: // toggle directionality if (ai.isHeadArrowed()) { ai.setHeadArrowed(false); ai.setBodyArrowed(false); numUnset++; } else { ai.setHeadArrowed(true); ai.setBodyArrowed(true); numSet++; } break; case HEADEXTEND: // end-extend the head if (ai.isHeadExtended()) { ai.setHeadExtended(false); numUnset++; } else { ai.setHeadExtended(true); numSet++; } break; case TAILEXTEND: // end-extend the tail if (ai.isTailExtended()) { ai.setTailExtended(false); numUnset++; } else { ai.setTailExtended(true); numSet++; } break; } } } repaintAny = false; if (numSet == 0 && numUnset == 0) System.out.println("No changes were made"); else { String action = ""; repaintAny = true; repaintContents = false; action = how.toString(); switch (how) { case DIRECTIONAL: case HEADEXTEND: case TAILEXTEND: repaintContents = true; break; } if (numUnset == 0) System.out.println("Made " + numSet + " arcs " + action); else if (numSet == 0) System.out.println("Made " + numUnset + " arcs not " + action); else System.out.println("Made " + numSet + " arcs " + action + "; and " + numUnset + " arcs not " + action); } fieldVariableChanged("repaintAny"); fieldVariableChanged("repaintContents"); return true; } public void terminateOK() { if (repaintAny) { if (repaintContents) EditWindow.repaintAllContents(); else EditWindow.repaintAll(); } } } public static class ToggleNegationJob extends Job { private Cell cell; private List<ElectricObject> highlighted; // Can't use Highlight2 since it is not serializable private int numSet; public ToggleNegationJob(Cell cell, List<Highlight2> highlighted) { super("Toggle negation", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.cell = cell; this.highlighted = new ArrayList<ElectricObject>(); for(Highlight2 h : highlighted) { if (!h.isHighlightEOBJ()) continue; this.highlighted.add(h.getElectricObject()); } startJob(); } public boolean doIt() throws JobException { // make sure negation is allowed if (cantEdit(cell, null, true, false, true) != 0) return false; numSet = 0; for(ElectricObject eobj : highlighted) { if (eobj instanceof PortInst) { PortInst pi = (PortInst)eobj; for(Iterator<Connection> cIt = pi.getConnections(); cIt.hasNext(); ) { Connection con = cIt.next(); con.setNegated(!con.isNegated()); } } if (eobj instanceof ArcInst) { ArcInst ai = (ArcInst)eobj; for(int i=0; i<2; i++) { ai.setNegated(i, !ai.isNegated((i))); } } } fieldVariableChanged("numSet"); if (numSet == 0) System.out.println("No ports negated"); else { System.out.println("Negated " + numSet + " ports"); } return true; } public void terminateOK() { if (numSet != 0) { EditWindow.repaintAllContents(); } } } public static class RipTheBus extends Job { private Cell cell; private List<ArcInst> list; public RipTheBus(Cell cell, List<ArcInst> list) { super("Rip Bus", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.cell = cell; this.list = list; startJob(); } public boolean doIt() throws JobException { // make sure ripping arcs is allowed if (cantEdit(cell, null, true, false, true) != 0) return false; for(ArcInst ai : list) { if (ai.getProto() != Schematics.tech().bus_arc) continue; Netlist netList = ai.getParent().acquireUserNetlist(); if (netList == null) { System.out.println("Sorry, a deadlock aborted bus ripping (network information unavailable). Please try again"); break; } int busWidth = netList.getBusWidth(ai); String netName = netList.getNetworkName(ai); if (netName.length() == 0) { System.out.println("Bus " + ai.describe(true) + " has no name"); continue; } // determine length of stub wires double stublen = (int)(ai.getLambdaLength() / 3 + 0.5); double lowXBus = 0, lowYBus = 0; int lowEnd = 1; double sepX = 0, sepY = 0; double lowX = 0, lowY = 0; // determine location of individual signals if (ai.getHeadLocation().getX() == ai.getTailLocation().getX()) { lowX = ai.getHeadLocation().getX(); if (lowX < ai.getParent().getBounds().getCenterX()) lowX += stublen; else lowX -= stublen; if (ai.getLocation(0).getY() < ai.getLocation(1).getY()) lowEnd = 0; lowY = (int)(ai.getLocation(lowEnd).getY()); double highy = (int)(ai.getLocation(1-lowEnd).getY()); if (highy-lowY >= busWidth-1) { // signals fit on grid sepY = (int)((highy-lowY) / (busWidth-1)); lowY = (int)(((highy - lowY) - (sepY * (busWidth-1))) / 2 + lowY); } else { // signals don't fit: just make them even lowY = ai.getLocation(lowEnd).getY(); highy = ai.getLocation(1-lowEnd).getY(); sepY = (highy-lowY) / (busWidth-1); } lowXBus = ai.getTailLocation().getX(); lowYBus = lowY; } else if (ai.getTailLocation().getY() == ai.getHeadLocation().getY()) { lowY = ai.getTailLocation().getY(); if (lowY < ai.getParent().getBounds().getCenterY()) lowY += stublen; else lowY -= stublen; if (ai.getLocation(0).getX() < ai.getLocation(1).getX()) lowEnd = 0; lowX = (int)(ai.getLocation(lowEnd).getX()); double highx = (int)(ai.getLocation(1-lowEnd).getX()); if (highx-lowX >= busWidth-1) { // signals fit on grid sepX = (int)((highx-lowX) / (busWidth-1)); lowX = (int)(((highx - lowX) - (sepX * (busWidth-1))) / 2 + lowX); } else { // signals don't fit: just make them even lowX = ai.getLocation(lowEnd).getX(); highx = ai.getLocation(1-lowEnd).getX(); sepX = (highx-lowX) / (busWidth-1); } lowXBus = lowX; lowYBus = ai.getTailLocation().getY(); } else { System.out.println("Bus " + ai.describe(true) + " must be horizontal or vertical to be ripped out");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -