JAL-3032 adds Java 8 functionality (2/2)
[jalview.git] / src2 / fr / orsay / lri / varna / models / VARNAEdits.java
1 package fr.orsay.lri.varna.models;
2
3 import java.awt.Point;
4 import java.awt.geom.Point2D;
5 import java.util.ArrayList;
6
7 import javax.swing.undo.AbstractUndoableEdit;
8 import javax.swing.undo.CannotRedoException;
9 import javax.swing.undo.CannotUndoException;
10 import javax.swing.undo.UndoableEdit;
11
12 import fr.orsay.lri.varna.VARNAPanel;
13 import fr.orsay.lri.varna.applications.templateEditor.GraphicalTemplateElement;
14 import fr.orsay.lri.varna.applications.templateEditor.TemplatePanel;
15 import fr.orsay.lri.varna.applications.templateEditor.TemplateEdits.ElementEdgeMoveTemplateEdit;
16 import fr.orsay.lri.varna.exceptions.ExceptionNAViewAlgorithm;
17 import fr.orsay.lri.varna.models.rna.ModeleBase;
18 import fr.orsay.lri.varna.models.rna.ModeleBP;
19 import fr.orsay.lri.varna.models.rna.RNA;
20
21 public class VARNAEdits {
22         public static final double MAX_DISTANCE= 55.0;
23         public static  class BasesShiftEdit extends AbstractUndoableEdit
24         {
25                 private ArrayList<Integer> _indices; 
26                 private double _dx; 
27                 private double _dy;
28                 private VARNAPanel _vp;
29                 public BasesShiftEdit(ArrayList<Integer> indices, double dx, double dy, VARNAPanel p)
30                 {
31                         _indices = indices;
32                         _dx = dx;
33                         _dy = dy;
34                         _vp = p;
35                 }
36                 public void undo() throws CannotUndoException {
37                         for (int index: _indices)
38                         {
39                                 ModeleBase mb = _vp.getRNA().getBaseAt(index);
40                             _vp.getRNA().setCoord(index,new Point2D.Double(mb.getCoords().x-_dx,mb.getCoords().y-_dy));
41                             _vp.getRNA().setCenter(index,new Point2D.Double(mb.getCenter().x-_dx,mb.getCenter().y-_dy));
42                         }
43                         _vp.repaint();                  
44                 }
45                 public void redo() throws CannotRedoException {
46                         for (int index: _indices)
47                         {
48                                 ModeleBase mb = _vp.getRNA().getBaseAt(index);
49                             _vp.getRNA().setCoord(index,new Point2D.Double(mb.getCoords().x+_dx,mb.getCoords().y+_dy));
50                             _vp.getRNA().setCenter(index,new Point2D.Double(mb.getCenter().x-_dx,mb.getCenter().y-_dy));
51                         }
52                         _vp.repaint();
53                 }
54                 public boolean canUndo() { return true; }
55                 public boolean canRedo() { return true; }
56                 public String getPresentationName() { return "Base #"+_indices+" shifted"; }
57                 public boolean addEdit(UndoableEdit anEdit)
58                 {
59                         if (anEdit instanceof BasesShiftEdit)
60                         {
61                                 BasesShiftEdit e = (BasesShiftEdit) anEdit;
62                                 if (e._indices.equals(_indices))
63                                 {
64                                         Point2D.Double tot = new Point2D.Double(_dx+e._dx,_dy+e._dy);
65                                         if (tot.distance(0.0, 0.0)<MAX_DISTANCE)
66                                         {
67                                                 _dx = _dx+e._dx;
68                                                 _dy = _dy+e._dy;
69                                                 return true;
70                                         }
71                                 }
72                         }
73                         return false;
74                 }
75         };
76
77         public static  class HelixRotateEdit extends AbstractUndoableEdit
78         {
79                 private double _delta; 
80                 private double _base; 
81                 private double _pLimL; 
82                 private double _pLimR; 
83                 private Point _h; 
84                 private Point _ml; 
85                 private VARNAPanel _vp;
86                 public HelixRotateEdit(double delta, double base, double pLimL, double pLimR, Point h, Point ml, VARNAPanel vp)
87                 {
88                         _delta = delta;
89                         _base = base;
90                         _pLimL = pLimL;
91                         _pLimR = pLimR;
92                         _h = h;
93                         _ml = ml;
94                         _vp = vp;
95                 }
96                 public void undo() throws CannotUndoException {
97                         _vp.getVARNAUI().UIRotateEverything(-_delta, _base, _pLimL, _pLimR, _h, _ml);
98                         _vp.repaint();                  
99                 }
100                 public void redo() throws CannotRedoException {
101                         _vp.getVARNAUI().UIRotateEverything(_delta, _base, _pLimL, _pLimR, _h, _ml);
102                         _vp.repaint();
103                 }
104                 public boolean canUndo() { return true; }
105                 public boolean canRedo() { return true; }
106                 public String getPresentationName() { return "Helix #"+_h+" rotated angle:"+_delta; }
107                 public boolean addEdit(UndoableEdit anEdit)
108                 {
109                         if (anEdit instanceof HelixRotateEdit)
110                         {
111                                 HelixRotateEdit e = (HelixRotateEdit) anEdit;
112                                 if (e._h.equals(_h))
113                                 {
114                                         double totAngle = e._delta+_delta;
115                                         while (totAngle>Math.PI)
116                                         { totAngle -= 2.0*Math.PI; }
117                                         if (Math.abs(totAngle)<Math.PI/8.0)
118                                         {
119                                                 _delta=totAngle;
120                                                 return true;
121                                         }
122                                 }
123                         }
124                         return false;
125                 }
126         };
127         
128         
129         public static  class SingleBaseMoveEdit extends AbstractUndoableEdit
130         {
131                 private int _index; 
132                 private double _ox; 
133                 private double _oy;
134                 private double _nx; 
135                 private double _ny;
136                 private VARNAPanel _vp;
137                 public SingleBaseMoveEdit(int index, double nx, double ny, VARNAPanel p)
138                 {
139                         _index = index;
140                         ModeleBase mb = p.getRNA().getBaseAt(index);
141                         _ox = mb.getCoords().x;
142                         _oy = mb.getCoords().y;
143                         _nx = nx;
144                         _ny = ny;
145                         _vp = p;
146                 }
147                 public void undo() throws CannotUndoException {
148                         _vp.getRNA().setCoord(_index,new Point2D.Double(_ox,_oy));
149                         _vp.repaint();                  
150                 }
151                 public void redo() throws CannotRedoException {
152                         _vp.getRNA().setCoord(_index,new Point2D.Double(_nx,_ny));
153                         _vp.repaint();
154                 }
155                 public boolean canUndo() { return true; }
156                 public boolean canRedo() { return true; }
157                 public String getPresentationName() { return "Base #"+_index+" moved"; }
158                 public boolean addEdit(UndoableEdit anEdit)
159                 {
160                         if (anEdit instanceof SingleBaseMoveEdit)
161                         {
162                                 SingleBaseMoveEdit e = (SingleBaseMoveEdit) anEdit;
163                                 if (e._index==_index)
164                                 {
165                                         Point2D.Double po1 = new Point2D.Double(_ox,_oy);
166                                         Point2D.Double pn1 = new Point2D.Double(_nx,_ny);
167                                         Point2D.Double po2 = new Point2D.Double(e._ox,e._oy);
168                                         Point2D.Double pn2 = new Point2D.Double(e._nx,e._ny);
169                                         if ((pn1.equals(po2))&&(po1.distance(pn2)<MAX_DISTANCE))
170                                         {
171                                                 _nx = e._nx;
172                                                 _ny = e._ny;
173                                                 return true;
174                                         }
175                                 }
176                         }
177                         return false;
178                 }
179         };
180
181         public static  class HelixFlipEdit extends AbstractUndoableEdit
182         {
183                 private Point _h; 
184                 private VARNAPanel _vp;
185                 public HelixFlipEdit(Point h, VARNAPanel vp)
186                 {
187                         _h = h;
188                         _vp = vp;
189                 }
190                 public void undo() throws CannotUndoException {
191                         _vp.getVARNAUI().UIFlipHelix(_h);
192                         _vp.repaint();                  
193                 }
194                 public void redo() throws CannotRedoException {
195                         _vp.getVARNAUI().UIFlipHelix(_h);
196                         _vp.repaint();
197                 }
198                 public boolean canUndo() { return true; }
199                 public boolean canRedo() { return true; }
200                 public String getPresentationName() { return "Helix #"+_h+" flipped";}
201                 public boolean addEdit(UndoableEdit anEdit)
202                 {
203                         return false;
204                 }
205         };
206
207         public static  class AddBPEdit extends AbstractUndoableEdit
208         {
209                 private ModeleBP _msbp; 
210                 private int _i;
211                 private int _j;
212                 private VARNAPanel _vp;
213                 public AddBPEdit(int i, int j, ModeleBP msbp, VARNAPanel vp)
214                 {
215                         _msbp = msbp;
216                         _i = i;
217                         _j = j;
218                         _vp = vp;
219                 }
220                 public void undo() throws CannotUndoException {
221                         _vp.getRNA().removeBP(_msbp);
222                         _vp.repaint();                  
223                 }
224                 public void redo() throws CannotRedoException {
225                         _vp.getRNA().addBP(_i,_j,_msbp);
226                         _vp.repaint();
227                 }
228                 public boolean canUndo() { return true; }
229                 public boolean canRedo() { return true; }
230                 public String getPresentationName() { return "Add BP ("+_i+","+_j+")";}
231                 public boolean addEdit(UndoableEdit anEdit)
232                 {
233                         return false;
234                 }
235         };
236
237         public static  class RemoveBPEdit extends AbstractUndoableEdit
238         {
239                 private ModeleBP _msbp; 
240                 private int _i;
241                 private int _j;
242                 private VARNAPanel _vp;
243                 public RemoveBPEdit( int i, int j,ModeleBP msbp, VARNAPanel vp)
244                 {
245                         _msbp = msbp;
246                         _i = i;
247                         _j = j;
248                         _vp = vp;
249                 }
250                 public void undo() throws CannotUndoException {
251                         _vp.getRNA().addBP(_i,_j,_msbp);
252                         _vp.repaint();                  
253                 }
254                 public void redo() throws CannotRedoException {
255                         _vp.getRNA().removeBP(_msbp);
256                         _vp.repaint();
257                 }
258                 public boolean canUndo() { return true; }
259                 public boolean canRedo() { return true; }
260                 public String getPresentationName() { return "Remove BP ("+_i+","+_j+")";}
261                 public boolean addEdit(UndoableEdit anEdit)
262                 {
263                         return false;
264                 }
265         };
266
267         public static  class RescaleRNAEdit extends AbstractUndoableEdit
268         {
269                 private double _factor;
270                 private VARNAPanel _vp;
271                 public RescaleRNAEdit( double angle, VARNAPanel vp)
272                 {
273                         _factor = angle;
274                         _vp = vp;
275                 }
276                 public void undo() throws CannotUndoException {
277                         _vp.getRNA().rescale(1.0/_factor);
278                         _vp.repaint();                  
279                 }
280                 public void redo() throws CannotRedoException {
281                         _vp.getRNA().rescale(_factor);
282                         _vp.repaint();
283                 }
284                 public boolean canUndo() { return true; }
285                 public boolean canRedo() { return true; }
286                 public String getPresentationName() { return "Rescale RNA factor:"+_factor+"";}
287                 public boolean addEdit(UndoableEdit anEdit)
288                 {
289                         if (anEdit instanceof RescaleRNAEdit)
290                         {
291                                 RescaleRNAEdit e = (RescaleRNAEdit) anEdit;
292                                 double cumFact = _factor*e._factor;
293                                 if (cumFact>.7 || cumFact<1.3)
294                                 {
295                                         _factor *= e._factor;
296                                         return true;
297                                 }
298                         }
299                         return false;
300                 }
301         };
302
303         public static  class RotateRNAEdit extends AbstractUndoableEdit
304         {
305                 private double _angle;
306                 private VARNAPanel _vp;
307                 public RotateRNAEdit( double angle, VARNAPanel vp)
308                 {
309                         _angle = angle;
310                         _vp = vp;
311                 }
312                 public void undo() throws CannotUndoException {
313                         _vp.getRNA().globalRotation(-_angle);
314                         _vp.repaint();                  
315                 }
316                 public void redo() throws CannotRedoException {
317                         _vp.getRNA().globalRotation(_angle);
318                         _vp.repaint();
319                 }
320                 public boolean canUndo() { return true; }
321                 public boolean canRedo() { return true; }
322                 public String getPresentationName() { return "Rotate RNA angle:"+_angle+"";}
323                 public boolean addEdit(UndoableEdit anEdit)
324                 {
325                         if (anEdit instanceof RotateRNAEdit)
326                         {
327                                 RotateRNAEdit e = (RotateRNAEdit) anEdit;
328                                 if (Math.abs(_angle+e._angle)<30)
329                                 {
330                                         _angle += e._angle;
331                                         return true;
332                                 }
333                         }
334                         return false;
335                 }
336         };
337
338         public static  class RedrawEdit extends AbstractUndoableEdit
339         {
340                 private int _prevMode;
341                 private int _newMode;
342                 private boolean _prevFlat;
343                 private boolean _newFlat;
344                 private ArrayList<Point2D.Double> _backupCoords = new ArrayList<Point2D.Double>();
345                 private ArrayList<Point2D.Double> _backupCenters = new ArrayList<Point2D.Double>();
346                 private VARNAPanel _vp;
347                 
348
349                 public RedrawEdit(VARNAPanel vp,boolean newFlat)
350                 {
351                         this(vp.getRNA().getDrawMode(),vp,newFlat);
352                 }
353
354                 public RedrawEdit(int newMode, VARNAPanel vp)
355                 {
356                         this(newMode,vp,vp.getFlatExteriorLoop());
357                 }
358         
359                 public RedrawEdit(int newMode, VARNAPanel vp, boolean newFlat)
360                 {
361                         _vp = vp;
362                         _newMode = newMode;
363                         _newFlat = newFlat;
364                         _prevFlat = _vp.getFlatExteriorLoop();
365                         for (ModeleBase mb: _vp.getRNA().get_listeBases())
366                         {
367                                 _backupCoords.add(new Point2D.Double(mb.getCoords().x,mb.getCoords().y));
368                                 _backupCenters.add(new Point2D.Double(mb.getCenter().x,mb.getCenter().y));
369                         }
370                         _prevMode = _vp.getDrawMode();
371                 }
372                 public void undo() throws CannotUndoException {
373                         RNA r = _vp.getRNA();
374                         _vp.setFlatExteriorLoop(_prevFlat);
375                         r.setDrawMode(_prevMode);
376                         for (int index =0;index<_vp.getRNA().get_listeBases().size();index++)
377                         {
378                             Point2D.Double oldCoord = _backupCoords.get(index);
379                             Point2D.Double oldCenter = _backupCenters.get(index);
380                             r.setCoord(index, oldCoord);
381                             r.setCenter(index, oldCenter);
382                         }
383                         _vp.repaint();                  
384                 }
385                 public void redo() throws CannotRedoException {
386                         try {
387                                 _vp.setFlatExteriorLoop(_newFlat);
388                                 _vp.getRNA().drawRNA(_newMode,_vp.getConfig());
389                         } catch (ExceptionNAViewAlgorithm e) {
390                                 e.printStackTrace();
391                         }
392                         _vp.repaint();
393                 }
394                 public boolean canUndo() { return true; }
395                 public boolean canRedo() { return true; }
396                 public String getPresentationName() { return "Redraw whole RNA";}
397                 public boolean addEdit(UndoableEdit anEdit)
398                 {
399                         return false;
400                 }
401         };
402
403 }