📄 circuitchanges.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: CircuitChanges.java * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) 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. * * Electric(tm) 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 Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool.user;import com.sun.electric.database.ImmutableArcInst;import com.sun.electric.database.geometry.EPoint;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.text.Pref;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.topology.ArcInst;import com.sun.electric.database.topology.Connection;import com.sun.electric.database.topology.Geometric;import com.sun.electric.database.topology.NodeInst;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.topology.RTNode;import com.sun.electric.database.variable.DisplayedText;import com.sun.electric.database.variable.ElectricObject;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.Layer;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.SizeOffset;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Artwork;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.technology.technologies.Schematics;import com.sun.electric.tool.Job;import com.sun.electric.tool.io.input.LibraryFiles;import com.sun.electric.tool.project.Project;import com.sun.electric.tool.user.menus.MenuCommands;import com.sun.electric.tool.user.ui.EditWindow;import com.sun.electric.tool.user.ui.OutlineListener;import com.sun.electric.tool.user.ui.ToolBar;import com.sun.electric.tool.user.ui.TopLevel;import com.sun.electric.tool.user.ui.WindowContent;import com.sun.electric.tool.user.ui.WindowFrame;import com.sun.electric.tool.user.waveform.WaveformWindow;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import javax.swing.JOptionPane;/** * Class for user-level changes to the circuit. */public class CircuitChanges{ // constructor, never used private CircuitChanges() {} /****************************** NODE TRANSFORMATION ******************************/ private static double lastRotationAmount = 90; /** * Method to handle the command to rotate the selected objects by an amount. * @param amount the amount to rotate. If the amount is zero, prompt for an amount. */ public static void rotateObjects(int amount) { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; // if zero rotation, prompt for amount if (amount == 0) { String val = JOptionPane.showInputDialog("Amount to rotate", new Double(lastRotationAmount)); if (val == null) return; double fAmount = TextUtils.atof(val); if (fAmount == 0) { System.out.println("Null rotation amount"); return; } lastRotationAmount = fAmount; amount = (int)(fAmount * 10); } List<Geometric> highs = MenuCommands.getSelectedObjects(true, true); if (highs.size() == 0) { System.out.println("Cannot rotate: nothing is selected"); return; } new CircuitChangeJobs.RotateSelected(cell, highs, amount, false, false); } /** * Method to handle the command to mirror the selected objects. * @param horizontally true to mirror horizontally (about the horizontal, flipping the Y value). * False to mirror vertically (about the vertical, flipping the X value). */ public static void mirrorObjects(boolean horizontally) { WindowFrame wf = WindowFrame.getCurrentWindowFrame(); if (wf == null) return; Cell cell = wf.getContent().getCell(); if (cell == null) return; new CircuitChangeJobs.RotateSelected(cell, MenuCommands.getSelectedObjects(true, true), 0, true, horizontally); } /****************************** NODE ALIGNMENT ******************************/ /** * Method to align the selected objects to the grid. */ public static void alignToGrid() { // get a list of all selected nodes and arcs List<Geometric> selected = MenuCommands.getSelectedObjects(true, true); // make a set of selected nodes HashSet<NodeInst> selectedNodes = new HashSet<NodeInst>(); for(Geometric geom : selected) { if (geom instanceof NodeInst) selectedNodes.add((NodeInst)geom); } // make a list of nodes at the ends of arcs that should be added to the list List<NodeInst> addedNodes = new ArrayList<NodeInst>(); for(Geometric geom : selected) { if (!(geom instanceof ArcInst)) continue; ArcInst ai = (ArcInst)geom; NodeInst head = ai.getHead().getPortInst().getNodeInst(); if (!selectedNodes.contains(head)) { addedNodes.add(head); selectedNodes.add(head); } NodeInst tail = ai.getTail().getPortInst().getNodeInst(); if (!selectedNodes.contains(tail)) { addedNodes.add(tail); selectedNodes.add(tail); } } for(NodeInst ni : addedNodes) selected.add(ni); // now align them new CircuitChangeJobs.AlignObjects(selected, User.getAlignmentToGrid()); } /** * Method to align the selected nodes. * @param horizontal true to align them horizontally; false for vertically. * @param direction if horizontal is true, meaning is 0 for left, 1 for right, 2 for center. * If horizontal is false, meaning is 0 for top, 1 for bottom, 2 for center. */ public static void alignNodes(boolean horizontal, int direction) { // make sure there is a current cell Cell np = WindowFrame.needCurCell(); if (np == null) return; // get the objects to be moved (mark nodes with nonzero "temp1") List<Geometric> list = MenuCommands.getSelectedObjects(true, true); if (list.size() == 0) { System.out.println("First select objects to move"); return; } // make sure they are all in the same cell for(Geometric geom : list) { if (geom.getParent() != np) { System.out.println("All moved objects must be in the same cell"); return; } } // count the number of nodes List<NodeInst> nodes = new ArrayList<NodeInst>(); for(Geometric geom : list) { if (geom instanceof NodeInst) nodes.add((NodeInst)geom); } int total = nodes.size(); if (total == 0) return; NodeInst [] nis = new NodeInst[total]; double [] dCX = new double[total]; double [] dCY = new double[total];// double [] dSX = new double[total];// double [] dSY = new double[total];// int [] dRot = new int[total]; for(int i=0; i<total; i++) { nis[i] = nodes.get(i);// dSX[i] = dSY[i] = 0;// dRot[i] = 0; } // get bounds double lX = 0, hX = 0, lY = 0, hY = 0; for(int i=0; i<total; i++) { NodeInst ni = nis[i]; Rectangle2D bounds = ni.getBounds(); if (i == 0) { lX = bounds.getMinX(); hX = bounds.getMaxX(); lY = bounds.getMinY(); hY = bounds.getMaxY(); } else { if (bounds.getMinX() < lX) lX = bounds.getMinX(); if (bounds.getMaxX() > hX) hX = bounds.getMaxX(); if (bounds.getMinY() < lY) lY = bounds.getMinY(); if (bounds.getMaxY() > hY) hY = bounds.getMaxY(); } } // determine motion for(int i=0; i<total; i++) { NodeInst ni = nis[i]; Rectangle2D bounds = ni.getBounds(); dCX[i] = dCY[i] = 0; if (horizontal) { // horizontal alignment switch (direction) { case 0: // align to left dCX[i] = lX - bounds.getMinX(); break; case 1: // align to right dCX[i] = hX - bounds.getMaxX(); break; case 2: // align to center dCX[i] = (lX + hX) / 2 - bounds.getCenterX(); break; } } else { // vertical alignment switch (direction) { case 0: // align to top dCY[i] = hY - bounds.getMaxY(); break; case 1: // align to bottom dCY[i] = lY - bounds.getMinY(); break; case 2: // align to center dCY[i] = (lY + hY) / 2 - bounds.getCenterY(); break; } } } new CircuitChangeJobs.AlignNodes(nis, dCX, dCY); } /****************************** ARC MODIFICATION ******************************/ /** * This method sets the highlighted arcs to Rigid */ public static void arcRigidCommand() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new CircuitChangeJobs.ChangeArcProperties(cell, CircuitChangeJobs.ChangeArcEnum.RIGID, getHighlighted()); } /** * This method sets the highlighted arcs to Non-Rigid */ public static void arcNotRigidCommand() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new CircuitChangeJobs.ChangeArcProperties(cell, CircuitChangeJobs.ChangeArcEnum.NONRIGID, getHighlighted()); } /** * This method sets the highlighted arcs to Fixed-Angle */ public static void arcFixedAngleCommand() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new CircuitChangeJobs.ChangeArcProperties(cell, CircuitChangeJobs.ChangeArcEnum.FIXEDANGLE, getHighlighted()); } /** * This method sets the highlighted arcs to Not-Fixed-Angle */ public static void arcNotFixedAngleCommand() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new CircuitChangeJobs.ChangeArcProperties(cell, CircuitChangeJobs.ChangeArcEnum.NONFIXEDANGLE, getHighlighted()); } /** * This method toggles the directionality of highlighted arcs. */ public static void arcDirectionalCommand() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new CircuitChangeJobs.ChangeArcProperties(cell, CircuitChangeJobs.ChangeArcEnum.DIRECTIONAL, getHighlighted()); } /** * This method sets the highlighted arcs to have their head end extended. */ public static void arcHeadExtendCommand() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new CircuitChangeJobs.ChangeArcProperties(cell, CircuitChangeJobs.ChangeArcEnum.HEADEXTEND, getHighlighted()); } /** * This method sets the highlighted arcs to have their tail end extended. */ public static void arcTailExtendCommand() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new CircuitChangeJobs.ChangeArcProperties(cell, CircuitChangeJobs.ChangeArcEnum.TAILEXTEND, getHighlighted()); } /** * This method sets the highlighted ports to be negated. */ public static void toggleNegatedCommand() { Cell cell = WindowFrame.needCurCell(); if (cell == null) return; new CircuitChangeJobs.ToggleNegationJob(cell, getHighlighted()); } /** * Get list of Highlights in current highlighter * @return list of Highlights */ public static List<Highlight2> getHighlighted() { WindowFrame wf = WindowFrame.getCurrentWindowFrame(); if (wf == null) return new ArrayList<Highlight2>(); Highlighter highlighter = wf.getContent().getHighlighter(); if (highlighter == null) return new ArrayList<Highlight2>(); return highlighter.getHighlights();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -