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.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/*<HepRepInstance*/ selectedInstances) {
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         // FIXME WIRED-382, we may want to stick to the same object...
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         // Farthest corner
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 }