1
/* -*- tab-width: 4 -*-
3
* Electric(tm) VLSI Design System
5
* File: Highlight2.java
7
* Copyright (c) 2006 Sun Microsystems and Static Free Software
9
* Electric(tm) is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 3 of the License, or
12
* (at your option) any later version.
14
* Electric(tm) is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with Electric(tm); see the file COPYING. If not, write to
21
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
22
* Boston, Mass 02111-1307, USA.
24
package com.sun.electric.tool.user;
26
import com.sun.electric.database.geometry.DBMath;
27
import com.sun.electric.database.geometry.GenMath;
28
import com.sun.electric.database.geometry.Poly;
29
import com.sun.electric.database.hierarchy.Cell;
30
import com.sun.electric.database.hierarchy.Export;
31
import com.sun.electric.database.hierarchy.Nodable;
32
import com.sun.electric.database.network.Netlist;
33
import com.sun.electric.database.network.Network;
34
import com.sun.electric.database.network.NetworkTool;
35
import com.sun.electric.database.prototype.PortProto;
36
import com.sun.electric.database.text.Name;
37
import com.sun.electric.database.topology.ArcInst;
38
import com.sun.electric.database.topology.Connection;
39
import com.sun.electric.database.topology.Geometric;
40
import com.sun.electric.database.topology.NodeInst;
41
import com.sun.electric.database.topology.PortInst;
42
import com.sun.electric.database.variable.DisplayedText;
43
import com.sun.electric.database.variable.ElectricObject;
44
import com.sun.electric.database.variable.Variable;
45
import com.sun.electric.technology.PrimitiveNode;
46
import com.sun.electric.technology.Technology;
47
import com.sun.electric.technology.technologies.Artwork;
48
import com.sun.electric.tool.Job;
49
import com.sun.electric.tool.user.ui.EditWindow;
50
import com.sun.electric.tool.user.ui.ToolBar;
52
import java.awt.BasicStroke;
53
import java.awt.Color;
54
import java.awt.Dimension;
56
import java.awt.Graphics;
57
import java.awt.Graphics2D;
58
import java.awt.Point;
59
import java.awt.Stroke;
60
import java.awt.font.FontRenderContext;
61
import java.awt.font.GlyphVector;
62
import java.awt.font.LineMetrics;
63
import java.awt.geom.AffineTransform;
64
import java.awt.geom.Point2D;
65
import java.awt.geom.Rectangle2D;
66
import java.util.HashSet;
67
import java.util.Iterator;
68
import java.util.List;
72
* Super class for all types of highlighting.
74
public abstract class Highlight2 implements Cloneable{
76
/** for drawing solid lines */ public static final BasicStroke solidLine = new BasicStroke(0);
77
/** for drawing dotted lines */ public static final BasicStroke dottedLine = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] {1}, 0);
78
/** for drawing dashed lines */ public static final BasicStroke dashedLine = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10, new float[] {10}, 0);
79
/** for drawing dashed lines */ public static final BasicStroke boldLine = new BasicStroke(3);
81
/** The Cell containing the selection. */ protected Cell cell;
82
private static final int CROSSSIZE = 3;
89
public Cell getCell() { return cell; }
94
if (!cell.isLinked()) return false;
98
// creating so HighlightEOBJ is not a public class
99
public boolean isHighlightEOBJ() { return false; }
101
// creating so HighlightText is not a public class
102
public boolean isHighlightText() { return false; }
104
public Object getObject() { return null; }
106
public Variable.Key getVarKey() { return null; }
108
// point variable, only useful for HighlightEOBJ?
109
public void setPoint(int p) {;}
110
public int getPoint() { return -1; }
112
public Object clone()
115
return super.clone();
117
catch (CloneNotSupportedException e) {
124
* Method to tell whether two Highlights are the same.
125
* @param obj the Highlight to compare to this one.
126
* @return true if the two refer to the same thing.
128
boolean sameThing(Highlight2 obj)
134
* Method to tell whether this Highlight is text that stays with its node.
135
* The two possibilities are (1) text on invisible pins
136
* (2) export names, when the option to move exports with their labels is requested.
137
* @return true if this Highlight is text that should move with its node.
139
public boolean nodeMovesWithText()
145
* Method to display this Highlight in a window.
146
* @param wnd the window in which to draw this highlight.
147
* @param g the Graphics associated with the window.
149
public void showHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY, boolean onlyHighlight,
150
Color mainColor, Stroke primaryStroke, boolean setConnected)
152
if (!isValid()) return;
153
g.setColor(mainColor);
154
Graphics2D g2 = (Graphics2D)g;
155
g2.setStroke(primaryStroke);
156
showInternalHighlight(wnd, g, highOffX, highOffY, onlyHighlight, setConnected);
159
abstract void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
160
boolean onlyHighlight, boolean setConnected);
163
* Method to populate a List of all highlighted Geometrics.
164
* @param list the list to populate
165
* @param wantNodes true if NodeInsts should be included in the list.
166
* @param wantArcs true if ArcInsts should be included in the list.
168
void getHighlightedEObjs(Highlighter highlighter, List<Geometric> list, boolean wantNodes, boolean wantArcs) {;}
170
static void getHighlightedEObjsInternal(Geometric geom, List<Geometric> list, boolean wantNodes, boolean wantArcs)
172
if (geom == null) return;
173
if (!wantNodes && geom instanceof NodeInst) return;
174
if (!wantArcs && geom instanceof ArcInst) return;
176
if (list.contains(geom)) return;
181
* Method to return the Geometric object that is in this Highlight.
182
* If the highlight is a PortInst, an Export, or annotation text, its base NodeInst is returned.
183
* @return the Geometric object that is in this Highlight.
184
* Returns null if this Highlight is not on a Geometric.
186
public Geometric getGeometric() { return null; }
189
* Method to return a List of all highlighted NodeInsts.
190
* Return a list with the highlighted NodeInsts.
192
void getHighlightedNodes(Highlighter highlighter, List<NodeInst> list) {;}
194
static void getHighlightedNodesInternal(Geometric geom, List<NodeInst> list)
196
if (geom == null || !(geom instanceof NodeInst)) return;
197
NodeInst ni = (NodeInst)geom;
198
if (list.contains(ni)) return;
203
* Method to return a List of all highlighted ArcInsts.
204
* Return a list with the highlighted ArcInsts.
206
void getHighlightedArcs(Highlighter highlighter, List<ArcInst> list) {;}
208
static void getHighlightedArcsInternal(Geometric geom, List<ArcInst> list)
210
if (geom == null || !(geom instanceof ArcInst)) return;
211
ArcInst ai = (ArcInst)geom;
213
if (list.contains(ai)) return;
218
* Method to return a set of the currently selected networks.
219
* Return a set of the currently selected networks.
220
* If there are no selected networks, the list is empty.
222
void getHighlightedNetworks(Set<Network> nets, Netlist netlist) {;}
225
* Method to return a List of all highlighted text.
226
* @param list list to populate.
227
* @param unique true to request that the text objects be unique,
228
* and not attached to another object that is highlighted.
229
* For example, if a node and an export on that node are selected,
230
* the export text will not be included if "unique" is true.
231
* Return a list with the Highlight objects that point to text.
233
void getHighlightedText(List<DisplayedText> list, boolean unique, List<Highlight2> getHighlights) {;}
236
* Method to return the bounds of the highlighted objects.
237
* @param wnd the window in which to get bounds.
238
* @return the bounds of the highlighted objects (null if nothing is highlighted).
240
Rectangle2D getHighlightedArea(EditWindow wnd) { return null; }
243
* Method to return the ElectricObject associated with this Highlight object.
244
* @return the ElectricObject associated with this Highlight object.
246
public ElectricObject getElectricObject() { return null; }
249
* Method to tell whether a point is over this Highlight.
250
* @param wnd the window being examined.
251
* @param x the X screen coordinate of the point.
252
* @param y the Y screen coordinate of the point.
253
* @return true if the point is over this Highlight.
255
boolean overHighlighted(EditWindow wnd, int x, int y, Highlighter highlighter) { return false; }
257
public String getInfo() { return null;}
260
* Method to load an array of counts with the number of highlighted objects in a list.
261
* arc = 0, node = 1, export = 2, text = 3, graphics = 4
262
* @param list the list of highlighted objects.
263
* @param counts the array of counts to set.
264
* @return a NodeInst, if it is in the list.
266
public static NodeInst getInfoCommand(List<Highlight2> list, int[] counts)
268
// information about the selected items
269
NodeInst theNode = null;
270
for(Highlight2 h : list)
272
ElectricObject eobj = h.getElectricObject();
273
if (h.isHighlightEOBJ())
275
if (eobj instanceof NodeInst || eobj instanceof PortInst)
278
if (eobj instanceof NodeInst) theNode = (NodeInst)eobj; else
279
theNode = ((PortInst)eobj).getNodeInst();
280
} else if (eobj instanceof ArcInst)
284
} else if (h.isHighlightText())
286
if (h.getVarKey() == Export.EXPORT_NAME) counts[2]++; else
288
if (h.getElectricObject() instanceof NodeInst)
289
theNode = (NodeInst)h.getElectricObject();
292
} else if (h instanceof HighlightArea)
295
} else if (h instanceof HighlightLine)
304
* Method to draw an array of points as highlighting.
305
* @param wnd the window in which drawing is happening.
306
* @param g the Graphics for the window.
307
* @param points the array of points being drawn.
308
* @param offX the X offset of the drawing.
309
* @param offY the Y offset of the drawing.
310
* @param opened true if the points are drawn "opened".
313
public static void drawOutlineFromPoints(EditWindow wnd, Graphics g, Point2D[] points, int offX, int offY,
314
boolean opened, boolean thickLine)
316
boolean onePoint = true;
317
if (points.length <= 0)
319
Point firstP = wnd.databaseToScreen(points[0].getX(), points[0].getY());
320
for(int i=1; i<points.length; i++)
322
Point p = wnd.databaseToScreen(points[i].getX(), points[i].getY());
323
if (DBMath.doublesEqual(p.getX(), firstP.getX()) &&
324
DBMath.doublesEqual(p.getY(), firstP.getY())) continue;
330
drawLine(g, wnd, firstP.x + offX-CROSSSIZE, firstP.y + offY, firstP.x + offX+CROSSSIZE, firstP.y + offY);
331
drawLine(g, wnd, firstP.x + offX, firstP.y + offY-CROSSSIZE, firstP.x + offX, firstP.y + offY+CROSSSIZE);
337
// if (thickCenter != null)
339
// Point lp = wnd.databaseToScreen(thickCenter.getX(), thickCenter.getY());
344
for(int i=0; i<points.length; i++)
349
if (opened) continue;
350
lastI = points.length - 1;
352
Point lp = wnd.databaseToScreen(points[lastI].getX(), points[lastI].getY());
353
Point p = wnd.databaseToScreen(points[i].getX(), points[i].getY());
354
int fX = lp.x + offX; int fY = lp.y + offY;
355
int tX = p.x + offX; int tY = p.y + offY;
356
drawLine(g, wnd, fX, fY, tX, tY);
359
if (fX < cX) fX--; else fX++;
360
if (fY < cY) fY--; else fY++;
361
if (tX < cX) tX--; else tX++;
362
if (tY < cY) tY--; else tY++;
363
drawLine(g, wnd, fX, fY, tX, tY);
368
void internalDescribe(StringBuffer desc) {;}
371
* Describe the Highlight
372
* @return a string describing the highlight
374
public String describe() {
375
StringBuffer desc = new StringBuffer();
376
desc.append(this.getClass().getName());
383
internalDescribe(desc);
384
return desc.toString();
388
* Gets a poly that describes the Highlight for the NodeInst.
389
* @param ni the nodeinst to get a poly that will be used to highlight it
390
* @return a poly outlining the nodeInst.
392
public static Poly getNodeInstOutline(NodeInst ni)
394
AffineTransform trans = ni.rotateOutAboutTrueCenter();
397
if (!ni.isCellInstance())
399
PrimitiveNode pn = (PrimitiveNode)ni.getProto();
401
// special case for outline nodes
402
if (pn.isHoldsOutline())
404
Point2D [] outline = ni.getTrace();
407
int numPoints = outline.length;
408
boolean whole = true;
409
for(int i=1; i<numPoints; i++)
411
if (outline[i] == null)
419
Point2D [] pointList = new Point2D.Double[numPoints];
420
for(int i=0; i<numPoints; i++)
422
pointList[i] = new Point2D.Double(ni.getAnchorCenterX() + outline[i].getX(),
423
ni.getAnchorCenterY() + outline[i].getY());
425
trans.transform(pointList, 0, pointList, 0, numPoints);
426
poly = new Poly(pointList);
427
if (ni.getFunction() == PrimitiveNode.Function.NODE)
429
poly.setStyle(Poly.Type.FILLED);
432
poly.setStyle(Poly.Type.OPENED);
439
// special case for circular nodes
440
if (pn == Artwork.tech().circleNode || pn == Artwork.tech().thickCircleNode)
442
// see if this circle is only a partial one
443
double [] angles = ni.getArcDegrees();
444
if (angles[0] != 0.0 || angles[1] != 0.0)
446
Point2D [] pointList = Artwork.fillEllipse(ni.getAnchorCenter(), ni.getXSize(), ni.getYSize(), angles[0], angles[1]);
447
poly = new Poly(pointList);
448
poly.setStyle(Poly.Type.OPENED);
449
poly.transform(ni.rotateOut());
454
// setup outline of node with standard offset
456
poly = ni.getBaseShape();
462
* Implementing clipping here speeds things up a lot if there are
463
* many large highlights off-screen
465
public static void drawLine(Graphics g, EditWindow wnd, int x1, int y1, int x2, int y2)
467
Dimension size = wnd.getScreenSize();
468
// first clip the line
469
Point pt1 = new Point(x1, y1);
470
Point pt2 = new Point(x2, y2);
471
if (GenMath.clipLine(pt1, pt2, 0, size.width-1, 0, size.height-1)) return;
472
g.drawLine(pt1.x, pt1.y, pt2.x, pt2.y);
473
// if (((x1 >= 0) && (x1 <= size.getLambdaFullWidth())) || ((x2 >= 0) && (x2 <= size.getLambdaFullWidth())) ||
474
// ((y1 >= 0) && (y1 <= size.getHeight())) || ((y2 >= 0) && (y2 <= size.getHeight()))) {
475
// g.drawLine(x1, y1, x2, y2);
480
class HighlightPoly extends Highlight2
482
/** The highlighted polygon */ private Poly polygon;
483
/** The color used when drawing polygons */ private Color color;
484
HighlightPoly(Cell c, Poly p, Color col)
491
public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
492
boolean onlyHighlight, boolean setConnected)
494
// switch colors if specified
495
Color oldColor = null;
498
oldColor = g.getColor();
503
Point2D[] points = polygon.getPoints();
504
if (polygon.getStyle() == Poly.Type.FILLED)
506
int [] xPoints = new int[points.length];
507
int [] yPoints = new int[points.length];
508
for(int i=0; i<points.length; i++)
510
Point p = wnd.databaseToScreen(points[i].getX(), points[i].getY());
514
g.fillPolygon(xPoints, yPoints, points.length);
517
boolean opened = (polygon.getStyle() == Poly.Type.OPENED);
518
drawOutlineFromPoints(wnd, g, points, highOffX, highOffY, opened, false);
521
// switch back to old color if switched
522
if (oldColor != null)
523
g.setColor(oldColor);
527
class HighlightLine extends Highlight2
529
/** The highlighted line. */ protected Point2D start, end, center;
530
/** The highlighted line is thick. */ protected boolean thickLine;
531
HighlightLine(Cell c, Point2D s, Point2D e, Point2D cen, boolean thick)
537
this.thickLine = thick;
540
public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
541
boolean onlyHighlight, boolean setConnected)
543
Point2D [] points = new Point2D.Double[2];
544
points[0] = new Point2D.Double(start.getX(), start.getY());
545
points[1] = new Point2D.Double(end.getX(), end.getY());
546
drawOutlineFromPoints(wnd, g, points, highOffX, highOffY, false, thickLine);
549
Rectangle2D getHighlightedArea(EditWindow wnd)
551
double cX = Math.min(start.getX(), end.getX());
552
double cY = Math.min(start.getY(), end.getY());
553
double sX = Math.abs(start.getX() - end.getX());
554
double sY = Math.abs(start.getY() - end.getY());
555
return new Rectangle2D.Double(cX, cY, sX, sY);
558
public String getInfo()
560
String description = "Line from (" + start.getX() + "," + start.getY() + ") to (" +
561
end.getX() + "," + end.getY() + ")";
566
class HighlightObject extends Highlight2
568
/** The highlighted generic object */ private Object object;
569
HighlightObject(Cell c, Object obj)
575
public Object getObject() { return object; }
577
public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
578
boolean onlyHighlight, boolean setConnected)
580
System.out.println("Should call this one?");
584
class HighlightArea extends Highlight2
586
/** The highlighted area. */ protected Rectangle2D bounds;
587
HighlightArea(Cell c, Rectangle2D area)
590
bounds = new Rectangle2D.Double();
591
bounds.setRect(area);
594
public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
595
boolean onlyHighlight, boolean setConnected)
597
Point2D [] points = new Point2D.Double[5];
598
points[0] = new Point2D.Double(bounds.getMinX(), bounds.getMinY());
599
points[1] = new Point2D.Double(bounds.getMinX(), bounds.getMaxY());
600
points[2] = new Point2D.Double(bounds.getMaxX(), bounds.getMaxY());
601
points[3] = new Point2D.Double(bounds.getMaxX(), bounds.getMinY());
602
points[4] = new Point2D.Double(bounds.getMinX(), bounds.getMinY());
603
drawOutlineFromPoints(wnd, g, points, highOffX, highOffY, false, false);
606
void getHighlightedEObjs(Highlighter highlighter, List<Geometric> list, boolean wantNodes, boolean wantArcs)
608
List<Highlight2> inArea = Highlighter.findAllInArea(highlighter, cell, false, false, false, false, false, false, bounds, null);
609
for(Highlight2 ah : inArea)
611
if (!(ah instanceof HighlightEOBJ)) continue;
612
ElectricObject eobj = ((HighlightEOBJ)ah).eobj;
613
if (eobj instanceof ArcInst) {
615
list.add((ArcInst)eobj);
616
} else if (eobj instanceof NodeInst) {
618
list.add((NodeInst)eobj);
619
} else if (eobj instanceof PortInst) {
621
list.add(((PortInst)eobj).getNodeInst());
625
// if (eobj instanceof NodeInst || eobj instanceof PortInst) continue;
627
// if (!wantArcs && eobj instanceof ArcInst) continue;
628
// if (eobj instanceof PortInst) eobj = ((PortInst)eobj).getNodeInst();
629
// highlightedGeoms.add(eobj);
633
void getHighlightedNodes(Highlighter highlighter, List<NodeInst> list)
635
List<Highlight2> inArea = Highlighter.findAllInArea(highlighter, cell, false, false, false, false, false, false,
637
for(Highlight2 ah : inArea)
639
if (!(ah instanceof HighlightEOBJ)) continue;
640
ElectricObject eobj = ((HighlightEOBJ)ah).eobj;
641
if (eobj instanceof NodeInst)
642
list.add((NodeInst)eobj);
643
else if (eobj instanceof PortInst)
644
list.add(((PortInst)eobj).getNodeInst());
648
void getHighlightedArcs(Highlighter highlighter, List<ArcInst> list)
650
List<Highlight2> inArea = Highlighter.findAllInArea(highlighter, cell, false, false, false, false, false, false,
652
for(Highlight2 ah : inArea)
654
if (!(ah instanceof HighlightEOBJ)) continue;
655
ElectricObject eobj = ((HighlightEOBJ)ah).eobj;
656
if (eobj instanceof ArcInst)
657
list.add((ArcInst)eobj);
661
Rectangle2D getHighlightedArea(EditWindow wnd)
666
public String getInfo()
668
String description = "Area from " + bounds.getMinX() + "<=X<=" + bounds.getMaxX() +
669
" and " + bounds.getMinY() + "<=Y<=" + bounds.getMaxY();
674
class HighlightMessage extends Highlight2
676
/** The highlighted message. */ protected String msg;
677
/** Location of the message highlight */ protected Point2D loc;
678
/** Corner of text: 0=lowerLeft, 1=upperLeft, 2=upperRight, 3=lowerRight */ protected int corner;
680
HighlightMessage(Cell c, String m, Point2D p, int co)
688
void internalDescribe(StringBuffer desc)
694
public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
695
boolean onlyHighlight, boolean setConnected)
697
Point location = wnd.databaseToScreen(loc.getX(), loc.getY());
700
// determine the size of the text
701
Font font = g.getFont();
702
FontRenderContext frc = new FontRenderContext(null, true, true);
703
GlyphVector gv = font.createGlyphVector(frc, msg);
704
LineMetrics lm = font.getLineMetrics(msg, frc);
705
Rectangle2D rasRect = gv.getLogicalBounds();
706
int width = (int)rasRect.getWidth();
707
int height = (int)(lm.getHeight()+0.5);
710
case 1: // put upper-left corner of text at drawing coordinate
711
location.y += height;
713
case 2: // put upper-right corner of text at drawing coordinate
714
location.y += height;
717
case 3: // put lower-right corner of text at drawing coordinate
718
location.y += height;
723
Color oldColor = g.getColor();
724
g.setColor(new Color(255-oldColor.getRed(), 255-oldColor.getGreen(), 255-oldColor.getBlue()));
725
g.drawString(msg, location.x+1, location.y+1);
726
g.setColor(oldColor);
727
g.drawString(msg, location.x, location.y);
730
Rectangle2D getHighlightedArea(EditWindow wnd)
732
return new Rectangle2D.Double(loc.getX(), loc.getY(), 0, 0);
736
class HighlightEOBJ extends Highlight2
738
/** The highlighted object. */ protected ElectricObject eobj;
739
/** For Highlighted networks, this prevents excess highlights */ private boolean highlightConnected;
740
/** The highlighted outline point (only for NodeInst). */ protected int point;
741
/** The color used when drawing polygons */ private Color color;
743
public HighlightEOBJ(ElectricObject e, Cell c, boolean connected, int p)
747
this.highlightConnected = connected;
752
public HighlightEOBJ(ElectricObject e, Cell c, boolean connected, int p, Color col)
756
this.highlightConnected = connected;
761
void internalDescribe(StringBuffer desc)
764
if (eobj instanceof PortInst) {
765
desc.append(((PortInst)eobj).describe(true));
767
if (eobj instanceof NodeInst) {
768
desc.append(((NodeInst)eobj).describe(true));
770
if (eobj instanceof ArcInst) {
771
desc.append(((ArcInst)eobj).describe(true));
775
public ElectricObject getElectricObject() { return eobj; }
777
public boolean isHighlightEOBJ() { return true; }
779
public void setPoint(int p) { point = p;}
780
public int getPoint() { return point; }
784
if (!super.isValid()) return false;
786
if (eobj instanceof PortInst)
787
return ((PortInst)eobj).getNodeInst().isLinked();
788
return eobj.isLinked();
791
boolean sameThing(Highlight2 obj)
793
if (this == obj) return (true);
795
// Consider already obj==null
796
if (obj == null || getClass() != obj.getClass())
799
ElectricObject realEObj = eobj;
800
if (realEObj instanceof PortInst) realEObj = ((PortInst)realEObj).getNodeInst();
802
HighlightEOBJ other = (HighlightEOBJ)obj;
803
ElectricObject realOtherEObj = other.eobj;
804
if (realOtherEObj instanceof PortInst) realOtherEObj = ((PortInst)realOtherEObj).getNodeInst();
805
if (realEObj != realOtherEObj) return false;
809
public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
810
boolean onlyHighlight, boolean setConnected)
812
Graphics2D g2 = (Graphics2D)g;
813
highlightConnected = setConnected;
815
// switch colors if specified
816
Color oldColor = null;
819
oldColor = g.getColor();
824
if (eobj instanceof ArcInst)
826
ArcInst ai = (ArcInst)eobj;
828
// if (!Job.acquireExamineLock(false)) return;
830
// construct the polygons that describe the basic arc
831
Poly poly = ai.makeLambdaPoly(ai.getGridBaseWidth(), Poly.Type.CLOSED);
832
if (poly == null) return;
833
drawOutlineFromPoints(wnd, g, poly.getPoints(), highOffX, highOffY, false, false);
837
// this is the only thing highlighted: give more information about constraints
838
String constraints = "X";
839
if (ai.isRigid()) constraints = "R"; else
841
if (ai.isFixedAngle())
843
if (ai.isSlidable()) constraints = "FS"; else
845
} else if (ai.isSlidable()) constraints = "S";
847
Point p = wnd.databaseToScreen(ai.getTrueCenterX(), ai.getTrueCenterY());
848
Font font = wnd.getFont(null);
851
GlyphVector gv = wnd.getGlyphs(constraints, font);
852
Rectangle2D glyphBounds = gv.getVisualBounds();
853
g.drawString(constraints, (int)(p.x - glyphBounds.getWidth()/2 + highOffX),
854
p.y + font.getSize()/2 + highOffY);
857
// Job.releaseExamineLock();
859
// Job.releaseExamineLock();
865
// highlight NodeInst
867
ElectricObject realEObj = eobj;
868
PortInst originalPi = null;
869
if (realEObj instanceof PortInst)
871
originalPi = ((PortInst)realEObj);
872
pp = originalPi.getPortProto();
873
realEObj = ((PortInst)realEObj).getNodeInst();
875
if (realEObj instanceof NodeInst)
877
NodeInst ni = (NodeInst)realEObj;
878
AffineTransform trans = ni.rotateOutAboutTrueCenter();
883
boolean drewOutline = false;
884
if (!ni.isCellInstance())
886
// special case for outline nodes
887
if (np.isHoldsOutline())
889
Point2D [] outline = ni.getTrace();
892
int numPoints = outline.length;
893
Point2D [] pointList = new Point2D.Double[numPoints];
894
for(int i=0; i<numPoints; i++)
896
pointList[i] = new Point2D.Double(ni.getTrueCenterX() + outline[i].getX(),
897
ni.getTrueCenterY() + outline[i].getY());
899
trans.transform(pointList, 0, pointList, 0, numPoints);
900
drawOutlineFromPoints(wnd, g, pointList, 0, 0, true, null);
906
// setup outline of node with standard offset
909
SizeOffset so = ni.getSizeOffset();
910
double nodeLowX = ni.getTrueCenterX() - ni.getXSize()/2 + so.getLowXOffset();
911
double nodeHighX = ni.getTrueCenterX() + ni.getXSize()/2 - so.getHighXOffset();
912
double nodeLowY = ni.getTrueCenterY() - ni.getYSize()/2 + so.getLowYOffset();
913
double nodeHighY = ni.getTrueCenterY() + ni.getYSize()/2 - so.getHighYOffset();
914
if (nodeLowX == nodeHighX && nodeLowY == nodeHighY)
916
float x = (float)nodeLowX;
917
float y = (float)nodeLowY;
918
float size = 3 / (float)wnd.getScale();
919
Point c1 = wnd.databaseToScreen(x+size, y);
920
Point c2 = wnd.databaseToScreen(x-size, y);
921
Point c3 = wnd.databaseToScreen(x, y+size);
922
Point c4 = wnd.databaseToScreen(x, y-size);
923
drawLine(g, wnd, c1.x + offX, c1.y + offY, c2.x + offX, c2.y + offY);
924
drawLine(g, wnd, c3.x + offX, c3.y + offY, c4.x + offX, c4.y + offY);
927
double nodeX = (nodeLowX + nodeHighX) / 2;
928
double nodeY = (nodeLowY + nodeHighY) / 2;
929
Poly poly = new Poly(nodeX, nodeY, nodeHighX-nodeLowX, nodeHighY-nodeLowY);
930
poly.transform(trans);
931
drawOutlineFromPoints(wnd, g, poly.getPoints(), offX, offY, false, null);
936
// draw the selected point
939
Point2D [] points = ni.getTrace();
942
// if this is a spline, highlight the true shape
943
if (ni.getProto() == Artwork.tech().splineNode)
945
Point2D [] changedPoints = new Point2D[points.length];
946
for(int i=0; i<points.length; i++)
948
changedPoints[i] = points[i];
951
double x = ni.getAnchorCenterX() + points[point].getX();
952
double y = ni.getAnchorCenterY() + points[point].getY();
953
Point2D thisPt = new Point2D.Double(x, y);
954
trans.transform(thisPt, thisPt);
955
Point cThis = wnd.databaseToScreen(thisPt);
956
Point2D db = wnd.screenToDatabase(cThis.x+offX, cThis.y+offY);
957
changedPoints[i] = new Point2D.Double(db.getX() - ni.getAnchorCenterX(), db.getY() - ni.getAnchorCenterY());
960
Point2D [] spPoints = Artwork.tech().fillSpline(ni.getAnchorCenterX(), ni.getAnchorCenterY(), changedPoints);
961
Point cLast = wnd.databaseToScreen(spPoints[0]);
962
for(int i=1; i<spPoints.length; i++)
964
Point cThis = wnd.databaseToScreen(spPoints[i]);
965
drawLine(g, wnd, cLast.x, cLast.y, cThis.x, cThis.y);
970
// draw an "x" through the selected point
971
if (points[point] != null)
973
double x = ni.getAnchorCenterX() + points[point].getX();
974
double y = ni.getAnchorCenterY() + points[point].getY();
975
Point2D thisPt = new Point2D.Double(x, y);
976
trans.transform(thisPt, thisPt);
977
Point cThis = wnd.databaseToScreen(thisPt);
979
drawLine(g, wnd, cThis.x + size + offX, cThis.y + size + offY, cThis.x - size + offX, cThis.y - size + offY);
980
drawLine(g, wnd, cThis.x + size + offX, cThis.y - size + offY, cThis.x - size + offX, cThis.y + size + offY);
982
// find previous and next point, and draw lines to them
983
boolean showWrap = ni.traceWraps();
984
Point2D prevPt = null, nextPt = null;
985
int prevPoint = point - 1;
986
if (prevPoint < 0 && showWrap) prevPoint = points.length - 1;
987
if (prevPoint >= 0 && points[prevPoint] != null)
989
prevPt = new Point2D.Double(ni.getAnchorCenterX() + points[prevPoint].getX(),
990
ni.getAnchorCenterY() + points[prevPoint].getY());
991
trans.transform(prevPt, prevPt);
992
if (prevPt.getX() == thisPt.getX() && prevPt.getY() == thisPt.getY()) prevPoint = -1; else
994
Point cPrev = wnd.databaseToScreen(prevPt);
995
drawLine(g, wnd, cThis.x + offX, cThis.y + offY, cPrev.x, cPrev.y);
998
int nextPoint = point + 1;
999
if (nextPoint >= points.length)
1001
if (showWrap) nextPoint = 0; else
1004
if (nextPoint >= 0 && points[nextPoint] != null)
1006
nextPt = new Point2D.Double(ni.getAnchorCenterX() + points[nextPoint].getX(),
1007
ni.getAnchorCenterY() + points[nextPoint].getY());
1008
trans.transform(nextPt, nextPt);
1009
if (nextPt.getX() == thisPt.getX() && nextPt.getY() == thisPt.getY()) nextPoint = -1; else
1011
Point cNext = wnd.databaseToScreen(nextPt);
1012
drawLine(g, wnd, cThis.x + offX, cThis.y + offY, cNext.x, cNext.y);
1016
// draw arrows on the lines
1017
if (offX == 0 && offY == 0 && points.length > 2 && prevPt != null && nextPt != null)
1019
double arrowLen = Double.MAX_VALUE;
1020
if (prevPoint >= 0) arrowLen = Math.min(thisPt.distance(prevPt), arrowLen);
1021
if (nextPoint >= 0) arrowLen = Math.min(thisPt.distance(nextPt), arrowLen);
1023
double angleOfArrow = Math.PI * 0.8;
1026
Point2D prevCtr = new Point2D.Double((prevPt.getX()+thisPt.getX()) / 2,
1027
(prevPt.getY()+thisPt.getY()) / 2);
1028
double prevAngle = DBMath.figureAngleRadians(prevPt, thisPt);
1029
Point2D prevArrow1 = new Point2D.Double(prevCtr.getX() + Math.cos(prevAngle+angleOfArrow) * arrowLen,
1030
prevCtr.getY() + Math.sin(prevAngle+angleOfArrow) * arrowLen);
1031
Point2D prevArrow2 = new Point2D.Double(prevCtr.getX() + Math.cos(prevAngle-angleOfArrow) * arrowLen,
1032
prevCtr.getY() + Math.sin(prevAngle-angleOfArrow) * arrowLen);
1033
Point cPrevCtr = wnd.databaseToScreen(prevCtr);
1034
Point cPrevArrow1 = wnd.databaseToScreen(prevArrow1);
1035
Point cPrevArrow2 = wnd.databaseToScreen(prevArrow2);
1036
drawLine(g, wnd, cPrevCtr.x, cPrevCtr.y, cPrevArrow1.x, cPrevArrow1.y);
1037
drawLine(g, wnd, cPrevCtr.x, cPrevCtr.y, cPrevArrow2.x, cPrevArrow2.y);
1042
Point2D nextCtr = new Point2D.Double((nextPt.getX()+thisPt.getX()) / 2,
1043
(nextPt.getY()+thisPt.getY()) / 2);
1044
double nextAngle = DBMath.figureAngleRadians(thisPt, nextPt);
1045
Point2D nextArrow1 = new Point2D.Double(nextCtr.getX() + Math.cos(nextAngle+angleOfArrow) * arrowLen,
1046
nextCtr.getY() + Math.sin(nextAngle+angleOfArrow) * arrowLen);
1047
Point2D nextArrow2 = new Point2D.Double(nextCtr.getX() + Math.cos(nextAngle-angleOfArrow) * arrowLen,
1048
nextCtr.getY() + Math.sin(nextAngle-angleOfArrow) * arrowLen);
1049
Point cNextCtr = wnd.databaseToScreen(nextCtr);
1050
Point cNextArrow1 = wnd.databaseToScreen(nextArrow1);
1051
Point cNextArrow2 = wnd.databaseToScreen(nextArrow2);
1052
drawLine(g, wnd, cNextCtr.x, cNextCtr.y, cNextArrow1.x, cNextArrow1.y);
1053
drawLine(g, wnd, cNextCtr.x, cNextCtr.y, cNextArrow2.x, cNextArrow2.y);
1058
// do not offset the node, just this point
1063
// draw nodeInst outline
1064
if ((offX == 0 && offY == 0) || point < 0)
1066
Poly niPoly = getNodeInstOutline(ni);
1067
boolean niOpened = (niPoly.getStyle() == Poly.Type.OPENED);
1068
Point2D [] points = niPoly.getPoints();
1069
drawOutlineFromPoints(wnd, g, points, offX, offY, niOpened, false);
1072
// draw the selected port
1075
//@TODO MAYBE I need the main color
1076
// g.setColor(mainColor);
1077
Poly poly = ni.getShapeOfPort(pp);
1078
boolean opened = true;
1079
Point2D [] points = poly.getPoints();
1080
if (poly.getStyle() == Poly.Type.FILLED || poly.getStyle() == Poly.Type.CLOSED) opened = false;
1081
if (poly.getStyle() == Poly.Type.CIRCLE || poly.getStyle() == Poly.Type.THICKCIRCLE ||
1082
poly.getStyle() == Poly.Type.DISC)
1084
double sX = points[0].distance(points[1]) * 2;
1085
Point2D [] pts = Artwork.fillEllipse(points[0], sX, sX, 0, 360);
1086
poly = new Poly(pts);
1087
poly.transform(ni.rotateOut());
1088
points = poly.getPoints();
1089
} else if (poly.getStyle() == Poly.Type.CIRCLEARC)
1091
double [] angles = ni.getArcDegrees();
1092
double sX = points[0].distance(points[1]) * 2;
1093
Point2D [] pts = Artwork.fillEllipse(points[0], sX, sX, angles[0], angles[1]);
1094
poly = new Poly(pts);
1095
poly.transform(ni.rotateOut());
1096
points = poly.getPoints();
1098
drawOutlineFromPoints(wnd, g, points, offX, offY, opened, false);
1099
// g.setColor(mainColor);
1101
// show name of port
1102
if (ni.isCellInstance() && (g instanceof Graphics2D))
1104
// only show name if port is wired (because all other situations already show the port)
1105
boolean wired = false;
1106
for(Iterator<Connection> cIt = ni.getConnections(); cIt.hasNext(); )
1108
Connection con = cIt.next();
1109
if (con.getPortInst().getPortProto() == pp) { wired = true; break; }
1113
Font font = new Font(User.getDefaultFont(), Font.PLAIN, (int)(1.5*EditWindow.getDefaultFontSize()));
1114
GlyphVector v = wnd.getGlyphs(pp.getName(), font);
1115
Point2D point = wnd.databaseToScreen(poly.getCenterX(), poly.getCenterY());
1116
((Graphics2D)g).drawGlyphVector(v, (float)point.getX()+offX, (float)point.getY()+offY);
1120
// if this is a port on an "example icon", show the equivalent port in the cell
1121
// if (ni.isIconOfParent())
1123
// // find export in parent
1124
// Export equiv = (Export)cell.findPortProto(pp.getName());
1125
// if (equiv != null)
1127
// PortInst ePi = equiv.getOriginalPort();
1128
// Poly ePoly = ePi.getPoly();
1129
// Point eP = wnd.databaseToScreen(ePoly.getCenterX(), ePoly.getCenterY());
1130
// Point p = wnd.databaseToScreen(poly.getCenterX(), poly.getCenterY());
1131
// drawLine(g, wnd, eP.x, eP.y, p.x + offX, p.y + offY);
1135
// highlight objects that are electrically connected to this object
1136
// unless specified not to. HighlightConnected is set to false by addNetwork when
1137
// it figures out what's connected and adds them manually. Because they are added
1138
// in addNetwork, we shouldn't try and add connected objects here.
1139
if (highlightConnected && onlyHighlight) {
1140
Netlist netlist = cell.acquireUserNetlist();
1141
if (netlist == null) return;
1142
NodeInst originalNI = ni;
1143
if (ni.isIconOfParent())
1145
// find export in parent
1146
Export equiv = (Export)cell.findPortProto(pp.getName());
1149
originalPi = equiv.getOriginalPort();
1150
ni = originalPi.getNodeInst();
1151
pp = originalPi.getPortProto();
1154
Set<Network> networks = new HashSet<Network>();
1155
networks = NetworkTool.getNetworksOnPort(originalPi, netlist, networks);
1157
HashSet<Geometric> markObj = new HashSet<Geometric>();
1158
for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); )
1160
ArcInst ai = it.next();
1161
Name arcName = ai.getNameKey();
1162
for (int i=0; i<arcName.busWidth(); i++) {
1163
if (networks.contains(netlist.getNetwork(ai, i))) {
1165
markObj.add(ai.getHeadPortInst().getNodeInst());
1166
markObj.add(ai.getTailPortInst().getNodeInst());
1172
for (Iterator<Nodable> it = netlist.getNodables(); it.hasNext(); ) {
1173
Nodable no = it.next();
1174
NodeInst oNi = no.getNodeInst();
1175
if (oNi == originalNI) continue;
1176
if (markObj.contains(ni)) continue;
1178
boolean highlightNo = false;
1179
for(Iterator<PortProto> eIt = no.getProto().getPorts(); eIt.hasNext(); )
1181
PortProto oPp = eIt.next();
1182
Name opName = oPp.getNameKey();
1183
for (int j=0; j<opName.busWidth(); j++) {
1184
if (networks.contains(netlist.getNetwork(no, oPp, j))) {
1189
if (highlightNo) break;
1194
//System.out.println("Search took "+com.sun.electric.database.text.TextUtils.getElapsedTime(System.currentTimeMillis()-start));
1196
// draw lines along all of the arcs on the network
1197
Stroke origStroke = g2.getStroke();
1198
g2.setStroke(dashedLine);
1199
for(Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); )
1201
ArcInst ai = it.next();
1202
if (!markObj.contains(ai)) continue;
1203
Point c1 = wnd.databaseToScreen(ai.getHeadLocation());
1204
Point c2 = wnd.databaseToScreen(ai.getTailLocation());
1205
drawLine(g, wnd, c1.x, c1.y, c2.x, c2.y);
1208
// draw dots in all connected nodes
1209
g2.setStroke(solidLine);
1210
for (Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )
1212
NodeInst oNi = it.next();
1213
if (!markObj.contains(oNi)) continue;
1215
Point c = wnd.databaseToScreen(oNi.getTrueCenter());
1216
g.fillOval(c.x-4, c.y-4, 8, 8);
1218
// connect the center dots to the input arcs
1219
Point2D nodeCenter = oNi.getTrueCenter();
1220
for(Iterator<Connection> pIt = oNi.getConnections(); pIt.hasNext(); )
1222
Connection con = pIt.next();
1223
ArcInst ai = con.getArc();
1224
if (!markObj.contains(ai)) continue;
1225
Point2D arcEnd = con.getLocation();
1226
if (arcEnd.getX() != nodeCenter.getX() || arcEnd.getY() != nodeCenter.getY())
1228
Point c1 = wnd.databaseToScreen(arcEnd);
1229
Point c2 = wnd.databaseToScreen(nodeCenter);
1230
//g2.setStroke(dottedLine);
1231
//if (c1.distance(c2) < 15) g2.setStroke(solidLine);
1232
drawLine(g, wnd, c1.x, c1.y, c2.x, c2.y);
1236
g2.setStroke(origStroke);
1241
// switch back to old color if switched
1242
if (oldColor != null)
1243
g.setColor(oldColor);
1246
void getHighlightedEObjs(Highlighter highlighter, List<Geometric> list, boolean wantNodes, boolean wantArcs)
1248
getHighlightedEObjsInternal(getGeometric(), list, wantNodes, wantArcs);
1251
void getHighlightedNodes(Highlighter highlighter, List<NodeInst> list)
1253
getHighlightedNodesInternal(getGeometric(), list);
1256
void getHighlightedArcs(Highlighter highlighter, List<ArcInst> list)
1258
getHighlightedArcsInternal(getGeometric(), list);
1261
void getHighlightedNetworks(Set<Network> nets, Netlist netlist)
1263
ElectricObject eObj = eobj;
1264
if (eObj instanceof NodeInst)
1266
NodeInst ni = (NodeInst)eObj;
1267
if (ni.getNumPortInsts() == 1)
1269
PortInst pi = ni.getOnlyPortInst();
1270
if (pi != null) eObj = pi;
1273
if (eObj instanceof PortInst)
1275
PortInst pi = (PortInst)eObj;
1276
nets = NetworkTool.getNetworksOnPort(pi, netlist, nets);
1277
// boolean added = false;
1278
// for(Iterator<Connection> aIt = pi.getNodeInst().getConnections(); aIt.hasNext(); )
1280
// Connection con = aIt.next();
1281
// ArcInst ai = con.getArc();
1282
// int wid = netlist.getBusWidth(ai);
1283
// for(int i=0; i<wid; i++)
1285
// Network net = netlist.getNetwork(ai, i);
1295
// Network net = netlist.getNetwork(pi);
1296
// if (net != null) nets.add(net);
1298
} else if (eObj instanceof ArcInst)
1300
ArcInst ai = (ArcInst)eObj;
1301
int width = netlist.getBusWidth(ai);
1302
for(int i=0; i<width; i++)
1304
Network net = netlist.getNetwork((ArcInst)eObj, i);
1305
if (net != null) nets.add(net);
1310
Rectangle2D getHighlightedArea(EditWindow wnd)
1312
ElectricObject eObj = eobj;
1313
if (eObj instanceof PortInst) eObj = ((PortInst)eObj).getNodeInst();
1314
if (eObj instanceof Geometric)
1316
Geometric geom = (Geometric)eObj;
1317
return geom.getBounds();
1322
public Geometric getGeometric()
1324
Geometric retVal = null;
1325
if (eobj instanceof PortInst) retVal = ((PortInst)eobj).getNodeInst(); else
1326
if (eobj instanceof Geometric) retVal = (Geometric)eobj;
1330
boolean overHighlighted(EditWindow wnd, int x, int y, Highlighter highlighter)
1332
Point2D slop = wnd.deltaScreenToDatabase(Highlighter.EXACTSELECTDISTANCE*2, Highlighter.EXACTSELECTDISTANCE*2);
1333
double directHitDist = slop.getX();
1334
Point2D start = wnd.screenToDatabase(x, y);
1335
Rectangle2D searchArea = new Rectangle2D.Double(start.getX(), start.getY(), 0, 0);
1337
ElectricObject eobj = this.eobj;
1338
if (eobj instanceof PortInst) eobj = ((PortInst)eobj).getNodeInst();
1339
if (eobj instanceof Geometric)
1341
boolean specialSelect = ToolBar.isSelectSpecial();
1342
Highlight2 got = Highlighter.checkOutObject((Geometric)eobj, true, false, specialSelect, searchArea, wnd, directHitDist, false);
1343
if (got == null) return false;
1344
if (!(got instanceof HighlightEOBJ))
1345
System.out.println("Error?");
1346
ElectricObject hObj = got.getElectricObject();
1347
ElectricObject hReal = hObj;
1348
if (hReal instanceof PortInst) hReal = ((PortInst)hReal).getNodeInst();
1349
for(Highlight2 alreadyDone : highlighter.getHighlights())
1351
if (!(alreadyDone instanceof HighlightEOBJ)) continue;
1352
HighlightEOBJ alreadyHighlighted = (HighlightEOBJ)alreadyDone;
1353
ElectricObject aHObj = alreadyHighlighted.getElectricObject();
1354
ElectricObject aHReal = aHObj;
1355
if (aHReal instanceof PortInst) aHReal = ((PortInst)aHReal).getNodeInst();
1356
if (hReal == aHReal)
1358
// found it: adjust the port/point
1359
if (hObj != aHObj || alreadyHighlighted.point != ((HighlightEOBJ)got).point)
1361
alreadyHighlighted.eobj = got.getElectricObject();
1362
alreadyHighlighted.point = ((HighlightEOBJ)got).point;
1363
synchronized(highlighter) {
1364
highlighter.setChanged(true);
1375
public String getInfo()
1377
String description = "";
1378
ElectricObject realObj = eobj;
1380
if (realObj instanceof PortInst)
1381
realObj = ((PortInst)realObj).getNodeInst();
1382
if (realObj instanceof NodeInst)
1384
NodeInst ni = (NodeInst)realObj;
1385
description = "Node " + ni.describe(true);
1386
} else if (realObj instanceof ArcInst)
1388
ArcInst ai = (ArcInst)eobj;
1389
description = "Arc " + ai.describe(true);
1395
class HighlightText extends Highlight2
1397
/** The highlighted object. */ protected final ElectricObject eobj;
1398
/** The highlighted variable. */ protected final Variable.Key varKey;
1400
public HighlightText(ElectricObject e, Cell c, Variable.Key key)
1406
if (key == NodeInst.NODE_NAME || key == NodeInst.NODE_PROTO)
1407
cls = NodeInst.class;
1408
else if (key == ArcInst.ARC_NAME)
1409
cls = ArcInst.class;
1410
else if (key == Export.EXPORT_NAME)
1412
if (cls != null && !cls.isInstance(e))
1413
throw new IllegalArgumentException(key + " in " + e);
1416
void internalDescribe(StringBuffer desc)
1420
if (varKey == NodeInst.NODE_NAME)
1422
desc.append(", name: ");
1423
desc.append(((NodeInst)eobj).getName());
1424
} else if (varKey == NodeInst.NODE_PROTO)
1426
desc.append(", instance: ");
1427
desc.append(((NodeInst)eobj).getProto().getName());
1428
} else if (varKey == ArcInst.ARC_NAME)
1430
desc.append(", name: ");
1431
desc.append(((ArcInst)eobj).getName());
1432
} else if (varKey == Export.EXPORT_NAME)
1434
desc.append(", export: ");
1435
desc.append(((Export)eobj).getName());
1438
desc.append(", var: ");
1439
desc.append(eobj.getParameterOrVariable(varKey).describe(-1));
1444
public ElectricObject getElectricObject() { return eobj; }
1446
// creating so HighlightText is not a public class
1447
public boolean isHighlightText() { return true; }
1449
public Variable.Key getVarKey() { return varKey; }
1453
if (!super.isValid()) return false;
1454
if (eobj == null || varKey == null) return false;
1455
if (!eobj.isLinked()) return false;
1457
if (varKey == NodeInst.NODE_NAME ||
1458
varKey == ArcInst.ARC_NAME ||
1459
varKey == NodeInst.NODE_PROTO ||
1460
varKey == Export.EXPORT_NAME) return true;
1461
return eobj.getParameterOrVariable(varKey) != null;
1464
boolean sameThing(Highlight2 obj)
1466
if (this == obj) return (true);
1468
// Consider already obj==null
1469
if (obj == null || getClass() != obj.getClass())
1472
HighlightText other = (HighlightText)obj;
1473
if (eobj != other.eobj) return false;
1474
if (cell != other.cell) return false;
1475
if (varKey != other.varKey) return false;
1479
public void showInternalHighlight(EditWindow wnd, Graphics g, int highOffX, int highOffY,
1480
boolean onlyHighlight, boolean setConnected)
1482
Graphics2D g2 = (Graphics2D)g;
1483
Point2D [] points = Highlighter.describeHighlightText(wnd, eobj, varKey);
1484
if (points == null) return;
1485
Point2D [] linePoints = new Point2D[2];
1486
for(int i=0; i<points.length; i += 2)
1488
linePoints[0] = points[i];
1489
linePoints[1] = points[i+1];
1490
drawOutlineFromPoints(wnd, g, linePoints, highOffX, highOffY, false, false);
1494
// this is the only thing highlighted: show the attached object
1495
ElectricObject eObj = eobj;
1496
if (eObj != null && eObj instanceof Geometric)
1498
Geometric geom = (Geometric)eObj;
1499
if (geom instanceof ArcInst || !((NodeInst)geom).isInvisiblePinWithText())
1501
Point c = wnd.databaseToScreen(geom.getTrueCenter());
1502
int lowX = Integer.MAX_VALUE, highX = Integer.MIN_VALUE;
1503
int lowY = Integer.MAX_VALUE, highY = Integer.MIN_VALUE;
1504
for(int i=0; i<points.length; i++)
1506
Point a = wnd.databaseToScreen(points[i]);
1507
if (a.x < lowX) lowX = a.x;
1508
if (a.x > highX) highX = a.x;
1509
if (a.y < lowY) lowY = a.y;
1510
if (a.y > highY) highY = a.y;
1512
int cX = (lowX+highX)/2;
1513
int cY = (lowY+highY)/2;
1514
if (Math.abs(cX - c.x) > 4 || Math.abs(cY - c.y) > 4)
1516
g.fillOval(c.x-4, c.y-4, 8, 8);
1517
g2.setStroke(dottedLine);
1518
drawLine(g, wnd, c.x, c.y, cX, cY);
1519
g2.setStroke(solidLine);
1527
// * Method to tell whether this Highlight is text that stays with its node.
1528
// * The two possibilities are (1) text on invisible pins
1529
// * (2) export names, when the option to move exports with their labels is requested.
1530
// * @return true if this Highlight is text that should move with its node.
1532
// public boolean nodeMovesWithText()
1534
// if (varKey != null)
1536
// // moving variable text
1537
// if (!(eobj instanceof NodeInst)) return false;
1538
// NodeInst ni = (NodeInst)eobj;
1539
// if (ni.isInvisiblePinWithText()) return true;
1542
// // moving export text
1543
// if (!(eobj instanceof Export)) return false;
1544
// Export pp = (Export)eobj;
1545
// if (pp.getOriginalPort().getNodeInst().getProto() == Generic.tech.invisiblePinNode) return true;
1546
// if (User.isMoveNodeWithExport()) return true;
1551
public Geometric getGeometric()
1553
if (DisplayedText.objectMovesWithText(eobj, varKey))
1555
if (eobj instanceof Export) return ((Export)eobj).getOriginalPort().getNodeInst();
1556
if (eobj instanceof Geometric) return (Geometric)eobj;
1561
void getHighlightedEObjs(Highlighter highlighter, List<Geometric> list, boolean wantNodes, boolean wantArcs)
1563
getHighlightedEObjsInternal(getGeometric(), list, wantNodes, wantArcs);
1566
void getHighlightedNodes(Highlighter highlighter, List<NodeInst> list)
1568
getHighlightedNodesInternal(getGeometric(), list);
1571
void getHighlightedArcs(Highlighter highlighter, List<ArcInst> list)
1573
getHighlightedArcsInternal(getGeometric(), list);
1576
void getHighlightedNetworks(Set<Network> nets, Netlist netlist)
1578
if (/*varKey == null &&*/ eobj instanceof Export)
1580
Export pp = (Export)eobj;
1581
int width = netlist.getBusWidth(pp);
1582
for(int i=0; i<width; i++)
1584
Network net = netlist.getNetwork(pp, i);
1585
if (net != null) nets.add(net);
1590
DisplayedText makeDisplayedText()
1593
return new DisplayedText(eobj, varKey);
1597
void getHighlightedText(List<DisplayedText> list, boolean unique, List<Highlight2> getHighlights)
1599
DisplayedText dt = makeDisplayedText();
1600
if (dt == null) return;
1601
if (list.contains(dt)) return;
1603
// if this text is on a selected object, don't include the text
1606
ElectricObject onObj = null;
1609
if (eobj instanceof Export)
1611
onObj = ((Export)eobj).getOriginalPort().getNodeInst();
1612
} else if (eobj instanceof PortInst)
1614
onObj = ((PortInst)eobj).getNodeInst();
1615
} else if (eobj instanceof Geometric)
1621
// now see if the object is in the list
1624
boolean found = false;
1625
for(Highlight2 oH : getHighlights)
1627
if (!(oH instanceof HighlightEOBJ)) continue;
1628
ElectricObject fobj = ((HighlightEOBJ)oH).eobj;
1629
if (fobj instanceof PortInst) fobj = ((PortInst)fobj).getNodeInst();
1630
if (fobj == onObj) { found = true; break; }
1640
Rectangle2D getHighlightedArea(EditWindow wnd)
1644
Poly poly = eobj.computeTextPoly(wnd, varKey);
1645
if (poly != null) return poly.getBounds2D();
1650
boolean overHighlighted(EditWindow wnd, int x, int y, Highlighter highlighter)
1652
Point2D start = wnd.screenToDatabase(x, y);
1653
Poly poly = eobj.computeTextPoly(wnd, varKey);
1655
if (poly.isInside(start)) return true;
1659
public String describe()
1661
String description = "Unknown";
1662
if (varKey != null && eobj != null)
1664
if (varKey == NodeInst.NODE_NAME)
1666
description = "Node name for " + ((NodeInst)eobj).describe(true);
1667
} else if (varKey == ArcInst.ARC_NAME)
1669
description = "Arc name for " + ((ArcInst)eobj).describe(true);
1670
} else if (varKey == Export.EXPORT_NAME)
1672
description = "Export '" + ((Export)eobj).getName() + "'";
1673
} else if (varKey == NodeInst.NODE_PROTO)
1675
description = "Cell instance name " + ((NodeInst)eobj).describe(true);
1678
description = eobj.getParameterOrVariable(varKey).getFullDescription(eobj);
1684
public String getInfo()
1686
return "Text: " + describe();