Addition of rubberband
[jalview.git] / src / jalview / gui / SeqPanel.java
1 package jalview.gui;\r
2 \r
3 import java.awt.*;\r
4 import java.awt.event.*;\r
5 import jalview.datamodel.*;\r
6 import javax.swing.*;\r
7 import jalview.schemes.*;\r
8 import jalview.analysis.*;\r
9 \r
10 \r
11 public class SeqPanel extends JPanel\r
12 {\r
13 \r
14   public    SeqCanvas         seqCanvas;\r
15   public    AlignmentPanel    parent;\r
16 \r
17   protected int startres;\r
18   protected int lastres;\r
19   protected int endres;\r
20 \r
21   protected int startseq;\r
22   protected int padseq;\r
23 \r
24   public    boolean editFlag;\r
25   protected AlignViewport av;\r
26 \r
27   // if character is inserted or deleted, we will need to recalculate the conservation\r
28   int seqEditOccurred = -1;\r
29 \r
30   public SeqPanel(AlignViewport avp, AlignmentPanel p) {\r
31     this.av         = avp;\r
32 \r
33     seqCanvas  = new SeqCanvas(avp);\r
34     setLayout(new BorderLayout());\r
35     add(seqCanvas, BorderLayout.CENTER);\r
36 \r
37     parent = p;\r
38 \r
39     addMouseMotionListener( new MouseMotionAdapter()\r
40     {\r
41       public void mouseMoved(MouseEvent evt)\r
42       {  doMouseMoved(evt);   }\r
43       public void mouseDragged(MouseEvent evt)\r
44       {\r
45         if(av.groupDefiningMode)\r
46           doMouseDraggedDefineMode(evt);\r
47         else\r
48           doMouseDragged(evt);\r
49       }\r
50     });\r
51 \r
52     addMouseListener( new MouseAdapter()\r
53     {\r
54       public void mouseReleased(MouseEvent evt)\r
55       {\r
56         if(av.groupDefiningMode)\r
57           doMouseReleasedDefineMode(evt);\r
58         else\r
59           doMouseReleased(evt);\r
60       }\r
61       public void mousePressed(MouseEvent evt)\r
62       {\r
63         if(av.groupDefiningMode)\r
64           doMousePressedDefineMode(evt);\r
65         else\r
66           doMousePressed(evt);\r
67       }\r
68 \r
69     });\r
70     repaint();\r
71   }\r
72 \r
73 \r
74   public void doMouseReleased(MouseEvent evt) {\r
75 \r
76     int x = evt.getX();\r
77     int res = x/av.getCharWidth() + av.getStartRes();\r
78 \r
79     endres = res;\r
80 \r
81       // This is to detect edits - we're at the end of an edit if mouse is up\r
82     editFlag = false;\r
83     startseq = -1;\r
84     startres = -1;\r
85     lastres  = -1;\r
86     if(seqEditOccurred>-1)\r
87       updateConservation(seqEditOccurred);\r
88 \r
89     seqEditOccurred = -1;\r
90 \r
91     parent.RefreshPanels();\r
92     repaint();\r
93 \r
94   }\r
95 \r
96   public void doMousePressed(MouseEvent evt) {\r
97     parent.alignFrame.addHistoryItem("sequence edit");\r
98     int seq;\r
99     int res;\r
100 \r
101     int x = evt.getX();\r
102     int y = evt.getY();\r
103 \r
104     res = x/av.getCharWidth() + av.getStartRes();\r
105     seq = y/av.getCharHeight() + av.getStartSeq();\r
106 \r
107     if (seq < av.getAlignment().getHeight() && res < av.getAlignment().getSequenceAt(seq).getLength())\r
108     {\r
109       //char resstr = align.getSequenceAt(seq).getSequence().charAt(res);\r
110       // Find the residue's position in the sequence (res is the position\r
111       // in the alignment\r
112 \r
113       startseq = seq;\r
114 \r
115       if (startseq == (av.getAlignment().getHeight()-1)) {\r
116         padseq = 1;\r
117       } else {\r
118         padseq = 1;\r
119       }\r
120 \r
121       startres = res;\r
122       lastres = res;\r
123 \r
124       } else {\r
125       startseq = -1;\r
126       startres = -1;\r
127       lastres = -1;\r
128     }\r
129 \r
130     return;\r
131   }\r
132 \r
133   public void doMouseMoved(MouseEvent evt)\r
134   {\r
135     int res=0, seq=0;\r
136     int x = evt.getX();\r
137     int y = evt.getY();\r
138     if(av.wrapAlignment)\r
139     {\r
140       y -= 2*av.charHeight;\r
141       int chunkHeight = (av.getAlignment().getHeight()+2)*av.charHeight;\r
142 \r
143 \r
144       res =   (int)((y/chunkHeight)*(getWidth()/av.charWidth)) +  x/av.getCharWidth() + av.getStartRes();\r
145 \r
146       System.out.println( ((y/chunkHeight)*(getWidth()/av.charWidth)) +" "+((x / av.getCharWidth()) + av.getStartRes()) );\r
147       y %= chunkHeight;\r
148       seq =     y / av.getCharHeight() + av.getStartSeq();\r
149 \r
150       //   chunkHeight =  (da.getHeight() + 2)*charHeight;\r
151       //  startx += chunkWidth;\r
152     }\r
153     else\r
154     {\r
155       res = x / av.getCharWidth()  + av.getStartRes();\r
156       seq = y / av.getCharHeight() + av.getStartSeq();\r
157     }\r
158 \r
159 \r
160     if(seq>=av.getAlignment().getHeight())\r
161       return;\r
162 \r
163     Object obj = ResidueProperties.aa2Triplet.get( av.getAlignment().getSequenceAt(seq).getCharAt(res)+"" ) ;\r
164     String aa = "";\r
165     if(obj!=null)\r
166          aa = obj.toString();\r
167 \r
168     StringBuffer text = new StringBuffer("Sequence " +(seq+1)+" ID: "+av.getAlignment().getSequenceAt(seq).getName());\r
169     if(aa!="")\r
170       text.append("  Residue: "+aa+" ("+  av.getAlignment().getSequenceAt(seq).findPosition(res)+")");\r
171 \r
172     parent.alignFrame.statusBar.setText(text.toString());\r
173 \r
174   }\r
175 \r
176   public void doMouseDragged(MouseEvent evt) {\r
177     // If we're dragging we're editing\r
178     editFlag = true;\r
179     int x = evt.getX();\r
180 \r
181     int res = x/av.getCharWidth() + av.getStartRes();\r
182     if (res < 0) {res = 0;}\r
183 \r
184     if (res  != lastres) {\r
185       if (startseq != -1) {\r
186 \r
187         // Group editing\r
188         if (av.getGroupEdit()) {\r
189           SequenceGroup sg = av.getAlignment().findGroup(startseq);\r
190 \r
191           if(sg!=null)\r
192           if (res < av.getAlignment().getWidth() && res < lastres)\r
193           {\r
194             boolean flag = false;\r
195             for (int i= 0 ; i < sg.getSize(); i++)\r
196             {\r
197               SequenceI s = (SequenceI)sg.getSequenceAt(i);\r
198               for (int j=lastres-1; j >= res; j--)\r
199               {\r
200                 if (!flag)\r
201                 {\r
202                   if (s.getSequence().charAt(j)!=av.getAlignment().getGapCharacter() &&\r
203                       s.getSequence().charAt(j)==' ')\r
204                   {\r
205                     res = j+1;\r
206                     flag = true;\r
207                   }\r
208                 }\r
209               }\r
210             }\r
211           }\r
212 \r
213           if(sg!=null)\r
214           for (int i= 0 ; i < sg.getSize(); i++)\r
215           {\r
216             SequenceI s = (SequenceI)sg.getSequenceAt(i);\r
217             boolean found = false;\r
218             int sno = -1;\r
219             for (int k = 0; k < av.getAlignment().getHeight(); k++)\r
220             {\r
221               if (av.getAlignment().getSequenceAt(k) == s)\r
222               {\r
223                 found = true;\r
224                 sno = k;\r
225                 break;\r
226               }\r
227             }\r
228             if (found && sno != -1) {\r
229               if (res < av.getAlignment().getWidth() && res > lastres)\r
230               {\r
231                 for (int j = lastres; j < res; j++)\r
232                   insertChar(j,sno);\r
233 \r
234                 int index = av.getAlignment().findIndex(s);\r
235                 if (index != -1)\r
236                   drawChars(index,index+1,lastres);\r
237 \r
238 \r
239               } else if (res < av.getAlignment().getWidth() && res < lastres)\r
240               {\r
241                 for (int j = res; j < lastres; j++)\r
242                 {\r
243                   deleteChar(j,res,sno);\r
244                   startres = res;\r
245                 }\r
246                 int index = av.getAlignment().findIndex(s);\r
247                 if (index != -1)\r
248                   drawChars(index,index+1,res);\r
249 \r
250               }\r
251             }\r
252 \r
253           }\r
254           lastres = res;\r
255         } else {\r
256 \r
257 \r
258           if (res < av.getAlignment().getWidth() && res > lastres) {\r
259             // dragging to the right\r
260             for (int j = lastres; j < res; j++)\r
261               insertChar(j,startseq);\r
262 \r
263             drawChars(startseq,startseq+1,lastres);\r
264 \r
265           } else if (res < av.getAlignment().getWidth() && res < lastres)\r
266           {\r
267 \r
268             // dragging to the left\r
269             for (int j = res; j < lastres; j++) {\r
270               deleteChar(j,res,startseq);\r
271               startres = res;\r
272             }\r
273             drawChars(startseq,startseq+1,res);\r
274           }\r
275         }\r
276       }\r
277       lastres = res;\r
278     }\r
279 \r
280     repaint();\r
281     return;\r
282   }\r
283 \r
284   public void drawChars(int seqstart, int seqend, int start) {\r
285     seqCanvas.drawPanel(seqCanvas.gg, start,av.getEndRes(),seqstart,seqend,av.getStartRes(),av.getStartSeq(),0);\r
286     repaint();\r
287   }\r
288 \r
289   public void insertChar(int j, int seq)\r
290   {\r
291     av.getAlignment().getSequenceAt(seq).insertCharAt(j, av.getGapCharacter());\r
292     seqEditOccurred=seq;\r
293   }\r
294 \r
295   public void deleteChar(int j, int res, int seq)\r
296   {\r
297 \r
298     if (av.getAlignment().getSequenceAt(seq).getSequence().charAt(j)=='.' ||\r
299         av.getAlignment().getSequenceAt(seq).getSequence().charAt(j)=='-' ||\r
300         av.getAlignment().getSequenceAt(seq).getSequence().charAt(j)==' ' )\r
301     {\r
302         av.getAlignment().getSequenceAt(seq).deleteCharAt(j);\r
303     }\r
304 \r
305     av.getAlignment().getWidth();\r
306     repaint();\r
307     seqEditOccurred=seq;\r
308   }\r
309 \r
310 \r
311   void updateConservation(int i)\r
312   {\r
313     Alignment al = (Alignment) av.getAlignment();\r
314     SequenceGroup sg = av.alignment.findGroup( al.getSequenceAt(i));\r
315     if(sg==null || !(sg.cs instanceof ConservationColourScheme))\r
316       return;\r
317 \r
318     Conservation c = sg.getConservation();\r
319 \r
320     c = new Conservation("All", al.cons,\r
321                          ResidueProperties.propHash, 3, sg.sequences, 0,\r
322                          al.getWidth());\r
323     c.calculate();\r
324     c.verdict(false, 100);\r
325     sg.setConservation(c);\r
326     ConservationColourScheme ccs = (ConservationColourScheme)sg.cs;\r
327     ccs.conserve = c;\r
328   }\r
329 \r
330 \r
331   public void doMousePressedDefineMode(MouseEvent evt)\r
332   {\r
333     int res = evt.getX()/av.getCharWidth() + av.getStartRes();\r
334     int seq = evt.getY()/av.getCharHeight() + av.getStartSeq();\r
335 \r
336     stretchGroup = av.getRubberbandGroup();\r
337     if(stretchGroup == null)\r
338         stretchGroup = av.alignment.findGroup((Sequence)av.getAlignment().getSequenceAt(seq));\r
339       else if(!stretchGroup.sequences.contains((Sequence)av.getAlignment().getSequenceAt(seq))\r
340             || stretchGroup.getStartRes()<res\r
341             || stretchGroup.getEndRes()>res)\r
342      {\r
343        System.out.println(stretchGroup.getStartRes()+" "+stretchGroup.getEndRes()+" "+res);\r
344        stretchGroup = null;\r
345      }\r
346 \r
347 \r
348 \r
349     if(stretchGroup==null)\r
350     {\r
351       // define a new group here\r
352       SequenceGroup sg = new SequenceGroup();\r
353       sg.setStartRes(res);\r
354       sg.setEndRes(res);\r
355       sg.addSequence( (Sequence)av.getAlignment().getSequenceAt(seq) );\r
356       av.setRubberbandGroup( sg );\r
357       stretchGroup = sg;\r
358       System.out.println("new rubberband group");\r
359     }\r
360     else if( javax.swing.SwingUtilities.isRightMouseButton(evt))\r
361     {\r
362         // edit the properties of existing group\r
363     }\r
364 \r
365     if(stretchGroup!=null && stretchGroup.getEndRes()==res)\r
366     {\r
367       // Edit end res position of selected group\r
368       changeEndRes = true;\r
369     }\r
370     if(stretchGroup!=null && stretchGroup.getStartRes()==res)\r
371     {\r
372       // Edit end res position of selected group\r
373       changeStartRes = true;\r
374     }\r
375 \r
376     seqCanvas.paintFlag = true;\r
377     repaint();\r
378 \r
379 \r
380   }\r
381 \r
382   boolean changeEndSeq = false;\r
383   boolean changeStartSeq = false;\r
384   boolean changeEndRes = false;\r
385   boolean changeStartRes = false;\r
386   SequenceGroup stretchGroup = null;\r
387 \r
388 \r
389   public void doMouseReleasedDefineMode(MouseEvent evt)\r
390   {\r
391     changeEndRes = false;\r
392     changeStartRes = false;\r
393     stretchGroup = null;\r
394   }\r
395 \r
396   public void doMouseDraggedDefineMode(MouseEvent evt)\r
397   {\r
398     int res = evt.getX()/av.getCharWidth() + av.getStartRes();\r
399     Sequence seq = (Sequence)av.getAlignment().getSequenceAt(\r
400                     evt.getY()/av.getCharHeight() + av.getStartSeq());\r
401 \r
402    // SequenceGroup newSeqGroup = av.alignment.findGroup(seq);\r
403 \r
404     if(res<av.getStartRes())\r
405       res = av.getStartRes();\r
406     else if(res>av.getEndRes())\r
407       res = av.getEndRes();\r
408 \r
409     if(changeEndRes)\r
410     {\r
411       if(res>stretchGroup.getStartRes()-1)\r
412         stretchGroup.setEndRes( res );\r
413     }\r
414     else if(changeStartRes)\r
415     {\r
416       if(res<stretchGroup.getEndRes()+1)\r
417         stretchGroup.setStartRes( res );\r
418     }\r
419 \r
420    /* if(newSeqGroup != stretchGroup)\r
421     {\r
422       if(newSeqGroup !=null)\r
423         av.getAlignment().removeFromGroup(newSeqGroup, seq );\r
424 \r
425       if(stretchGroup!=null)\r
426         stretchGroup.addSequence( seq );\r
427     }*/\r
428 \r
429     seqCanvas.paintFlag = true;\r
430     repaint();\r
431 \r
432   }\r
433 \r
434 }\r
435 \r
436 \r
437 \r
438 \r