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