View Javadoc

1   // Copyright 2004-2005, FreeHEP.
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/*HepRepInstance>*/ pickedInstances = new HashSet(); 
53      private transient Set/*HepRepInstance>*/ selectedInstances = new HashSet(); 
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/*<HepRepInstance*/ selectedInstances) {
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         // update selection rectangle
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 }