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.HepRepInstance;
16
17 import hep.wired.edit.SetTranslate;
18 import hep.wired.interaction.DefaultInteractionHandler;
19 import hep.wired.interaction.DragRectangleToScale;
20 import hep.wired.services.GraphicsPanel;
21 import hep.wired.services.RecordPlot;
22 import hep.wired.util.NullEvent;
23 import hep.wired.util.XYZindices;
24 import hep.wired.image.WiredBaseImage;
25
26 import hep.wired.heprep.graphicspanel.HepRepPanel;
27 import hep.wired.heprep.plugin.WiredPlugin;
28 import hep.wired.heprep.image.WiredImage;
29 import hep.wired.heprep.interaction.HepRepInfoPanel;
30 import hep.wired.heprep.util.Arrow;
31 import hep.wired.heprep.util.InsideRectanglePathConstructor;
32 import hep.wired.heprep.util.NearestPointPathConstructor;
33 import hep.wired.heprep.util.PathGraphics2D;
34 import hep.wired.heprep.util.WiredHepRepUtil;
35 import hep.wired.heprep.services.Projection;
36
37 /***
38 * Hover mouse near to object to show info.
39 *
40 * @author Mark Donszelmann
41 * @version $Id: DragRectangleToPick.java 2087 2005-07-20 23:49:09Z duns $
42 */
43 public class DragRectangleToPick extends DefaultInteractionHandler implements PickHandler, XYZindices {
44
45 private static final int cursorSize = 32;
46
47 private double x0;
48 private double y0;
49 private double x;
50 private double y;
51 private transient HepRepInstance currentInstance;
52 private transient Set
53 private transient Set
54
55 private Rectangle2D rectangle;
56 private boolean pickWhileDragging = false;
57
58 public DragRectangleToPick() {
59 super("Drag Rectangle 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("Rectangle%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(WiredBaseImage.getBestCursor("RectangleCursor%w", cursorSize, cursorSize));
76 }
77
78 public void setRecord(RecordPlot plot, Object record) {
79 info().setInfo((HepRep)record);
80 update(plot);
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 defineShape(plot, x, y);
93 selectInstances(plot);
94 }
95
96 public void setSelected(RecordPlot plot, Set
97 this.selectedInstances = selectedInstances;
98
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 plot.drawShape(rectangle);
106 }
107 }
108
109 public boolean isRegionZoomable() {
110 return rectangle != null;
111 }
112
113 public void zoomIntoRegion(RecordPlot plot) {
114 if (!isRegionZoomable()) return;
115
116 DragRectangleToScale.translateAndScale(plot, rectangle, true);
117 clearShape(plot);
118 }
119
120 public boolean isPickedTranslateable() {
121 return selectedInstances.size() == 1;
122 }
123
124 public void translateToPicked(RecordPlot plot) {
125 if (!isPickedTranslateable()) return;
126
127 double[] t = WiredHepRepUtil.getCenterPoint((HepRepInstance)selectedInstances.iterator().next());
128 if (t != null) {
129 plot.postEdit(new SetTranslate(-t[X], -t[Y], -t[Z]));
130 clearShape(plot);
131 }
132 }
133
134 public boolean canSetPickWhileDragging() {
135 return true;
136 }
137
138 public void setPickWhileDragging(boolean state) {
139 pickWhileDragging = state;
140 }
141
142 public boolean isPickWhileDragging() {
143 return pickWhileDragging;
144 }
145
146 public void reset(RecordPlot plot, InputEvent event) {
147 Application.getApplication().setStatusMessage("Click and drag a rectangle to pick objects and show information.");
148 clearShape(plot);
149 }
150
151 public void mouseButton1Clicked(RecordPlot plot, MouseEvent event) {
152 reset(plot, event);
153 }
154
155 public void mouseButton1DragStarted(RecordPlot plot, MouseEvent event) {
156 startShape(event.getX(), event.getY());
157 defineShape(plot, event.getX(), event.getY());
158 selectInstances(plot);
159 }
160
161 public void mouseButton1Dragged(RecordPlot plot, MouseEvent event) {
162 defineShape(plot, event.getX(), event.getY());
163 if (pickWhileDragging) selectInstances(plot);
164 }
165
166 public void mouseButton1DragEnded(RecordPlot plot, MouseEvent event) {
167 defineShape(plot, event.getX(), event.getY());
168 selectInstances(plot);
169 }
170
171 public void mouseEntered(RecordPlot plot, MouseEvent event) {
172 info().setInteractionHandler(this, plot);
173 info().setInfo((HepRep)plot.getRecord());
174 plot.requestFocusInWindow();
175 changeCursor(plot, event);
176 }
177
178 public void mouseWheelMoved(RecordPlot plot, MouseWheelEvent event) {
179 super.mouseWheelMoved(plot, event);
180
181
182 double s = getLastScale();
183 double w2 = plot.getWidth()/2;
184 double h2 = plot.getHeight()/2;
185 startShape((x0 - w2)*s + w2, (y0 - h2)*s + h2);
186 defineShape(plot, (x - w2)*s + w2, (y - h2)*s + h2);
187
188 selectInstances(plot);
189 }
190
191 private void clearShape(RecordPlot plot) {
192 startShape(0, 0);
193 x = 0;
194 y = 0;
195
196 info().setInfo((Set)null);
197
198 plot.drawShape(null);
199 }
200
201 private void startShape(double x0, double y0) {
202 this.x0 = x0;
203 this.y0 = y0;
204 rectangle = null;
205 }
206
207 private void defineShape(RecordPlot plot, double x, double y) {
208 this.x = x;
209 this.y = y;
210
211 double w = Math.abs(x - x0);
212 double h = Math.abs(y - y0);
213 if ((w != 0) && (h != 0)) {
214 rectangle = new Rectangle2D.Double(Math.min(x, x0), Math.min(y, y0), w, h);
215 } else {
216 rectangle = null;
217 }
218
219 plot.drawShape(rectangle);
220 }
221
222 private void selectInstances(RecordPlot plot) {
223 pickedInstances.clear();
224 selectedInstances.clear();
225
226 if (rectangle != null) {
227 InsideRectanglePathConstructor pathConstructor = new InsideRectanglePathConstructor(rectangle) {
228 protected void lineFound(Line2D line) {
229 if (!selectedInstances.contains(currentInstance)) {
230 pickedInstances.add(currentInstance);
231 selectedInstances.add(currentInstance);
232 }
233 }
234 };
235
236 draw(plot, pathConstructor);
237 }
238
239 if (pickedInstances.isEmpty()) {
240 info().setInfo((Set)null);
241 } else {
242 info().setInfo(pickedInstances);
243 }
244 }
245
246
247 private void draw(RecordPlot plot, PathConstructor pathConstructor) {
248
249 HepRepPanel panel = (HepRepPanel)plot.getGraphicsPanel();
250 panel.setHepRepInstanceListener(new HepRepPanel.InstanceListener() {
251 public void currentHepRepInstance(HepRepInstance instance) {
252 currentInstance = instance;
253 }
254 });
255
256 PathGraphics2D pathGraphics = new PathGraphics2D(pathConstructor);
257 List layers = info().getLayers();
258 Set types = info().getTypes();
259 panel.draw(pathGraphics, true, layers.isEmpty() ? null : layers, types.isEmpty() ? null : types, true);
260
261 panel.setHepRepInstanceListener(null);
262 }
263
264 public void setSize(RecordPlot plot, int width, int height) {
265 if ((getWidth() > 0) && (getHeight() > 0)) {
266 double sx = (double)width / getWidth();
267 double sy = (double)height / getHeight();
268 x0 = (int)(x0*sx);
269 y0 = (int)(y0*sy);
270 defineShape(plot, (int)(x*sx), (int)(y*sy));
271 selectInstances(plot);
272 } else {
273 reset(plot, null);
274 }
275 super.setSize(plot, width, height);
276 }
277
278 public String toString() {
279 return "Drag Rectangle to Pick";
280 }
281 }