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