📄 clickzoomwirelistener.java
字号:
text.add("...too many to display"); break; } if (obj instanceof PortInst) { // only give option to connect to ports PortInst pi = (PortInst)obj; String str = "("+num+"): Port "+pi.getPortProto().getName()+" on "+pi.getNodeInst().getName(); text.add(str); portList.add(pi); num++; } } if (num > 2) { // only show if more than one port to connect to under mouse wnd.setShowPopupCloud(text, new Point2D.Double(mouseX, mouseY)); wiringPopupCloudUp = true; wiringPopupCloudList = portList; wiringLastDBMouse = dbMouse; } } */ } if (modeRight == Mode.wiringConnect) { EditWindow.gridAlign(dbMouse); User.getUserTool().setCurrentArcProto(currentArcWhenWiringPressed); router.highlightRoute(wnd, cell, startObj, endObj, dbMouse); } if (modeRight == Mode.wiringToSpace) { // wire only to point in space EditWindow.gridAlign(dbMouse); User.getUserTool().setCurrentArcProto(currentArcWhenWiringPressed); router.highlightRoute(wnd, cell, startObj, null, dbMouse); } } // ===== Left mouse drags ===== if (isLeftMouse(evt)) { if (modeLeft == Mode.selectBox || modeLeft == Mode.drawBox || modeLeft == Mode.zoomBoxSingleShot) { // select objects in box wnd.setEndDrag(mouseX, mouseY); wnd.repaint(); } if (modeLeft == Mode.move || modeLeft == Mode.stickyMove) { // moving objects // if CTRL held, can only move orthogonally if (another) dbMouse = convertToOrthogonal(new Point2D.Double(dbMoveStartX, dbMoveStartY), dbMouse); // relocate highlight to under mouse Point2D dbDelta = new Point2D.Double(dbMouse.getX() - dbMoveStartX, dbMouse.getY() - dbMoveStartY); EditWindow.gridAlign(dbDelta); // align to grid Point2D screenDelta = wnd.deltaDatabaseToScreen(dbDelta.getX(), dbDelta.getY()); highlighter.setHighlightOffset((int)screenDelta.getX(), (int)screenDelta.getY()); // detect worst design-rule violation if moving just one object WorstSpacing ws = new WorstSpacing(); List<Geometric> selected = highlighter.getHighlightedEObjs(true, true); if (DRC.isInteractiveDRCDragOn() && selected.size() == 1) { Geometric g = selected.get(0); Netlist nl = g.getParent().acquireUserNetlist(); if (g instanceof ArcInst) { ArcInst ai = (ArcInst)g; Network net = nl.getNetwork(ai, 0); if (net != null) { Poly [] polys = ai.getProto().getTechnology().getShapeOfArc(ai); for(int i=0; i<polys.length; i++) ws.findWorstSpacing(g, polys[i], net, dbDelta, nl); } } else { NodeInst ni = (NodeInst)g; if (!ni.isCellInstance()) { AffineTransform trans = ni.rotateOut(); Poly [] polys = ni.getProto().getTechnology().getShapeOfNode(ni, true, true, null); for(int i=0; i<polys.length; i++) { PortProto pp = polys[i].getPort(); if (pp == null) continue; PortInst pi = ni.findPortInstFromProto(pp); if (pi == null) continue; Network net = nl.getNetwork(pi); if (net == null) continue; polys[i].transform(trans); ws.findWorstSpacing(g, polys[i], net, dbDelta, nl); } } } } // display DRC if known, otherwise distance moved if (moveDelta != null) highlighter.remove(moveDelta); if (moveDRC != null) highlighter.remove(moveDRC); String deltaMessage = "Moved (" + TextUtils.formatDouble(dbDelta.getX()) + "," + TextUtils.formatDouble(dbDelta.getY()) + ")"; WindowFrame wf = WindowFrame.getCurrentWindowFrame(); StatusBar.setCoordinates(deltaMessage, wf); if (ws.validSpacing()) { // display worst design rule violation boolean tooClose = ws.getSeparation() < ws.getMinSpacing(); String message = ws.getOneLayer().getName(); if (ws.getOneLayer() != ws.getOtherLayer()) message += " to " + ws.getOtherLayer().getName(); message += " spacing is " + TextUtils.formatDouble(ws.getSeparation()); if (tooClose) message = "ERROR! " + message + " MINIMUM IS " + TextUtils.formatDouble(ws.getMinSpacing()); // compute upper-left corner of moved object and place text there Geometric g = selected.get(0); Poly hPoly; if (g instanceof NodeInst) { hPoly = Highlight2.getNodeInstOutline((NodeInst)g); } else { ArcInst ai = (ArcInst)g; hPoly = ai.makeLambdaPoly(ai.getGridBaseWidth(), Poly.Type.CLOSED); } double minX = 0, maxY = 0; Point2D[] points = hPoly.getPoints(); for(int i=0; i<points.length; i++) { if (i == 0 || points[i].getX() < minX) minX = points[i].getX(); if (i == 0 || points[i].getY() > maxY) maxY = points[i].getY(); } moveDelta = highlighter.addMessage(cell, message, new Point2D.Double(minX + dbDelta.getX(), maxY + dbDelta.getY())); Point2D end1 = new Point2D.Double(ws.getOnePoint().getX() - dbDelta.getX(), ws.getOnePoint().getY() - dbDelta.getY()); Point2D end2 = new Point2D.Double(ws.getOtherPoint().getX() - dbDelta.getX(), ws.getOtherPoint().getY() - dbDelta.getY()); moveDRC = highlighter.addLine(end1, end2, cell, tooClose); } wnd.repaint(); } } if (isMiddleMouse(evt)) { // Continue panning the screen int newX = evt.getX(); int newY = evt.getY(); Point2D pt = wnd.getScheduledOffset(); double scale = wnd.getScale(); wnd.setOffset(new Point2D.Double(pt.getX() - (newX - lastX) / scale, pt.getY() + (newY - lastY) / scale)); wnd.getSavedFocusBrowser().updateCurrentFocus(); wnd.fullRepaint(); lastX = newX; lastY = newY; return; } wnd.repaint(); } } /** * Class to detect the worst design-rule violation while moving a node or arc. */ private static class WorstSpacing { private boolean valid; private double separation; private double worstViolation; private double minSpacing; private Point2D worstFrom, worstTo; private Layer layerFrom, layerTo; public WorstSpacing() { valid = false; worstFrom = new Point2D.Double(0, 0); worstTo = new Point2D.Double(0, 0); } public boolean validSpacing() { return valid; } public double getSeparation() { return separation; } public double getMinSpacing() { return minSpacing; } public Layer getOneLayer() { return layerFrom; } public Layer getOtherLayer() { return layerTo; } public Point2D getOnePoint() { return worstFrom; } public Point2D getOtherPoint() { return worstTo; } /** * Method to update this WorstSpacing object according to a polygon on a Geometric. * @param self the Geometric being examined. * @param poly the Poly on the Geometric. * @param net the Network connected to the polygon. * @param delta the offset that is being applied to the polygon (how much it has been dragged). * @param nl the Netlist for the cell. */ public void findWorstSpacing(Geometric self, Poly poly, Network net, Point2D delta, Netlist nl) { // ignore null layers Layer lay = poly.getLayer(); if (lay == null) return; if (lay.isPseudoLayer()) return; if (lay.getFunction().isSubstrate()) return; // move the polygon by the dragged amount Point2D [] points = poly.getPoints(); for(int j=0; j<points.length; j++) poly.setPoint(j, points[j].getX() + delta.getX(), points[j].getY() + delta.getY()); // find simplest rule for this layer to itself Rectangle2D bounds = poly.getBounds2D(); double xS = bounds.getWidth(); double yS = bounds.getHeight(); double widRule = Math.min(xS, yS); double lenRule = Math.max(xS, yS); int multiCut = -1; double surround = DRC.getMaxSurround(lay, Double.MAX_VALUE); // search up to 5 times the design-rule distance away double worstInteractionDistance = surround * 5; Rectangle2D searchBounds = new Rectangle2D.Double( bounds.getMinX()-worstInteractionDistance, bounds.getMinY()-worstInteractionDistance, bounds.getWidth() + worstInteractionDistance*2, bounds.getHeight() + worstInteractionDistance*2); for(Iterator<RTBounds> it = self.getParent().searchIterator(searchBounds); it.hasNext(); ) { Geometric neighbor = (Geometric)it.next(); if (neighbor == self) continue; if (neighbor instanceof NodeInst) { NodeInst otherNi = (NodeInst)neighbor; if (otherNi.isCellInstance()) continue; AffineTransform trans = otherNi.rotateOut(); Poly [] otherPolys = otherNi.getProto().getTechnology().getShapeOfNode(otherNi, true, true, null); for(int i=0; i<otherPolys.length; i++) { Poly otherPoly = otherPolys[i]; Layer otherLay = otherPoly.getLayer(); if (otherLay == null) continue; if (otherLay.isPseudoLayer()) continue; if (otherLay.getFunction().isSubstrate()) continue; if (lay.getTechnology() != otherLay.getTechnology()) continue; PortProto pp = otherPoly.getPort(); if (pp == null) continue; PortInst pi = otherNi.findPortInstFromProto(pp); if (pi == null) continue; Network otherNet = nl.getNetwork(pi); if (otherNet == null) continue; if (net == otherNet) continue; DRCTemplate rule = DRC.getSpacingRule(lay, null, otherLay, null, false, multiCut, widRule, lenRule); if (rule == null) continue; double dist = rule.getValue(0); otherPoly.transform(trans); double sep = poly.separation(otherPoly); if (valid && sep-dist >= worstViolation) continue; // this is a better spacing valid = true; worstViolation = sep-dist; separation = sep; minSpacing = dist; layerFrom = lay; layerTo = otherLay; findClosestPoints(poly, otherPoly); } } else { ArcInst otherAi = (ArcInst)neighbor; Network otherNet = nl.getNetwork(otherAi, 0); if (otherNet == null) continue; if (net == otherNet) continue; Poly [] otherPolys = otherAi.getProto().getTechnology().getShapeOfArc(otherAi); for(int i=0; i<otherPolys.length; i++) { Poly otherPoly = otherPolys[i]; Layer otherLay = otherPoly.getLayer(); if (otherLay == null) continue; if (otherLay.isPseudoLayer()) continue; if (otherLay.getFunction().isSubstrate()) continue; DRCTemplate rule = DRC.getSpacingRule(lay, null, otherLay, null, true, multiCut, widRule, lenRule); if (rule == null) continue; double dist = rule.getValue(0); double sep = poly.separation(otherPoly); if (valid && sep-dist >= worstViolation) continue; // this is a better spacing valid = true; worstViolation = sep-dist; separation = sep; minSpacing = dist; layerFrom = lay; layerTo = otherLay; findClosestPoints(poly, otherPoly); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -