📄 sizelistener.java
字号:
public void mouseDragged(MouseEvent evt) { showHighlight(evt, (EditWindow)evt.getSource()); } public void mouseReleased(MouseEvent evt) { // restore the listener to the former state EditWindow wnd = (EditWindow)evt.getSource(); restoringOriginalSetup(wnd); // Checking the element hasn't been removed assert(stretchGeom.isLinked()); // handle scaling the selected objects if (stretchGeom instanceof NodeInst) { NodeInst ni = (NodeInst)stretchGeom; Point2D newCenter = new Point2D.Double(ni.getAnchorCenterX(), ni.getAnchorCenterY()); Point2D newSize = getNewNodeSize(evt, newCenter); new ScaleNode(ni, new EPoint(newCenter.getX(), newCenter.getY()), newSize.getX(), newSize.getY()); } else { ArcInst ai = (ArcInst)stretchGeom; double newLambdaBaseWidth = getNewArcSize(evt); new ScaleArc(ai, newLambdaBaseWidth); } wnd.repaint(); } private void restoringOriginalSetup(EditWindow wnd) { // restore the listener to the former state WindowFrame.setListener(oldListener); TopLevel.setCurrentCursor(oldCursor); if (wnd != null) showHighlight(null, wnd); } public void keyPressed(KeyEvent evt) { int chr = evt.getKeyCode(); EditWindow wnd = (EditWindow)evt.getSource(); Cell cell = wnd.getCell(); if (cell == null) return; // ESCAPE for abort if (chr == KeyEvent.VK_ESCAPE) { restoringOriginalSetup(wnd); System.out.println("Sizing aborted"); } } public void mouseClicked(MouseEvent evt) {} public void mouseEntered(MouseEvent evt) {} public void mouseExited(MouseEvent evt) {} public void mouseWheelMoved(MouseWheelEvent evt) {} public void keyReleased(KeyEvent evt) {} public void keyTyped(KeyEvent evt) {} private void showHighlight(MouseEvent evt, EditWindow wnd) { Highlighter highlighter = wnd.getHighlighter(); highlighter.clear(); highlighter.addElectricObject(stretchGeom, stretchGeom.getParent()); highlighter.finished(); if (evt != null) { if (stretchGeom instanceof NodeInst) { NodeInst ni = (NodeInst)stretchGeom; Point2D newCenter = new Point2D.Double(ni.getAnchorCenterX(), ni.getAnchorCenterY()); Point2D newSize = getNewNodeSize(evt, newCenter); Poly stretchedPoly = ni.getBaseShape(EPoint.snap(newCenter), newSize.getX(), newSize.getY()); Point2D [] stretchedPoints = stretchedPoly.getPoints(); for(int i=0; i<stretchedPoints.length; i++) { int lastI = i - 1; if (lastI < 0) lastI = stretchedPoints.length - 1; highlighter.addLine(stretchedPoints[lastI], stretchedPoints[i], ni.getParent()); } } else { // construct the polygons that describe the basic arc long newGridWidth = DBMath.lambdaToSizeGrid(getNewArcSize(evt)); ArcInst ai = (ArcInst)stretchGeom; Poly stretchedPoly = ai.makeLambdaPoly(newGridWidth, Poly.Type.CLOSED); if (stretchedPoly == null) return; Point2D [] stretchedPoints = stretchedPoly.getPoints(); for(int i=0; i<stretchedPoints.length; i++) { int lastI = i - 1; if (lastI < 0) lastI = stretchedPoints.length - 1; highlighter.addLine(stretchedPoints[lastI], stretchedPoints[i], ai.getParent()); } } wnd.repaint(); } } /** * Method to determine the proper size for the NodeInst being stretched, given a cursor location. * @param evt the event with the current cursor location. */ private Point2D getNewNodeSize(MouseEvent evt, Point2D newCenter) { // get the coordinates of the cursor in database coordinates EditWindow wnd = (EditWindow)evt.getSource(); int oldx = evt.getX(); int oldy = evt.getY(); Point2D pt = wnd.screenToDatabase(oldx, oldy); // get information about the node being stretched NodeInst ni = (NodeInst)stretchGeom; if (ni.getProto() instanceof Cell) return EPoint.ORIGIN; // setup outline of node with standard offset Poly nodePoly = ni.getBaseShape(); AffineTransform transIn = ni.transformIn(); transIn.transform(pt, pt); nodePoly.transform(transIn); // determine the closest point on the outline Point2D [] points = nodePoly.getPoints(); Point2D closest = null; Point2D farthest = null; if (farthestPoint != null) { for(int i=0; i<points.length; i++) { if (points[i].equals(farthestPoint)) { closest = points[(i + points.length/2) % points.length]; farthest = farthestPoint; break; } } } if (farthest == null || closest == null) { double closestDist = Double.MAX_VALUE; for(int i=0; i<points.length; i++) { double dist = pt.distance(points[i]); if (dist < closestDist) { closestDist = dist; closest = points[i]; farthest = points[(i + points.length/2) % points.length]; } } } farthestPoint = new Point2D.Double(farthest.getX(), farthest.getY()); // if SHIFT and CONTROL is held, use center-based sizing boolean centerBased = (evt.getModifiersEx()&MouseEvent.SHIFT_DOWN_MASK) != 0 && (evt.getModifiersEx()&MouseEvent.CTRL_DOWN_MASK) != 0; // if CONTROL is held, constrain to single-axis stretching boolean singleAxis = (evt.getModifiersEx()&MouseEvent.SHIFT_DOWN_MASK) == 0 && (evt.getModifiersEx()&MouseEvent.CTRL_DOWN_MASK) != 0; // if SHIFT held (or if a square primitive) make growth the same in both axes boolean square = !ni.isCellInstance() && ((PrimitiveNode)ni.getProto()).isSquare(); if ((evt.getModifiersEx()&MouseEvent.SHIFT_DOWN_MASK) != 0 && (evt.getModifiersEx()&MouseEvent.CTRL_DOWN_MASK) == 0) square = true; // determine the amount of growth of the node double growthRatioX, growthRatioY; if (centerBased) { double ptToCenterX = Math.abs(pt.getX()); double closestToCenterX = Math.abs(closest.getX()); double ptToCenterY = Math.abs(pt.getY()); double closestToCenterY = Math.abs(closest.getY()); growthRatioX = ptToCenterX / closestToCenterX; growthRatioY = ptToCenterY / closestToCenterY; } else { double ptToFarthestX = pt.getX() - farthest.getX(); double closestToFarthestX = closest.getX() - farthest.getX(); double ptToFarthestY = pt.getY() - farthest.getY(); double closestToFarthestY = closest.getY() - farthest.getY(); growthRatioX = ptToFarthestX / closestToFarthestX; growthRatioY = ptToFarthestY / closestToFarthestY; } int direction = -1; // both X and Y if (singleAxis) { // constrain to single-axis stretching double grx = Math.abs(growthRatioX); if (grx < 1) { if (grx == 0) grx = 9999; else grx = 1/grx; } double gry = Math.abs(growthRatioY); if (gry < 1) { if (gry == 0) gry = 9999; else gry = 1/gry; } if (grx > gry) { growthRatioY = 1; direction = 0; // Y } else { growthRatioX = 1; direction = 1; // X } } if (square) { if (Math.abs(growthRatioX) > Math.abs(growthRatioY)) growthRatioY = growthRatioX; else growthRatioX = growthRatioY; } // compute the new node size double newXSize = ni.getLambdaBaseXSize() * growthRatioX; double newYSize = ni.getLambdaBaseYSize() * growthRatioY; Point2D newSize = new Point2D.Double(newXSize, newYSize); // grid align the new node size EditWindow.gridAlignSize(newSize, direction); // determine the new center point if (!centerBased) { double closestX = closest.getX(); double closestY = closest.getY(); double farthestX = farthest.getX(); double farthestY = farthest.getY(); double newClosestX = farthestX + Math.abs(newSize.getX())*(closestX > farthestX ? 1 : -1); double newClosestY = farthestY + Math.abs(newSize.getY())*(closestY > farthestY ? 1 : -1); // try to ensure smart grid aligning// double TINY = 1e-6/DBMath.GRID;// if (newClosestX > closestX)// farthestX -= TINY;// else if (newClosestX < closestX)// farthestX += TINY;// if (newClosestY > closestY)// farthestY -= TINY;// else if (newClosestY < closestY)// farthestY += TINY; newCenter.setLocation((newClosestX - closestX) / 2, (newClosestY - closestY) / 2); ni.transformOut().transform(newCenter, newCenter); } return newSize; } /** * Method to determine the proper size for the ArcInst being stretched, given a cursor location. * @param evt the event with the current cursor location. * @return the new base size for the ArcInst in lambda units. */ private double getNewArcSize(MouseEvent evt) { // get the coordinates of the cursor in database coordinates EditWindow wnd = (EditWindow)evt.getSource(); int oldx = evt.getX(); int oldy = evt.getY(); Point2D pt = wnd.screenToDatabase(oldx, oldy); // get information about the arc being stretched ArcInst ai = (ArcInst)stretchGeom; // determine point on arc that is closest to the cursor Point2D ptOnLine = DBMath.closestPointToLine(ai.getHeadLocation(), ai.getTailLocation(), pt); double newLambdaBaseWidth = ptOnLine.distance(pt)*2; Point2D newLambdaBaseSize = new Point2D.Double(newLambdaBaseWidth, newLambdaBaseWidth); EditWindow.gridAlignSize(newLambdaBaseSize, -1); return newLambdaBaseSize.getX(); } private static class ScaleNode extends Job { private NodeInst stretchNode; private EPoint newCenter; private double newWidth, newHeight; protected ScaleNode(NodeInst stretchNode, EPoint newCenter, double newWidth, double newHeight) { super("Scale node", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.stretchNode = stretchNode; this.newCenter = newCenter; this.newWidth = newWidth; this.newHeight = newHeight; startJob(); } public boolean doIt() throws JobException { // make sure scaling the node is allowed if (CircuitChangeJobs.cantEdit(stretchNode.getParent(), null, true, false, true) != 0) return false; Point2D [] points = stretchNode.getTrace(); if (points != null) { double percX = newWidth / stretchNode.getLambdaBaseXSize(); double percY = newHeight / stretchNode.getLambdaBaseYSize(); AffineTransform trans = stretchNode.pureRotateOut(); Point2D [] newPoints = new Point2D[points.length]; for(int i=0; i<points.length; i++) { if (points[i] == null) continue; Point2D newPoint = new Point2D.Double(points[i].getX() * percX, points[i].getY() * percY); trans.transform(newPoint, newPoint); newPoint.setLocation(newPoint.getX() + newCenter.getX(), newPoint.getY() + newCenter.getY()); newPoints[i] = newPoint; } stretchNode.setTrace(newPoints); return true; } double dWid = newWidth - stretchNode.getLambdaBaseXSize(); double dHei = newHeight - stretchNode.getLambdaBaseYSize(); stretchNode.modifyInstance(newCenter.getX() - stretchNode.getAnchorCenterX(), newCenter.getY() - stretchNode.getAnchorCenterY(), dWid, dHei, Orientation.IDENT); return true; } } private static class ScaleArc extends Job { private ArcInst stretchArc; private double newLambdaBaseWidth; protected ScaleArc(ArcInst stretchArc, double newLambdaBaseWidth) { super("Scale arc", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.stretchArc = stretchArc; this.newLambdaBaseWidth = newLambdaBaseWidth; startJob(); } public boolean doIt() throws JobException { // make sure scaling the arc is allowed if (CircuitChangeJobs.cantEdit(stretchArc.getParent(), null, true, false, true) != 0) return false; stretchArc.setLambdaBaseWidth(newLambdaBaseWidth); return true; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -