REpaint after sequence col selected
[jalview.git] / src / MCview / AppletPDBCanvas.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 package MCview;\r
20 \r
21 import jalview.analysis.AlignSeq;\r
22 \r
23 import jalview.datamodel.*;\r
24 \r
25 // JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug\r
26 import java.awt.*;\r
27 import java.awt.event.*;\r
28 \r
29 import java.io.*;\r
30 \r
31 import java.util.*;\r
32 \r
33 \r
34 \r
35 public class AppletPDBCanvas extends Panel implements MouseListener, MouseMotionListener\r
36 {\r
37 \r
38     MCMatrix idmat = new MCMatrix(3, 3);\r
39     MCMatrix objmat = new MCMatrix(3, 3);\r
40     boolean redrawneeded = true;\r
41     int omx = 0;\r
42     int mx = 0;\r
43     int omy = 0;\r
44     int my = 0;\r
45     public PDBfile pdb;\r
46     int bsize;\r
47     Image img;\r
48     Graphics ig;\r
49     Dimension prefsize;\r
50     float[] centre = new float[3];\r
51     float[] width = new float[3];\r
52     float maxwidth;\r
53     float scale;\r
54     String inStr;\r
55     String inType;\r
56     boolean bysequence = true;\r
57     boolean depthcue = true;\r
58     boolean wire = false;\r
59     boolean bymolecule = false;\r
60     boolean zbuffer = true;\r
61     boolean dragging;\r
62     int xstart;\r
63     int xend;\r
64     int ystart;\r
65     int yend;\r
66     int xmid;\r
67     int ymid;\r
68     Font font = new Font("Helvetica", Font.PLAIN, 10);\r
69     jalview.appletgui.SeqCanvas seqcanvas;\r
70     public Sequence sequence;\r
71     final StringBuffer mappingDetails = new StringBuffer();\r
72     String appletToolTip = null;\r
73     int toolx, tooly;\r
74     PDBChain mainchain;\r
75     Vector highlightRes;\r
76     boolean pdbAction = false;\r
77     Bond highlightBond1, highlightBond2;\r
78 \r
79     public AppletPDBCanvas(jalview.appletgui.SeqCanvas seqcanvas, Sequence seq)\r
80     {\r
81       this.seqcanvas = seqcanvas;\r
82       this.sequence = seq;\r
83 \r
84       seqcanvas.setPDBCanvas(this);\r
85       addKeyListener(new KeyAdapter()\r
86       {\r
87 \r
88         public void keyPressed(KeyEvent evt)\r
89         {\r
90           doKeyPressed(evt);\r
91         }\r
92       });\r
93     }\r
94 \r
95 \r
96   public void setPDBFile(PDBfile pdb)\r
97    {\r
98         int max = -10;\r
99         int maxchain = -1;\r
100         int pdbstart = 0;\r
101         int pdbend = 0;\r
102         int seqstart = 0;\r
103         int seqend = 0;\r
104         AlignSeq maxAlignseq = null;;\r
105 \r
106         for (int i = 0; i < pdb.chains.size(); i++)\r
107         {\r
108 \r
109           mappingDetails.append("\n\nPDB Sequence is :\nSequence = " + ((PDBChain) pdb.chains.elementAt(i)).sequence.getSequence());\r
110           mappingDetails.append("\nNo of residues = " + ((PDBChain) pdb.chains.elementAt(i)).residues.size()+"\n\n");\r
111 \r
112             // Now lets compare the sequences to get\r
113             // the start and end points.\r
114             // Align the sequence to the pdb\r
115             AlignSeq as = new AlignSeq(sequence,\r
116                     ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep");\r
117             as.calcScoreMatrix();\r
118             as.traceAlignment();\r
119             PrintStream  ps = new PrintStream(System.out)\r
120            {\r
121               public void print(String x) {\r
122                    mappingDetails.append(x);\r
123                }\r
124                public void println()\r
125                {\r
126                  mappingDetails.append("\n");\r
127                }\r
128             };\r
129 \r
130             as.printAlignment(ps);\r
131 \r
132             if (as.maxscore > max) {\r
133                 max = as.maxscore;\r
134                 maxchain = i;\r
135 \r
136                 pdbstart = as.seq2start;\r
137                 pdbend = as.seq2end;\r
138                 seqstart = as.seq1start + sequence.getStart()-1;\r
139                 seqend = as.seq1end + sequence.getEnd()-1;\r
140                 maxAlignseq = as;\r
141             }\r
142 \r
143             mappingDetails.append("\nPDB start/end "  + pdbstart + " " + pdbend);\r
144             mappingDetails.append("\nSEQ start/end "+ seqstart + " " + seqend);\r
145         }\r
146 \r
147         mainchain = (PDBChain) pdb.chains.elementAt(maxchain);\r
148 \r
149         mainchain.pdbstart = pdbstart;\r
150         mainchain.pdbend = pdbend;\r
151         mainchain.seqstart = seqstart;\r
152         mainchain.seqend = seqend;\r
153         mainchain.isVisible = true;\r
154         mainchain.makeExactMapping(maxAlignseq, sequence);\r
155 \r
156         this.pdb = pdb;\r
157         this.prefsize = new Dimension(getSize().width, getSize().height);\r
158 \r
159         //Initialize the matrices to identity\r
160         for (int i = 0; i < 3; i++) {\r
161             for (int j = 0; j < 3; j++) {\r
162                 if (i != j) {\r
163                     idmat.addElement(i, j, 0);\r
164                     objmat.addElement(i, j, 0);\r
165                 } else {\r
166                     idmat.addElement(i, j, 1);\r
167                     objmat.addElement(i, j, 1);\r
168                 }\r
169             }\r
170         }\r
171 \r
172         addMouseMotionListener(this);\r
173         addMouseListener(this);\r
174 \r
175 \r
176         findCentre();\r
177         findWidth();\r
178 \r
179         setupBonds();\r
180 \r
181         scale = findScale();\r
182 \r
183         updateSeqColours();\r
184     }\r
185 \r
186 \r
187     Vector visiblebonds;\r
188     void setupBonds()\r
189     {\r
190       // Sort the bonds by z coord\r
191       visiblebonds = new Vector();\r
192 \r
193       for (int ii = 0; ii < pdb.chains.size(); ii++)\r
194       {\r
195         if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
196         {\r
197           Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
198 \r
199           for (int i = 0; i < tmp.size(); i++)\r
200           {\r
201             visiblebonds.addElement(tmp.elementAt(i));\r
202           }\r
203         }\r
204       }\r
205       updateSeqColours();\r
206       redrawneeded = true;\r
207       repaint();\r
208     }\r
209 \r
210 \r
211     public void findWidth() {\r
212         float[] max = new float[3];\r
213         float[] min = new float[3];\r
214 \r
215         max[0] = (float) -1e30;\r
216         max[1] = (float) -1e30;\r
217         max[2] = (float) -1e30;\r
218 \r
219         min[0] = (float) 1e30;\r
220         min[1] = (float) 1e30;\r
221         min[2] = (float) 1e30;\r
222 \r
223         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
224             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
225                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
226 \r
227                 for (int i = 0; i < bonds.size(); i++) {\r
228                     Bond tmp = (Bond) bonds.elementAt(i);\r
229 \r
230                     if (tmp.start[0] >= max[0]) {\r
231                         max[0] = tmp.start[0];\r
232                     }\r
233 \r
234                     if (tmp.start[1] >= max[1]) {\r
235                         max[1] = tmp.start[1];\r
236                     }\r
237 \r
238                     if (tmp.start[2] >= max[2]) {\r
239                         max[2] = tmp.start[2];\r
240                     }\r
241 \r
242                     if (tmp.start[0] <= min[0]) {\r
243                         min[0] = tmp.start[0];\r
244                     }\r
245 \r
246                     if (tmp.start[1] <= min[1]) {\r
247                         min[1] = tmp.start[1];\r
248                     }\r
249 \r
250                     if (tmp.start[2] <= min[2]) {\r
251                         min[2] = tmp.start[2];\r
252                     }\r
253 \r
254                     if (tmp.end[0] >= max[0]) {\r
255                         max[0] = tmp.end[0];\r
256                     }\r
257 \r
258                     if (tmp.end[1] >= max[1]) {\r
259                         max[1] = tmp.end[1];\r
260                     }\r
261 \r
262                     if (tmp.end[2] >= max[2]) {\r
263                         max[2] = tmp.end[2];\r
264                     }\r
265 \r
266                     if (tmp.end[0] <= min[0]) {\r
267                         min[0] = tmp.end[0];\r
268                     }\r
269 \r
270                     if (tmp.end[1] <= min[1]) {\r
271                         min[1] = tmp.end[1];\r
272                     }\r
273 \r
274                     if (tmp.end[2] <= min[2]) {\r
275                         min[2] = tmp.end[2];\r
276                     }\r
277                 }\r
278             }\r
279         }\r
280 \r
281         width[0] = (float) Math.abs(max[0] - min[0]);\r
282         width[1] = (float) Math.abs(max[1] - min[1]);\r
283         width[2] = (float) Math.abs(max[2] - min[2]);\r
284 \r
285         maxwidth = width[0];\r
286 \r
287         if (width[1] > width[0]) {\r
288             maxwidth = width[1];\r
289         }\r
290 \r
291         if (width[2] > width[1]) {\r
292             maxwidth = width[2];\r
293         }\r
294 \r
295        // System.out.println("Maxwidth = " + maxwidth);\r
296     }\r
297 \r
298     public float findScale() {\r
299         int dim;\r
300         int width;\r
301         int height;\r
302 \r
303         if (getSize().width != 0) {\r
304             width = getSize().width;\r
305             height = getSize().height;\r
306         } else {\r
307             width = prefsize.width;\r
308             height = prefsize.height;\r
309         }\r
310 \r
311         if (width < height) {\r
312             dim = width;\r
313         } else {\r
314             dim = height;\r
315         }\r
316 \r
317         return (float) (dim / (1.5d * maxwidth));\r
318     }\r
319 \r
320     public void findCentre() {\r
321         float xtot = 0;\r
322         float ytot = 0;\r
323         float ztot = 0;\r
324 \r
325         int bsize = 0;\r
326 \r
327         //Find centre coordinate\r
328         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
329             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
330                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
331 \r
332                 bsize += bonds.size();\r
333 \r
334                 for (int i = 0; i < bonds.size(); i++) {\r
335                     xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +\r
336                         ((Bond) bonds.elementAt(i)).end[0];\r
337 \r
338                     ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +\r
339                         ((Bond) bonds.elementAt(i)).end[1];\r
340 \r
341                     ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +\r
342                         ((Bond) bonds.elementAt(i)).end[2];\r
343                 }\r
344             }\r
345         }\r
346 \r
347         centre[0] = xtot / (2 * (float) bsize);\r
348         centre[1] = ytot / (2 * (float) bsize);\r
349         centre[2] = ztot / (2 * (float) bsize);\r
350     }\r
351 \r
352     public void paint(Graphics g)\r
353     {\r
354 \r
355       if(visiblebonds==null)\r
356       {\r
357         g.setColor(Color.black);\r
358         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
359         g.drawString("Error Parsing Pasted PDB data!!", 50, getSize().height/2);\r
360         return;\r
361       }\r
362 \r
363 \r
364         //Only create the image at the beginning -\r
365         //this saves much memory usage\r
366         if ((img == null) || (prefsize.width != getSize().width) ||\r
367                 (prefsize.height != getSize().height)) {\r
368 \r
369          try{     prefsize.width = getSize().width;\r
370            prefsize.height = getSize().height;\r
371 \r
372            scale = findScale();\r
373            img = createImage(prefsize.width, prefsize.height);\r
374            ig = img.getGraphics();\r
375 \r
376            redrawneeded = true;\r
377          }catch(Exception ex)\r
378          {\r
379            ex.printStackTrace();\r
380            System.out.println(getSize());\r
381          }\r
382         }\r
383 \r
384 \r
385         if (redrawneeded)\r
386         {\r
387           drawAll(ig, prefsize.width, prefsize.height);\r
388           redrawneeded = false;\r
389         }\r
390         if(appletToolTip!=null)\r
391         {\r
392           ig.setColor(Color.red);\r
393           ig.drawString(appletToolTip, toolx, tooly);\r
394         }\r
395 \r
396         g.drawImage(img, 0, 0, this);\r
397 \r
398         pdbAction = false;\r
399     }\r
400 \r
401     public void drawAll(Graphics g, int width, int height)\r
402     {\r
403       g.setColor(Color.black);\r
404       g.fillRect(0, 0, width, height);\r
405       drawScene(g);\r
406       drawLabels(g);\r
407     }\r
408 \r
409 \r
410     public void updateSeqColours()\r
411     {\r
412       if (pdbAction)\r
413       {\r
414         return;\r
415       }\r
416 \r
417       if(bysequence && pdb!=null)\r
418       {\r
419         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
420         {\r
421           colourBySequence((PDBChain) pdb.chains.elementAt(ii));\r
422         }\r
423       }\r
424 \r
425       redrawneeded=true;\r
426       repaint();\r
427     }\r
428 \r
429 \r
430     int findTrueIndex(int pos)\r
431     {\r
432       // returns the alignment position for a residue\r
433       int j = sequence.getStart();\r
434       int i = 0;\r
435 \r
436       while ( (i < sequence.getLength()) && (j <= sequence.getEnd()) && (j <= pos+1))\r
437       {\r
438         if (!jalview.util.Comparison.isGap(sequence.getCharAt(i)))\r
439         {\r
440           j++;\r
441         }\r
442 \r
443         i++;\r
444       }\r
445 \r
446       if(i>1)\r
447          i--;\r
448 \r
449       if ( (j == sequence.getEnd()) && (j < pos))\r
450       {\r
451         return sequence.getEnd() + 1;\r
452       }\r
453       else\r
454       {\r
455         return i;\r
456       }\r
457     }\r
458 \r
459 \r
460     // This method has been taken out of PDBChain to allow\r
461     // Applet and Application specific sequence renderers to be used\r
462     void colourBySequence(PDBChain chain)\r
463     {\r
464       for (int i = 0; i < chain.bonds.size(); i++)\r
465       {\r
466         Bond tmp = (Bond) chain.bonds.elementAt(i);\r
467         tmp.startCol = Color.lightGray;\r
468         tmp.endCol = Color.lightGray;\r
469         if(chain!=mainchain)\r
470           continue;\r
471 \r
472         if ( (tmp.at1.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&\r
473             (tmp.at1.resNumber <= ( (chain.offset + chain.pdbend) - 1)))\r
474         {\r
475 \r
476           int index = findTrueIndex(tmp.at1.alignmentMapping);\r
477                 //sequence.findIndex(tmp.at1.alignmentMapping);\r
478             if (index != -1)\r
479             {\r
480               tmp.startCol = seqcanvas.getSequenceRenderer().\r
481                   getResidueBoxColour( sequence, index);\r
482 \r
483           //    tmp.startCol = seqcanvas.getFeatureRenderer().\r
484          //         findFeatureColour(tmp.startCol, sequence, index);\r
485             }\r
486         }\r
487 \r
488         int index =  findTrueIndex(tmp.at2.alignmentMapping);\r
489             //sequence.findIndex( tmp.at2.alignmentMapping );\r
490         if (index != -1)\r
491         {\r
492           tmp.endCol = seqcanvas.getSequenceRenderer().\r
493               getResidueBoxColour( sequence, index);\r
494         //  tmp.endCol = seqcanvas.getFeatureRenderer().\r
495         //      findFeatureColour(tmp.endCol, sequence, index);\r
496         }\r
497       }\r
498     }\r
499 \r
500 \r
501     public void drawScene(Graphics g)\r
502     {\r
503 \r
504         if (zbuffer) {\r
505             Zsort.Zsort(visiblebonds);\r
506         }\r
507 \r
508 \r
509         Bond tmpBond=null;\r
510         for (int i = 0; i < visiblebonds.size(); i++)\r
511         {\r
512             tmpBond = (Bond) visiblebonds.elementAt(i);\r
513 \r
514 \r
515             xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
516                 (getSize().width / 2));\r
517             ystart = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
518                 (getSize().height / 2));\r
519 \r
520             xend = (int) (((tmpBond.end[0] - centre[0]) * scale) +\r
521                 (getSize().width / 2));\r
522             yend = (int) (((tmpBond.end[1] - centre[1]) * scale) +\r
523                 (getSize().height / 2));\r
524 \r
525             xmid = (xend + xstart) / 2;\r
526             ymid = (yend + ystart) / 2;\r
527 \r
528             if (depthcue && !bymolecule)\r
529             {\r
530                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
531                     g.setColor(tmpBond.startCol.darker().darker());\r
532                     drawLine(g, xstart, ystart, xmid, ymid);\r
533 \r
534                     g.setColor(tmpBond.endCol.darker().darker());\r
535                     drawLine(g, xmid, ymid, xend, yend);\r
536                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
537                     g.setColor(tmpBond.startCol.darker());\r
538                     drawLine(g, xstart, ystart, xmid, ymid);\r
539 \r
540                     g.setColor(tmpBond.endCol.darker());\r
541                     drawLine(g, xmid, ymid, xend, yend);\r
542                 } else {\r
543                     g.setColor(tmpBond.startCol);\r
544                     drawLine(g, xstart, ystart, xmid, ymid);\r
545 \r
546                     g.setColor(tmpBond.endCol);\r
547                     drawLine(g, xmid, ymid, xend, yend);\r
548                 }\r
549             } else if (depthcue && bymolecule) {\r
550                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
551                     g.setColor(Color.green.darker().darker());\r
552                     drawLine(g, xstart, ystart, xend, yend);\r
553                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
554                     g.setColor(Color.green.darker());\r
555                     drawLine(g, xstart, ystart, xend, yend);\r
556                 } else {\r
557                     g.setColor(Color.green);\r
558                     drawLine(g, xstart, ystart, xend, yend);\r
559                 }\r
560             } else if (!depthcue && !bymolecule) {\r
561                 g.setColor(tmpBond.startCol);\r
562                 drawLine(g, xstart, ystart, xmid, ymid);\r
563                 g.setColor(tmpBond.endCol);\r
564                 drawLine(g, xmid, ymid, xend, yend);\r
565             } else {\r
566                 drawLine(g, xstart, ystart, xend, yend);\r
567             }\r
568 \r
569             if(highlightBond1!=null && highlightBond1==tmpBond)\r
570             {\r
571               g.setColor(Color.white);\r
572               drawLine(g, xmid, ymid, xend, yend);\r
573             }\r
574 \r
575             if(highlightBond2!=null && highlightBond2==tmpBond)\r
576             {\r
577               g.setColor(Color.white);\r
578               drawLine(g, xstart, ystart, xmid, ymid);\r
579             }\r
580 \r
581         }\r
582     }\r
583 \r
584     public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {\r
585         if (!wire) {\r
586             if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {\r
587                 g.drawLine(x1, y1, x2, y2);\r
588                 g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);\r
589                 g.drawLine(x1, y1 - 1, x2, y2 - 1);\r
590             } else {\r
591                 g.setColor(g.getColor().brighter());\r
592                 g.drawLine(x1, y1, x2, y2);\r
593                 g.drawLine(x1 + 1, y1, x2 + 1, y2);\r
594                 g.drawLine(x1 - 1, y1, x2 - 1, y2);\r
595             }\r
596         } else {\r
597             g.drawLine(x1, y1, x2, y2);\r
598         }\r
599     }\r
600 \r
601     public Dimension minimumsize() {\r
602         return prefsize;\r
603     }\r
604 \r
605     public Dimension preferredsize() {\r
606         return prefsize;\r
607     }\r
608 \r
609     public void doKeyPressed(KeyEvent evt)\r
610     {\r
611       if (evt.getKeyCode() == KeyEvent.VK_UP)\r
612       {\r
613         scale = (float) (scale * 1.1);\r
614         redrawneeded = true;\r
615         repaint();\r
616       }\r
617       else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
618       {\r
619         scale = (float) (scale * 0.9);\r
620         redrawneeded = true;\r
621         repaint();\r
622       }\r
623     }\r
624 \r
625     public void mousePressed(MouseEvent e) {\r
626       pdbAction = true;\r
627       Atom fatom = findAtom(e.getX(), e.getY());\r
628       if(fatom!=null)\r
629       {\r
630         fatom.isSelected = !fatom.isSelected;\r
631 \r
632         redrawneeded = true;\r
633         repaint();\r
634         if (foundchain != -1)\r
635         {\r
636           PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
637           if (chain == mainchain)\r
638           {\r
639             if (fatom.alignmentMapping != -1)\r
640             {\r
641               if (highlightRes == null)\r
642                 highlightRes = new Vector();\r
643 \r
644               if (highlightRes.contains(fatom.alignmentMapping+"" + ""))\r
645                 highlightRes.removeElement(fatom.alignmentMapping + "");\r
646               else\r
647                 highlightRes.addElement(fatom.alignmentMapping + "");\r
648             }\r
649           }\r
650         }\r
651 \r
652         }\r
653         mx = e.getX();\r
654         my = e.getY();\r
655         omx = mx;\r
656         omy = my;\r
657         dragging = false;\r
658     }\r
659 \r
660     public void mouseMoved(MouseEvent e) {\r
661       pdbAction = true;\r
662       if(highlightBond1!=null)\r
663       {\r
664         highlightBond1.at2.isSelected = false;\r
665         highlightBond2.at1.isSelected = false;\r
666         highlightBond1 = null;\r
667         highlightBond2 = null;\r
668       }\r
669 \r
670         Atom fatom = findAtom(e.getX(), e.getY());\r
671 \r
672         PDBChain chain = null;\r
673         if(foundchain!=-1)\r
674         {\r
675           chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
676           if(chain == mainchain)\r
677           {\r
678             highlightSeqcanvas( fatom.alignmentMapping );\r
679           }\r
680         }\r
681 \r
682         if (fatom != null) {\r
683             toolx = e.getX();\r
684             tooly = e.getY();\r
685 \r
686             appletToolTip = chain.id+":"+ fatom.resNumber+" "+ fatom.resName;\r
687             redrawneeded = true;\r
688             repaint();\r
689         } else {\r
690             highlightSeqcanvas( -1);\r
691             appletToolTip = null;\r
692             redrawneeded = true;\r
693             repaint();\r
694         }\r
695     }\r
696 \r
697 \r
698     void highlightSeqcanvas(int pos)\r
699     {\r
700       int index = seqcanvas.getViewport().getAlignment().findIndex(sequence);\r
701 \r
702       int size = pos==-1?0:3;\r
703 \r
704       if(highlightRes!=null)\r
705         size += highlightRes.size()*3;\r
706 \r
707       int [] array = new int[size];\r
708       int i=0;\r
709       if(highlightRes!=null)\r
710       {\r
711         for (i = 0; i < highlightRes.size(); i++)\r
712         {\r
713           int a = Integer.parseInt(highlightRes.elementAt(\r
714               i).toString())+1;\r
715           array[i * 3] = index;\r
716           array[ (i * 3) + 1] = a;\r
717           array[ (i * 3) + 2] = a;\r
718         }\r
719       }\r
720 \r
721       if(pos!=-1)\r
722       {\r
723         array[i * 3] = index;\r
724         array[i * 3 + 1] = pos+1;\r
725         array[i * 3 + 2] = pos+1;\r
726       }\r
727 \r
728       seqcanvas.highlightSearchResults(array);\r
729     }\r
730 \r
731 \r
732     public void mouseClicked(MouseEvent e) {\r
733     }\r
734 \r
735     public void mouseEntered(MouseEvent e) {\r
736     }\r
737 \r
738     public void mouseExited(MouseEvent e) {\r
739     }\r
740 \r
741     public void mouseDragged(MouseEvent evt) {\r
742         int x = evt.getX();\r
743         int y = evt.getY();\r
744         mx = x;\r
745         my = y;\r
746 \r
747         MCMatrix objmat = new MCMatrix(3, 3);\r
748         objmat.setIdentity();\r
749 \r
750         if ((evt.getModifiers() & Event.META_MASK) != 0) {\r
751             objmat.rotatez((float) ((mx - omx)));\r
752         } else {\r
753             objmat.rotatex((float) ((my - omy)));\r
754             objmat.rotatey((float) ((omx - mx)));\r
755         }\r
756 \r
757         //Alter the bonds\r
758         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
759             Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
760 \r
761             for (int i = 0; i < bonds.size(); i++) {\r
762                 Bond tmpBond = (Bond) bonds.elementAt(i);\r
763 \r
764                 //Translate the bond so the centre is 0,0,0\r
765                 tmpBond.translate(-centre[0], -centre[1], -centre[2]);\r
766 \r
767                 //Now apply the rotation matrix\r
768                 tmpBond.start = objmat.vectorMultiply(tmpBond.start);\r
769                 tmpBond.end = objmat.vectorMultiply(tmpBond.end);\r
770 \r
771                 //Now translate back again\r
772                 tmpBond.translate(centre[0], centre[1], centre[2]);\r
773             }\r
774         }\r
775 \r
776         objmat = null;\r
777 \r
778         omx = mx;\r
779         omy = my;\r
780 \r
781         dragging = true;\r
782 \r
783         redrawneeded = true;\r
784 \r
785         repaint();\r
786     }\r
787 \r
788     public void mouseReleased(MouseEvent evt) {\r
789         dragging = false;\r
790         return;\r
791     }\r
792 \r
793     void drawLabels(Graphics g) {\r
794 \r
795         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
796         {\r
797             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
798 \r
799             if (chain.isVisible)\r
800             {\r
801                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
802 \r
803                 for (int i = 0; i < bonds.size(); i++)\r
804                 {\r
805                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
806 \r
807                     if (tmpBond.at1.isSelected)\r
808                     {\r
809                         labelAtom(g, tmpBond, 1);\r
810                     }\r
811 \r
812                     if (tmpBond.at2.isSelected)\r
813                     {\r
814 \r
815                         labelAtom(g, tmpBond, 2);\r
816                     }\r
817                 }\r
818             }\r
819         }\r
820     }\r
821 \r
822     public void labelAtom(Graphics g, Bond b, int n) {\r
823         g.setFont(font);\r
824 \r
825         if (n == 1) {\r
826             int xstart = (int) (((b.start[0] - centre[0]) * scale) +\r
827                 (getSize().width / 2));\r
828             int ystart = (int) (((b.start[1] - centre[1]) * scale) +\r
829                 (getSize().height / 2));\r
830 \r
831             g.setColor(Color.red);\r
832             g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
833         }\r
834 \r
835         if (n == 2) {\r
836             int xstart = (int) (((b.end[0] - centre[0]) * scale) +\r
837                 (getSize().width / 2));\r
838             int ystart = (int) (((b.end[1] - centre[1]) * scale) +\r
839                 (getSize().height / 2));\r
840 \r
841             g.setColor(Color.red);\r
842             g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
843         }\r
844     }\r
845 \r
846     int foundchain = -1;\r
847     public Atom findAtom(int x, int y) {\r
848         Atom fatom = null;\r
849 \r
850         foundchain = -1;\r
851 \r
852         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
853         {\r
854             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
855             int truex;\r
856             Bond tmpBond=null;\r
857 \r
858             if (chain.isVisible)\r
859             {\r
860                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
861 \r
862                 for (int i = 0; i < bonds.size(); i++)\r
863                 {\r
864                     tmpBond = (Bond) bonds.elementAt(i);\r
865 \r
866                     truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
867                         (getSize().width / 2));\r
868 \r
869                     if (Math.abs(truex - x) <= 2)\r
870                     {\r
871                         int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
872                             (getSize().height / 2));\r
873 \r
874                         if (Math.abs(truey - y) <= 2)\r
875                         {\r
876                             fatom = tmpBond.at1;\r
877                             foundchain = ii;\r
878                             break;\r
879                         }\r
880                     }\r
881                 }\r
882 \r
883                 // Still here? Maybe its the last bond\r
884 \r
885                 truex = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +\r
886                                (getSize().width / 2));\r
887 \r
888                 if (Math.abs(truex - x) <= 2)\r
889                 {\r
890                   int truey = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +\r
891                                      (getSize().height / 2));\r
892 \r
893                   if (Math.abs(truey - y) <= 2)\r
894                   {\r
895                     fatom = tmpBond.at2;\r
896                     foundchain = ii;\r
897                     break;\r
898                   }\r
899                 }\r
900 \r
901             }\r
902 \r
903             if (fatom != null) //)&& chain.ds != null)\r
904              {\r
905                 chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
906             }\r
907         }\r
908 \r
909         return fatom;\r
910     }\r
911 \r
912     public void update(Graphics g)\r
913     {\r
914       paint(g);\r
915     }\r
916 \r
917     public void highlightRes(int ii)\r
918    {\r
919 \r
920      if (highlightRes != null\r
921          && highlightRes.contains((ii-1) + ""))\r
922      {\r
923        return;\r
924      }\r
925 \r
926      int index = -1;\r
927      Bond tmpBond;\r
928      for(index=0; index<mainchain.bonds.size(); index++)\r
929      {\r
930        tmpBond = (Bond) mainchain.bonds.elementAt(index);\r
931        if (tmpBond.at1.alignmentMapping == ii - 1)\r
932        {\r
933          if (highlightBond1 != null)\r
934            highlightBond1.at2.isSelected = false;\r
935 \r
936          if (highlightBond2 != null)\r
937            highlightBond2.at1.isSelected = false;\r
938 \r
939          highlightBond1 = null;\r
940          highlightBond2 = null;\r
941 \r
942          if (index > 0)\r
943          {\r
944            highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);\r
945            highlightBond1.at2.isSelected = true;\r
946          }\r
947 \r
948          if (index != mainchain.bonds.size())\r
949          {\r
950            highlightBond2 = (Bond) mainchain.bonds.elementAt(index);\r
951            highlightBond2.at1.isSelected = true;\r
952          }\r
953 \r
954          break;\r
955        }\r
956      }\r
957 \r
958      redrawneeded = true;\r
959      repaint();\r
960    }\r
961 \r
962 \r
963     public void setAllchainsVisible(boolean b)\r
964     {\r
965       for (int ii = 0; ii < pdb.chains.size(); ii++)\r
966       {\r
967         PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
968         chain.isVisible = b;\r
969       }\r
970       mainchain.isVisible = true;\r
971       findCentre();\r
972       setupBonds();\r
973     }\r
974 \r
975 }\r