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