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