1
2 package hep.wired.heprep.interaction;
3
4 import java.awt.*;
5 import java.awt.event.*;
6 import java.awt.geom.*;
7 import java.util.*;
8 import java.util.List;
9 import javax.swing.*;
10
11 import org.freehep.application.Application;
12 import org.freehep.graphicsio.PathConstructor;
13
14 import hep.graphics.heprep.HepRep;
15 import hep.graphics.heprep.HepRepPoint;
16 import hep.graphics.heprep.HepRepInstance;
17
18 import hep.wired.edit.SetTranslate;
19 import hep.wired.interaction.DefaultInteractionHandler;
20 import hep.wired.interaction.DragRectangleToScale;
21 import hep.wired.services.GraphicsPanel;
22 import hep.wired.services.RecordPlot;
23 import hep.wired.util.NullEvent;
24 import hep.wired.util.XYZindices;
25 import hep.wired.image.WiredBaseImage;
26
27 import hep.wired.heprep.graphicspanel.HepRepPanel;
28 import hep.wired.heprep.plugin.WiredPlugin;
29 import hep.wired.heprep.image.WiredImage;
30 import hep.wired.heprep.interaction.HepRepInfoPanel;
31 import hep.wired.heprep.util.Arrow;
32 import hep.wired.heprep.util.InsideRectanglePathConstructor;
33 import hep.wired.heprep.util.NearestPointPathConstructor;
34 import hep.wired.heprep.util.PathGraphics2D;
35 import hep.wired.heprep.util.WiredHepRepUtil;
36 import hep.wired.heprep.services.Projection;
37
38 /***
39 * Hover mouse near to object to show info.
40 *
41 * @author Mark Donszelmann
42 * @version $Id: HoverToPick.java 2087 2005-07-20 23:49:09Z duns $
43 */
44 public class HoverToPick extends DefaultInteractionHandler implements PickHandler, XYZindices {
45
46 private int x;
47 private int y;
48 private transient HepRepInstance currentInstance;
49 private transient HepRepInstance pickedInstance;
50 private boolean fixed = false;
51
52 private boolean pickWhileMoving = true;
53 private Point2D point;
54 private double minimumDistanceSq;
55
56 /***
57 */
58 public HoverToPick() {
59 super("Hover near Object to Pick");
60 }
61
62 private HepRepInfoPanel info() {
63 return WiredPlugin.getPlugin().getHepRepInfoPanel();
64 }
65
66 public Icon getIcon(int size) {
67 return WiredBaseImage.getIcon("PickInfo%w", size);
68 }
69
70 public boolean isSupportedBy(GraphicsPanel panel) {
71 return panel instanceof HepRepPanel;
72 }
73
74 public void changeCursor(RecordPlot plot, InputEvent event) {
75 plot.setCursor(Cursor.getDefaultCursor());
76 }
77
78 public void setRecord(RecordPlot plot, Object record) {
79 update(plot);
80 info().setInfo((HepRep)record);
81 }
82
83 public void setSelected(RecordPlot plot, boolean selected) {
84 if (selected) {
85 update(plot);
86 } else {
87 info().setInfo((Set)null);
88 }
89 }
90
91 public void update(RecordPlot plot) {
92 if ((plot.getWidth() != 0) && (plot.getHeight() != 0)) {
93 defineNearestPoint(plot, x, y);
94 defineShape(plot);
95 }
96 }
97
98 public void setSelected(RecordPlot plot, Set
99 Set highlightInstances = WiredHepRepUtil.getInstancesAndChildren(selectedInstances);
100
101 GraphicsPanel panel = plot.getGraphicsPanel();
102 if (panel instanceof HepRepPanel) {
103 ((HepRepPanel)panel).highlight(highlightInstances.size() > 0 ? highlightInstances : null);
104 ((Component)panel).repaint();
105 }
106 }
107
108 public boolean isRegionZoomable() {
109 return false;
110 }
111
112 public void zoomIntoRegion(RecordPlot plot) {
113 }
114
115 public boolean isPickedTranslateable() {
116 return fixed && (pickedInstance != null) && (pickedInstance.getPoints().size() > 0);
117 }
118
119 public void translateToPicked(RecordPlot plot) {
120 if (!isPickedTranslateable()) return;
121
122 double[] t = WiredHepRepUtil.getCenterPoint(pickedInstance);
123 if (t != null) {
124 plot.postEdit(new SetTranslate(-t[X], -t[Y], -t[Z]));
125 fixed = false;
126 clearShape(plot);
127 }
128 }
129
130 public boolean canSetPickWhileDragging() {
131 return true;
132 }
133
134 public void setPickWhileDragging(boolean state) {
135 pickWhileMoving = state;
136 }
137
138 public boolean isPickWhileDragging() {
139 return pickWhileMoving;
140 }
141
142 public void reset(RecordPlot plot, InputEvent event) {
143 Application.getApplication().setStatusMessage("Hover over or near an object to show information.");
144 fixed = false;
145 clearShape(plot);
146 }
147
148 public void mouseMoved(RecordPlot plot, MouseEvent event) {
149 changeCursor(plot, event);
150 if (!fixed) {
151 if (pickWhileMoving) {
152 defineNearestPoint(plot, event.getX(), event.getY());
153 } else {
154 definePoint(plot, event.getX(), event.getY());
155 }
156 defineShape(plot);
157 }
158 }
159
160 public void mouseButton1Clicked(RecordPlot plot, MouseEvent event) {
161 fixed = pickWhileMoving ? !fixed : true;
162 defineNearestPoint(plot, event.getX(), event.getY());
163 defineShape(plot);
164 }
165
166 public void mouseEntered(RecordPlot plot, MouseEvent event) {
167 if (!fixed) {
168 info().setInteractionHandler(this, plot);
169 info().setInfo((HepRep)plot.getRecord());
170 plot.requestFocusInWindow();
171 if (pickWhileMoving) {
172 defineNearestPoint(plot, event.getX(), event.getY());
173 } else {
174 definePoint(plot, event.getX(), event.getY());
175 }
176 defineShape(plot);
177 }
178 }
179
180 public void mouseExited(RecordPlot plot, MouseEvent event) {
181 if (!fixed) {
182 clearShape(plot);
183 }
184 }
185
186 public void mouseWheelMoved(RecordPlot plot, MouseWheelEvent event) {
187 super.mouseWheelMoved(plot, event);
188
189 fixed = false;
190
191 mouseMoved(plot, event);
192 }
193
194 private void clearShape(RecordPlot plot) {
195 x = 0;
196 y = 0;
197
198 info().setInfo((Set)null);
199
200 plot.drawShape(null);
201 }
202
203 private void definePoint(RecordPlot plot, int x, int y) {
204 this.x = x;
205 this.y = y;
206 point = new Point2D.Double(x, y);
207
208 pickedInstance = null;
209 }
210
211 private void defineNearestPoint(RecordPlot plot, int x, int y) {
212 definePoint(plot, x, y);
213
214 minimumDistanceSq = 0;
215 NearestPointPathConstructor pathConstructor = new NearestPointPathConstructor(point) {
216 protected void pointFound(Point2D p, double distanceSq, boolean closer) {
217 if (closer) {
218 minimumDistanceSq = distanceSq;
219 pickedInstance = currentInstance;
220 }
221 }
222 };
223 draw(plot, pathConstructor);
224
225 Point2D nearestPoint = pathConstructor.getNearestPoint();
226 if (nearestPoint != null) point = nearestPoint;
227 }
228
229 private void defineShape(RecordPlot plot) {
230 info().setInfo(pickedInstance);
231
232
233 Point2D corner = new Point2D.Double(
234 (point.getX() > plot.getX()+plot.getWidth()/2) ? plot.getX() : plot.getX() + plot.getWidth(),
235 (point.getY() > plot.getY()+plot.getHeight()/2) ? plot.getY() : plot.getY() + plot.getHeight()
236 );
237
238 GeneralPath path = new GeneralPath(new Arrow(corner, point, 20, 16, 70, false));
239 if (!fixed && pickWhileMoving) {
240 double distance = Math.max(Math.sqrt(minimumDistanceSq), 40);
241 path.append(new Ellipse2D.Double(point.getX() - distance, point.getY() - distance, distance*2, distance*2), false);
242 }
243 plot.drawShape(path);
244 }
245
246 private void draw(RecordPlot plot, PathConstructor pathConstructor) {
247
248 HepRepPanel panel = (HepRepPanel)plot.getGraphicsPanel();
249 panel.setHepRepInstanceListener(new HepRepPanel.InstanceListener() {
250 public void currentHepRepInstance(HepRepInstance instance) {
251 currentInstance = instance;
252 }
253 });
254
255 PathGraphics2D pathGraphics = new PathGraphics2D(pathConstructor);
256 List layers = info().getLayers();
257 Set types = info().getTypes();
258 panel.draw(pathGraphics, true, layers.isEmpty() ? null : layers, types.isEmpty() ? null : types, true);
259
260 panel.setHepRepInstanceListener(null);
261 }
262
263 public void setSize(RecordPlot plot, int width, int height) {
264 reset(plot, null);
265 super.setSize(plot, width, height);
266 }
267
268 public String toString() {
269 return "Hover to Pick";
270 }
271 }