JAL-3026 srcjar files for VARNA and log4j
[jalview.git] / srcjar / fr / orsay / lri / varna / applications / templateEditor / MouseControler.java
1 package fr.orsay.lri.varna.applications.templateEditor;
2
3 import java.awt.Point;
4 import java.awt.event.MouseEvent;
5 import java.awt.event.MouseListener;
6 import java.awt.event.MouseMotionListener;
7 import java.awt.event.MouseWheelEvent;
8 import java.awt.event.MouseWheelListener;
9 import java.awt.geom.Point2D;
10
11
12
13 public class MouseControler implements MouseListener, MouseMotionListener, MouseWheelListener {
14
15         private int _granularity = 8;
16         private final int HYSTERESIS_DISTANCE = 10;
17         TemplatePanel _sp;
18         GraphicalTemplateElement _elem;
19         TemplateEditorPanelUI _ui;
20         private GraphicalTemplateElement.RelativePosition _currentMode = Helix.RelativePosition.RP_OUTER;
21         private boolean movingView = false;
22         private Point2D.Double _clickedPos = new Point2D.Double();
23         private Point _clickedPosScreen = new Point();
24
25         public MouseControler(TemplatePanel sp, TemplateEditorPanelUI ui)
26         {
27                 _sp = sp;
28                 _elem = null;
29                 _ui = ui;
30         }
31
32         public void mouseWheelMoved(MouseWheelEvent e) {
33                 if (e.getWheelRotation() == -1) {
34                         _sp.zoomIn();
35                 }
36                 else {
37                         _sp.zoomOut();
38                 }
39                 e.consume();
40         }
41
42
43         public void mouseClicked(MouseEvent arg0) {
44         }
45
46         public void mouseEntered(MouseEvent arg0) {
47                 // TODO Auto-generated method stub
48
49         }
50
51         public void mouseExited(MouseEvent arg0) {
52                 // TODO Auto-generated method stub
53
54         }
55
56
57         
58         /**
59          * Get mouse position in logical coordinates, ie. those used in the template XML file.
60          * It differs from the screen coordinates relative to panel because of the scaling factor.
61          */
62         public Point2D.Double getLogicalMouseCoords(MouseEvent event) {
63                 return new Point2D.Double(event.getX()/_sp.getScaleFactor(), event.getY()/_sp.getScaleFactor());
64         }
65
66         public void mousePressed(MouseEvent arg0) {
67                 movingView = false;
68                 _clickedPos = new Point2D.Double(arg0.getX(), arg0.getY());
69                 _clickedPosScreen.x = arg0.getXOnScreen();
70                 _clickedPosScreen.y = arg0.getYOnScreen();
71                 
72                 // middle-click
73                 if (arg0.getButton() == MouseEvent.BUTTON2) {
74                         movingView = true;
75                         
76                 } else {
77                         
78                         Point2D.Double logicalMousePos = getLogicalMouseCoords(arg0);
79                         GraphicalTemplateElement elem = _sp.getElementAt(logicalMousePos.getX(), logicalMousePos.getY());
80                         _sp.Unselect();
81                         
82                         if (elem==null)
83                         {
84                                 if (arg0.getButton()==MouseEvent.BUTTON1
85                                                 && _ui.getSelectedTool() == TemplateEditorPanelUI.Tool.CREATE_HELIX)
86                                 {
87                                         _currentMode = Helix.RelativePosition.RP_EDIT_START;
88                                 }
89                                 else if ((arg0.getButton()==MouseEvent.BUTTON1
90                                                 && _ui.getSelectedTool() == TemplateEditorPanelUI.Tool.CREATE_UNPAIRED))
91                                 {
92                                         // Create a new unpaired region
93                                         UnpairedRegion n = new UnpairedRegion(logicalMousePos.getX(),logicalMousePos.getY(),_sp.getTemplate());
94                                         n.setDominantColor(_sp.nextBackgroundColor());
95                                         _ui.addElementUI(n);
96                                         _sp.setSelected(n);
97                                         _sp.repaint();
98                                         _elem = n;
99                                         _currentMode = GraphicalTemplateElement.RelativePosition.RP_EDIT_START;
100                                 }
101                         }
102                         else if (arg0.getButton()==MouseEvent.BUTTON1) 
103                         {
104                                 _currentMode = elem.getRelativePosition(logicalMousePos.getX(), logicalMousePos.getY());
105                                 _sp.setSelected(elem);
106                                 _elem = elem;
107                                 switch (_currentMode)
108                                 {
109                                 case RP_EDIT_START:
110                                 case RP_EDIT_END:
111                                 case RP_EDIT_TANGENT_5:
112                                 case RP_EDIT_TANGENT_3:
113                                         break;
114                                 case RP_INNER_MOVE:
115                                         break;
116                                 case RP_INNER_GENERAL:
117                                         _currentMode = Helix.RelativePosition.RP_INNER_MOVE; 
118                                         break;
119                                 case RP_CONNECT_END3:
120                                 case RP_CONNECT_END5:
121                                 case RP_CONNECT_START5:
122                                 case RP_CONNECT_START3:
123                                 {
124                                         Couple<GraphicalTemplateElement,GraphicalTemplateElement.RelativePosition> al = _sp.getPartner(elem, _currentMode);
125                                         boolean isConnected = (al!=null); 
126                                         if (isConnected)
127                                         {
128                                                 Connection c = _sp.getConnection(elem, _currentMode);
129                                                 _ui.removeConnectionUI(c);
130                                                 GraphicalTemplateElement p1 = c._h1;
131                                                 GraphicalTemplateElement p2 = c._h2;
132                                                 boolean p1IsHelix = (p1 instanceof Helix);
133                                                 boolean p1IsUnpaired = (p1 instanceof UnpairedRegion);
134                                                 boolean p2IsHelix = (p2 instanceof Helix);
135                                                 boolean p2IsUnpaired = (p2 instanceof UnpairedRegion);
136                                                 boolean p1StillAttached = (p1 == elem);
137         
138                                                 if ((p1IsUnpaired && p2IsHelix))
139                                                 {
140                                                         p1StillAttached = false;
141                                                 }
142                                                 if (p1StillAttached)
143                                                 { 
144                                                         _elem = p2;
145                                                         _currentMode = c._edge2;
146                                                 }
147                                                 else if (!p1StillAttached)
148                                                 { 
149                                                         _elem=p1;
150                                                         _currentMode = c._edge1;
151                                                 }
152         
153                                         }
154                                         if (_elem instanceof Helix)
155                                         { 
156                                                 _sp.setPointerPos(new Point2D.Double(logicalMousePos.getX(),logicalMousePos.getY()));
157                                                 _sp.setSelectedEdge(_currentMode);
158                                         }
159                                         _sp.setSelected(_elem);
160                                 }
161                                 break;
162                                 case RP_OUTER:
163                                         _sp.Unselect();
164                                         _elem = null;
165                                 }
166                                 _sp.repaint();
167                         }
168                 }
169         }
170
171         public void mouseReleased(MouseEvent arg0) {
172                 movingView = false;
173                 Point2D.Double logicalMousePos = getLogicalMouseCoords(arg0);
174                 if (_elem!=null)
175                 {
176                         switch (_currentMode)
177                         {
178                         case RP_EDIT_START:
179                         case RP_EDIT_END:
180                         {
181                                 if (_elem instanceof Helix)
182                                 {
183                                         Helix h = (Helix) _elem;
184                                         if (h.getPos().distance(h.getExtent())<10.0)
185                                         {
186                                                 _ui.removeElementUI(_elem);
187                                                 _sp.Unselect();
188                                         }
189                                 }
190                         }
191                         break;
192                         case RP_INNER_MOVE:
193                                 break;
194                         case RP_CONNECT_END3:
195                         case RP_CONNECT_END5:
196                         case RP_CONNECT_START5:
197                         case RP_CONNECT_START3:
198                         {
199                                 GraphicalTemplateElement t = _sp.getElementAt(logicalMousePos.getX(), logicalMousePos.getY(),_elem);
200                                 if (t!=null)
201                                 {
202                                         GraphicalTemplateElement.RelativePosition edge = t.getClosestEdge(logicalMousePos.getX(), logicalMousePos.getY());
203                                         _ui.addConnectionUI(_elem,_currentMode,t,edge);
204                                 }
205                                 _sp.setSelectedEdge(Helix.RelativePosition.RP_OUTER);
206                         }
207                         break;
208                         }
209                         _elem = null;           
210                         _sp.rescale();
211                 }
212                 _sp.setSelectedEdge(Helix.RelativePosition.RP_OUTER);
213                 _currentMode = Helix.RelativePosition.RP_OUTER;
214                 _sp.repaint();
215         }
216
217
218         private Point2D.Double projectPoint(double x, double y, Point2D.Double ref)
219         {
220                 Point2D.Double result = new Point2D.Double();
221                 double nx = x-ref.x;
222                 double ny = y-ref.y;
223                 double tmp = Double.MIN_VALUE;
224                 for (int i=0;i<this._granularity;i++)
225                 {
226                         double angle = 2.0*Math.PI*((double)i/(double)_granularity);
227                         double dx = Math.cos(angle);
228                         double dy = Math.sin(angle);
229                         double norm  = nx*dx+ny*dy;
230                         //System.out.println(""+angle+" "+norm);
231                         if (norm > tmp)
232                         {
233                                 tmp = norm;
234                                 result.x = ref.x+dx*norm;
235                                 result.y = ref.y+dy*norm;
236                         }
237                 }
238                 return result;
239         }
240
241         public void mouseDragged(MouseEvent arg0) 
242         {
243                 if (movingView) {
244                         Point trans = new Point(
245                                         arg0.getXOnScreen() - _clickedPosScreen.x,
246                                         arg0.getYOnScreen() - _clickedPosScreen.y);
247                         _sp.translateView(trans);
248                         _clickedPosScreen.x = arg0.getXOnScreen();
249                         _clickedPosScreen.y = arg0.getYOnScreen();
250                 } else {
251                         Point2D.Double logicalMousePos = getLogicalMouseCoords(arg0);
252                         if (_elem == null)
253                         {
254                                 switch (_currentMode)
255                                 {
256                                 case RP_EDIT_START:
257                                 {
258                                         if (_clickedPos.distance(arg0.getX(),arg0.getY())>HYSTERESIS_DISTANCE)
259                                         {
260                                                 System.out.println("Creating Helix...");
261                                                 Helix h1 = new Helix(logicalMousePos.getX(),logicalMousePos.getY(),_sp.getTemplate(),_sp.getRNAComponents());
262                                                 h1.setDominantColor(_sp.nextBackgroundColor());
263                                                 _ui.addElementUI(h1);
264                                                 _sp.setSelected(h1);
265                                                 _sp.repaint();
266                                                 _elem = h1;
267                                         }
268                                 }
269                                 break;
270         
271                                 }
272                         }
273                         else
274                         {
275                                 if (_elem instanceof Helix)
276                                 {
277                                         Helix h = (Helix) _elem;
278                                         switch (_currentMode)
279                                         {
280                                         case RP_EDIT_START:
281                                         {
282                                                 Point2D.Double d = projectPoint(logicalMousePos.getX(),logicalMousePos.getY(),h.getPos());
283                                                 _ui.setHelixExtentUI(h, d.x,d.y);
284                                         }
285                                         break;
286                                         case RP_EDIT_END:
287                                         {
288                                                 Point2D.Double d = projectPoint( logicalMousePos.getX(),logicalMousePos.getY(),h.getExtent());
289                                                 _ui.setHelixPosUI(h, d.x,d.y);
290                                         }
291                                         break;
292                                         case RP_INNER_MOVE:
293                                                 _ui.moveHelixUI(h, logicalMousePos.getX(),logicalMousePos.getY());
294                                                 break;
295                                         case RP_CONNECT_END3:
296                                         case RP_CONNECT_END5:
297                                         case RP_CONNECT_START5:
298                                         case RP_CONNECT_START3:
299                                                 _sp.setPointerPos(new Point2D.Double(logicalMousePos.getX(),logicalMousePos.getY()));
300                                                 _sp.repaint();                          
301                                                 break;
302                                         }
303                                 }
304                                 else if (_elem instanceof UnpairedRegion)
305                                 {
306                                         UnpairedRegion ur = (UnpairedRegion) _elem;
307                                         Point2D.Double p = new Point2D.Double(logicalMousePos.getX(),logicalMousePos.getY());
308                                         switch (_currentMode)
309                                         {
310                                         case RP_EDIT_TANGENT_5:
311                                         {
312                                                 _ui.setEdge5TangentUI(ur,logicalMousePos.getX(),logicalMousePos.getY());
313                                                 _sp.repaint();
314                                                 break;
315                                         }
316                                         case RP_EDIT_TANGENT_3:
317                                         {
318                                                 _ui.setEdge3TangentUI(ur,logicalMousePos.getX(),logicalMousePos.getY());
319                                                 _sp.repaint();
320                                                 break;
321                                         }
322                                         case RP_INNER_MOVE:
323                                         {
324                                                 _ui.moveUnpairedUI(ur,logicalMousePos.getX(),logicalMousePos.getY());
325                                                 _sp.repaint();
326                                                 break;
327                                         }
328                                         case RP_CONNECT_START5:
329                                                 _ui.setEdge5UI(ur,logicalMousePos.getX(),logicalMousePos.getY());
330                                                 break;
331                                         case RP_CONNECT_END3:
332                                                 _ui.setEdge3UI(ur,logicalMousePos.getX(),logicalMousePos.getY());
333                                                 break;
334                                         }
335                                         _sp.repaint();                          
336                                 }
337                         }
338                 }
339         }
340
341         public void mouseMoved(MouseEvent arg0) {
342                 // TODO Auto-generated method stub
343
344         }
345 }