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