No longer use ref to seqcanvas for painting
[jalview.git] / src / MCview / AppletPDBCanvas.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 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 java.io.*;\r
22 import java.util.*;\r
23 \r
24 // JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug\r
25 import java.awt.*;\r
26 import java.awt.event.*;\r
27 \r
28 import jalview.analysis.*;\r
29 import jalview.datamodel.*;\r
30 \r
31 import jalview.appletgui.*;\r
32 import jalview.structure.*;\r
33 \r
34 public class AppletPDBCanvas\r
35     extends Panel implements MouseListener, MouseMotionListener, StructureListener\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   PDBEntry pdbentry;\r
47   int bsize;\r
48   Image img;\r
49   Graphics ig;\r
50   Dimension prefsize;\r
51   float[] centre = new float[3];\r
52   float[] width = new float[3];\r
53   float maxwidth;\r
54   float scale;\r
55   String inStr;\r
56   String inType;\r
57   boolean bysequence = true;\r
58   boolean depthcue = true;\r
59   boolean wire = false;\r
60   boolean bymolecule = false;\r
61   boolean zbuffer = true;\r
62   boolean dragging;\r
63   int xstart;\r
64   int xend;\r
65   int ystart;\r
66   int yend;\r
67   int xmid;\r
68   int ymid;\r
69   Font font = new Font("Helvetica", Font.PLAIN, 10);\r
70   public SequenceI [] 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   FeatureRenderer fr;\r
81   AlignmentPanel ap;\r
82   StructureSelectionManager ssm;\r
83 \r
84   public AppletPDBCanvas(PDBEntry pdbentry,\r
85                          SequenceI[] seq,\r
86                          AlignmentPanel ap,\r
87                          String protocol)\r
88 \r
89   {\r
90     this.ap = ap;\r
91     this.pdbentry = pdbentry;\r
92     this.sequence = seq;\r
93 \r
94     ssm = StructureSelectionManager.getStructureSelectionManager();\r
95 \r
96     try{\r
97       pdb = ssm.setMapping(seq, pdbentry.getFile(), protocol);\r
98     }catch(Exception ex)\r
99     {\r
100       ex.printStackTrace();\r
101       return;\r
102     }\r
103 \r
104     pdbentry.setId(pdb.id);\r
105 \r
106     ssm.addStructureViewerListener(this);\r
107 \r
108     colourBySequence(ap.getSequenceRenderer(),\r
109                      ap.av.getShowSequenceFeatures() ?\r
110                      ap.getFeatureRenderer() : null);\r
111 \r
112     int max = -10;\r
113     int maxchain = -1;\r
114     int pdbstart = 0;\r
115     int pdbend = 0;\r
116     int seqstart = 0;\r
117     int seqend = 0;\r
118     AlignSeq maxAlignseq = null;\r
119 \r
120     //JUST DEAL WITH ONE SEQUENCE FOR NOW\r
121     SequenceI sequence = seq[0];\r
122 \r
123     for (int i = 0; i < pdb.chains.size(); i++)\r
124     {\r
125 \r
126       mappingDetails.append("\n\nPDB Sequence is :\nSequence = " +\r
127                             ( (PDBChain) pdb.chains.elementAt(i)).sequence.\r
128                             getSequenceAsString());\r
129       mappingDetails.append("\nNo of residues = " +\r
130                             ( (PDBChain) pdb.chains.elementAt(i)).residues.size() +\r
131                             "\n\n");\r
132 \r
133       // Now lets compare the sequences to get\r
134       // the start and end points.\r
135       // Align the sequence to the pdb\r
136       AlignSeq as = new AlignSeq(sequence,\r
137                                  ( (PDBChain) pdb.chains.elementAt(i)).sequence,\r
138                                  "pep");\r
139       as.calcScoreMatrix();\r
140       as.traceAlignment();\r
141       PrintStream ps = new PrintStream(System.out)\r
142       {\r
143         public void print(String x)\r
144         {\r
145           mappingDetails.append(x);\r
146         }\r
147 \r
148         public void println()\r
149         {\r
150           mappingDetails.append("\n");\r
151         }\r
152       };\r
153 \r
154       as.printAlignment(ps);\r
155 \r
156       if (as.maxscore > max)\r
157       {\r
158         max = as.maxscore;\r
159         maxchain = i;\r
160 \r
161         pdbstart = as.seq2start;\r
162         pdbend = as.seq2end;\r
163         seqstart = as.seq1start + sequence.getStart() - 1;\r
164         seqend = as.seq1end + sequence.getEnd() - 1;\r
165         maxAlignseq = as;\r
166       }\r
167 \r
168       mappingDetails.append("\nPDB start/end " + pdbstart + " " + pdbend);\r
169       mappingDetails.append("\nSEQ start/end " + seqstart + " " + seqend);\r
170     }\r
171 \r
172     mainchain = (PDBChain) pdb.chains.elementAt(maxchain);\r
173 \r
174     mainchain.pdbstart = pdbstart;\r
175     mainchain.pdbend = pdbend;\r
176     mainchain.seqstart = seqstart;\r
177     mainchain.seqend = seqend;\r
178     mainchain.isVisible = true;\r
179   //  mainchain.makeExactMapping(maxAlignseq, sequence);\r
180   //  mainchain.transferRESNUMFeatures(sequence, null);\r
181     this.pdb = pdb;\r
182     this.prefsize = new Dimension(getSize().width, getSize().height);\r
183 \r
184     //Initialize the matrices to identity\r
185     for (int i = 0; i < 3; i++)\r
186     {\r
187       for (int j = 0; j < 3; j++)\r
188       {\r
189         if (i != j)\r
190         {\r
191           idmat.addElement(i, j, 0);\r
192           objmat.addElement(i, j, 0);\r
193         }\r
194         else\r
195         {\r
196           idmat.addElement(i, j, 1);\r
197           objmat.addElement(i, j, 1);\r
198         }\r
199       }\r
200     }\r
201 \r
202     addMouseMotionListener(this);\r
203     addMouseListener(this);\r
204 \r
205     addKeyListener(new KeyAdapter()\r
206     {\r
207       public void keyPressed(KeyEvent evt)\r
208       {\r
209         doKeyPressed(evt);\r
210       }\r
211     });\r
212 \r
213     findCentre();\r
214     findWidth();\r
215 \r
216     setupBonds();\r
217 \r
218     scale = findScale();\r
219   }\r
220 \r
221   Vector visiblebonds;\r
222   void setupBonds()\r
223   {\r
224     seqColoursReady = false;\r
225     // Sort the bonds by z coord\r
226     visiblebonds = new Vector();\r
227 \r
228     for (int ii = 0; ii < pdb.chains.size(); ii++)\r
229     {\r
230       if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
231       {\r
232         Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
233 \r
234         for (int i = 0; i < tmp.size(); i++)\r
235         {\r
236           visiblebonds.addElement(tmp.elementAt(i));\r
237         }\r
238       }\r
239     }\r
240     seqColoursReady = true;\r
241     colourBySequence(ap.getSequenceRenderer(),\r
242                                ap.av.getShowSequenceFeatures() ?\r
243                                ap.getFeatureRenderer() : null);\r
244     redrawneeded = true;\r
245     repaint();\r
246   }\r
247 \r
248   public void findWidth()\r
249   {\r
250     float[] max = new float[3];\r
251     float[] min = new float[3];\r
252 \r
253     max[0] = (float) - 1e30;\r
254     max[1] = (float) - 1e30;\r
255     max[2] = (float) - 1e30;\r
256 \r
257     min[0] = (float) 1e30;\r
258     min[1] = (float) 1e30;\r
259     min[2] = (float) 1e30;\r
260 \r
261     for (int ii = 0; ii < pdb.chains.size(); ii++)\r
262     {\r
263       if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
264       {\r
265         Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
266 \r
267         for (int i = 0; i < bonds.size(); i++)\r
268         {\r
269           Bond tmp = (Bond) bonds.elementAt(i);\r
270 \r
271           if (tmp.start[0] >= max[0])\r
272           {\r
273             max[0] = tmp.start[0];\r
274           }\r
275 \r
276           if (tmp.start[1] >= max[1])\r
277           {\r
278             max[1] = tmp.start[1];\r
279           }\r
280 \r
281           if (tmp.start[2] >= max[2])\r
282           {\r
283             max[2] = tmp.start[2];\r
284           }\r
285 \r
286           if (tmp.start[0] <= min[0])\r
287           {\r
288             min[0] = tmp.start[0];\r
289           }\r
290 \r
291           if (tmp.start[1] <= min[1])\r
292           {\r
293             min[1] = tmp.start[1];\r
294           }\r
295 \r
296           if (tmp.start[2] <= min[2])\r
297           {\r
298             min[2] = tmp.start[2];\r
299           }\r
300 \r
301           if (tmp.end[0] >= max[0])\r
302           {\r
303             max[0] = tmp.end[0];\r
304           }\r
305 \r
306           if (tmp.end[1] >= max[1])\r
307           {\r
308             max[1] = tmp.end[1];\r
309           }\r
310 \r
311           if (tmp.end[2] >= max[2])\r
312           {\r
313             max[2] = tmp.end[2];\r
314           }\r
315 \r
316           if (tmp.end[0] <= min[0])\r
317           {\r
318             min[0] = tmp.end[0];\r
319           }\r
320 \r
321           if (tmp.end[1] <= min[1])\r
322           {\r
323             min[1] = tmp.end[1];\r
324           }\r
325 \r
326           if (tmp.end[2] <= min[2])\r
327           {\r
328             min[2] = tmp.end[2];\r
329           }\r
330         }\r
331       }\r
332     }\r
333 \r
334     width[0] = (float) Math.abs(max[0] - min[0]);\r
335     width[1] = (float) Math.abs(max[1] - min[1]);\r
336     width[2] = (float) Math.abs(max[2] - min[2]);\r
337 \r
338     maxwidth = width[0];\r
339 \r
340     if (width[1] > width[0])\r
341     {\r
342       maxwidth = width[1];\r
343     }\r
344 \r
345     if (width[2] > width[1])\r
346     {\r
347       maxwidth = width[2];\r
348     }\r
349 \r
350     // System.out.println("Maxwidth = " + maxwidth);\r
351   }\r
352 \r
353   public float findScale()\r
354   {\r
355     int dim;\r
356     int width;\r
357     int height;\r
358 \r
359     if (getSize().width != 0)\r
360     {\r
361       width = getSize().width;\r
362       height = getSize().height;\r
363     }\r
364     else\r
365     {\r
366       width = prefsize.width;\r
367       height = prefsize.height;\r
368     }\r
369 \r
370     if (width < height)\r
371     {\r
372       dim = width;\r
373     }\r
374     else\r
375     {\r
376       dim = height;\r
377     }\r
378 \r
379     return (float) (dim / (1.5d * maxwidth));\r
380   }\r
381 \r
382   public void findCentre()\r
383   {\r
384     float xtot = 0;\r
385     float ytot = 0;\r
386     float ztot = 0;\r
387 \r
388     int bsize = 0;\r
389 \r
390     //Find centre coordinate\r
391     for (int ii = 0; ii < pdb.chains.size(); ii++)\r
392     {\r
393       if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
394       {\r
395         Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
396 \r
397         bsize += bonds.size();\r
398 \r
399         for (int i = 0; i < bonds.size(); i++)\r
400         {\r
401           xtot = xtot + ( (Bond) bonds.elementAt(i)).start[0] +\r
402               ( (Bond) bonds.elementAt(i)).end[0];\r
403 \r
404           ytot = ytot + ( (Bond) bonds.elementAt(i)).start[1] +\r
405               ( (Bond) bonds.elementAt(i)).end[1];\r
406 \r
407           ztot = ztot + ( (Bond) bonds.elementAt(i)).start[2] +\r
408               ( (Bond) bonds.elementAt(i)).end[2];\r
409         }\r
410       }\r
411     }\r
412 \r
413     centre[0] = xtot / (2 * (float) bsize);\r
414     centre[1] = ytot / (2 * (float) bsize);\r
415     centre[2] = ztot / (2 * (float) bsize);\r
416   }\r
417 \r
418   public void paint(Graphics g)\r
419   {\r
420 \r
421     if (errorLoading)\r
422     {\r
423       g.setColor(Color.white);\r
424       g.fillRect(0, 0, getSize().width, getSize().height);\r
425       g.setColor(Color.black);\r
426       g.setFont(new Font("Verdana", Font.BOLD, 14));\r
427       g.drawString("Error loading PDB data!!", 50, getSize().height / 2);\r
428       return;\r
429     }\r
430 \r
431     if (!seqColoursReady)\r
432     {\r
433       g.setColor(Color.black);\r
434       g.setFont(new Font("Verdana", Font.BOLD, 14));\r
435       g.drawString("Fetching PDB data...", 50, getSize().height / 2);\r
436       return;\r
437     }\r
438 \r
439     //Only create the image at the beginning -\r
440     //this saves much memory usage\r
441     if ( (img == null) || (prefsize.width != getSize().width) ||\r
442         (prefsize.height != getSize().height))\r
443     {\r
444 \r
445       try\r
446       {\r
447         prefsize.width = getSize().width;\r
448         prefsize.height = getSize().height;\r
449 \r
450         scale = findScale();\r
451         img = createImage(prefsize.width, prefsize.height);\r
452         ig = img.getGraphics();\r
453 \r
454         redrawneeded = true;\r
455       }\r
456       catch (Exception ex)\r
457       {\r
458         ex.printStackTrace();\r
459       }\r
460     }\r
461 \r
462     if (redrawneeded)\r
463     {\r
464       drawAll(ig, prefsize.width, prefsize.height);\r
465       redrawneeded = false;\r
466     }\r
467     if (appletToolTip != null)\r
468     {\r
469       ig.setColor(Color.red);\r
470       ig.drawString(appletToolTip, toolx, tooly);\r
471     }\r
472 \r
473     g.drawImage(img, 0, 0, this);\r
474 \r
475     pdbAction = false;\r
476   }\r
477 \r
478   public void drawAll(Graphics g, int width, int height)\r
479   {\r
480     ig.setColor(Color.black);\r
481     ig.fillRect(0, 0, width, height);\r
482     drawScene(ig);\r
483     drawLabels(ig);\r
484   }\r
485 \r
486   public void setColours(jalview.schemes.ColourSchemeI cs)\r
487   {\r
488     bysequence = false;\r
489     pdb.setColours(cs);\r
490     redrawneeded = true;\r
491     repaint();\r
492   }\r
493 \r
494 \r
495 \r
496   // This method has been taken out of PDBChain to allow\r
497   // Applet and Application specific sequence renderers to be used\r
498   void colourBySequence(SequenceRenderer sr, FeatureRenderer fr)\r
499   {\r
500     StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());\r
501 \r
502     boolean showFeatures = false;\r
503     if (fr!=null)\r
504     {\r
505       if (fr == null)\r
506       {\r
507         fr = new jalview.appletgui.FeatureRenderer(ap.av);\r
508       }\r
509       fr.transferSettings(fr);\r
510       showFeatures = true;\r
511     }\r
512 \r
513     PDBChain chain;\r
514     if (bysequence && pdb != null)\r
515     {\r
516       for (int ii = 0; ii < pdb.chains.size(); ii++)\r
517       {\r
518         chain = (PDBChain) pdb.chains.elementAt(ii);\r
519 \r
520         for (int i = 0; i < chain.bonds.size(); i++)\r
521         {\r
522           Bond tmp = (Bond) chain.bonds.elementAt(i);\r
523           tmp.startCol = Color.lightGray;\r
524           tmp.endCol = Color.lightGray;\r
525           if (chain != mainchain)\r
526           {\r
527             continue;\r
528           }\r
529 \r
530           for (int s = 0; s < sequence.length; s++)\r
531           {\r
532             for (int m = 0; m < mapping.length; m++)\r
533             {\r
534               if (mapping[m].getSequence() == sequence[s])\r
535               {\r
536                 int pos = mapping[m].getSeqPos(tmp.at1.resNumber)-1;\r
537                 if (pos > 0)\r
538                 {\r
539                   pos = sequence[s].findIndex(pos);\r
540                   tmp.startCol = sr.getResidueBoxColour(sequence[s], pos);\r
541                   if (showFeatures)\r
542                   {\r
543                     tmp.startCol = fr.findFeatureColour(tmp.startCol,\r
544                                                         sequence[s],\r
545                                                         pos);\r
546                   }\r
547                 }\r
548                 pos = mapping[m].getSeqPos(tmp.at2.resNumber)-1;\r
549                 if (pos > 0)\r
550                 {\r
551                   pos = sequence[s].findIndex(pos);\r
552                   tmp.endCol = sr.getResidueBoxColour(sequence[s], pos);\r
553                   if (showFeatures)\r
554                   {\r
555                     tmp.endCol = fr.findFeatureColour(tmp.endCol,\r
556                                                         sequence[s],\r
557                                                         pos);\r
558                   }\r
559                 }\r
560 \r
561               }\r
562             }\r
563           }\r
564         }\r
565       }\r
566     }\r
567   }\r
568 \r
569   Zsort zsort;\r
570   public void drawScene(Graphics g)\r
571   {\r
572     if (zbuffer)\r
573     {\r
574       if (zsort == null)\r
575       {\r
576         zsort = new Zsort();\r
577       }\r
578 \r
579       zsort.Zsort(visiblebonds);\r
580     }\r
581 \r
582     Bond tmpBond = null;\r
583     for (int i = 0; i < visiblebonds.size(); i++)\r
584     {\r
585       tmpBond = (Bond) visiblebonds.elementAt(i);\r
586 \r
587       xstart = (int) ( ( (tmpBond.start[0] - centre[0]) * scale) +\r
588                       (getSize().width / 2));\r
589       ystart = (int) ( ( (tmpBond.start[1] - centre[1]) * scale) +\r
590                       (getSize().height / 2));\r
591 \r
592       xend = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +\r
593                     (getSize().width / 2));\r
594       yend = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +\r
595                     (getSize().height / 2));\r
596 \r
597       xmid = (xend + xstart) / 2;\r
598       ymid = (yend + ystart) / 2;\r
599 \r
600       if (depthcue && !bymolecule)\r
601       {\r
602         if (tmpBond.start[2] < (centre[2] - (maxwidth / 6)))\r
603         {\r
604           g.setColor(tmpBond.startCol.darker().darker());\r
605           drawLine(g, xstart, ystart, xmid, ymid);\r
606 \r
607           g.setColor(tmpBond.endCol.darker().darker());\r
608           drawLine(g, xmid, ymid, xend, yend);\r
609         }\r
610         else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6)))\r
611         {\r
612           g.setColor(tmpBond.startCol.darker());\r
613           drawLine(g, xstart, ystart, xmid, ymid);\r
614 \r
615           g.setColor(tmpBond.endCol.darker());\r
616           drawLine(g, xmid, ymid, xend, yend);\r
617         }\r
618         else\r
619         {\r
620           g.setColor(tmpBond.startCol);\r
621           drawLine(g, xstart, ystart, xmid, ymid);\r
622 \r
623           g.setColor(tmpBond.endCol);\r
624           drawLine(g, xmid, ymid, xend, yend);\r
625         }\r
626 \r
627       }\r
628       else if (depthcue && bymolecule)\r
629       {\r
630         if (tmpBond.start[2] < (centre[2] - (maxwidth / 6)))\r
631         {\r
632           g.setColor(Color.green.darker().darker());\r
633           drawLine(g, xstart, ystart, xend, yend);\r
634         }\r
635         else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6)))\r
636         {\r
637           g.setColor(Color.green.darker());\r
638           drawLine(g, xstart, ystart, xend, yend);\r
639         }\r
640         else\r
641         {\r
642           g.setColor(Color.green);\r
643           drawLine(g, xstart, ystart, xend, yend);\r
644         }\r
645       }\r
646       else if (!depthcue && !bymolecule)\r
647       {\r
648         g.setColor(tmpBond.startCol);\r
649         drawLine(g, xstart, ystart, xmid, ymid);\r
650         g.setColor(tmpBond.endCol);\r
651         drawLine(g, xmid, ymid, xend, yend);\r
652       }\r
653       else\r
654       {\r
655         drawLine(g, xstart, ystart, xend, yend);\r
656       }\r
657 \r
658       if (highlightBond1 != null && highlightBond1 == tmpBond)\r
659       {\r
660         g.setColor(Color.white);\r
661         drawLine(g, xmid, ymid, xend, yend);\r
662       }\r
663 \r
664       if (highlightBond2 != null && highlightBond2 == tmpBond)\r
665       {\r
666         g.setColor(Color.white);\r
667         drawLine(g, xstart, ystart, xmid, ymid);\r
668       }\r
669 \r
670     }\r
671   }\r
672 \r
673   public void drawLine(Graphics g, int x1, int y1, int x2, int y2)\r
674   {\r
675     if (!wire)\r
676     {\r
677       if ( ( (float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5)\r
678       {\r
679         g.drawLine(x1, y1, x2, y2);\r
680         g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);\r
681         g.drawLine(x1, y1 - 1, x2, y2 - 1);\r
682       }\r
683       else\r
684       {\r
685         g.setColor(g.getColor().brighter());\r
686         g.drawLine(x1, y1, x2, y2);\r
687         g.drawLine(x1 + 1, y1, x2 + 1, y2);\r
688         g.drawLine(x1 - 1, y1, x2 - 1, y2);\r
689       }\r
690     }\r
691     else\r
692     {\r
693       g.drawLine(x1, y1, x2, y2);\r
694     }\r
695   }\r
696 \r
697   public Dimension minimumsize()\r
698   {\r
699     return prefsize;\r
700   }\r
701 \r
702   public Dimension preferredsize()\r
703   {\r
704     return prefsize;\r
705   }\r
706 \r
707   public void doKeyPressed(KeyEvent evt)\r
708   {\r
709     if (evt.getKeyCode() == KeyEvent.VK_UP)\r
710     {\r
711       scale = (float) (scale * 1.1);\r
712       redrawneeded = true;\r
713       repaint();\r
714     }\r
715     else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
716     {\r
717       scale = (float) (scale * 0.9);\r
718       redrawneeded = true;\r
719       repaint();\r
720     }\r
721   }\r
722 \r
723   public void mousePressed(MouseEvent e)\r
724   {\r
725     pdbAction = true;\r
726     Atom fatom = findAtom(e.getX(), e.getY());\r
727     if (fatom != null)\r
728     {\r
729       fatom.isSelected = !fatom.isSelected;\r
730 \r
731       redrawneeded = true;\r
732       repaint();\r
733       if (foundchain != -1)\r
734       {\r
735         PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
736         if (chain == mainchain)\r
737         {\r
738           if (fatom.alignmentMapping != -1)\r
739           {\r
740             if (highlightRes == null)\r
741             {\r
742               highlightRes = new Vector();\r
743             }\r
744 \r
745             if (highlightRes.contains(fatom.alignmentMapping + "" + ""))\r
746             {\r
747               highlightRes.removeElement(fatom.alignmentMapping + "");\r
748             }\r
749             else\r
750             {\r
751               highlightRes.addElement(fatom.alignmentMapping + "");\r
752             }\r
753           }\r
754         }\r
755       }\r
756 \r
757     }\r
758     mx = e.getX();\r
759     my = e.getY();\r
760     omx = mx;\r
761     omy = my;\r
762     dragging = false;\r
763   }\r
764 \r
765   public void mouseMoved(MouseEvent e)\r
766   {\r
767     pdbAction = true;\r
768     if (highlightBond1 != null)\r
769     {\r
770       highlightBond1.at2.isSelected = false;\r
771       highlightBond2.at1.isSelected = false;\r
772       highlightBond1 = null;\r
773       highlightBond2 = null;\r
774     }\r
775 \r
776     Atom fatom = findAtom(e.getX(), e.getY());\r
777 \r
778     PDBChain chain = null;\r
779     if (foundchain != -1)\r
780     {\r
781       chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
782       if (chain == mainchain)\r
783       {\r
784         mouseOverStructure(fatom.resNumber, chain.id);\r
785       }\r
786     }\r
787 \r
788     if (fatom != null)\r
789     {\r
790       toolx = e.getX();\r
791       tooly = e.getY();\r
792 \r
793       appletToolTip = chain.id + ":" + fatom.resNumber + " " + fatom.resName;\r
794       redrawneeded = true;\r
795       repaint();\r
796     }\r
797     else\r
798     {\r
799       mouseOverStructure(-1, chain!=null?chain.id:null);\r
800       appletToolTip = null;\r
801       redrawneeded = true;\r
802       repaint();\r
803     }\r
804   }\r
805 \r
806   public void mouseClicked(MouseEvent e)\r
807   {\r
808   }\r
809 \r
810   public void mouseEntered(MouseEvent e)\r
811   {\r
812   }\r
813 \r
814   public void mouseExited(MouseEvent e)\r
815   {\r
816   }\r
817 \r
818   public void mouseDragged(MouseEvent evt)\r
819   {\r
820     int x = evt.getX();\r
821     int y = evt.getY();\r
822     mx = x;\r
823     my = y;\r
824 \r
825     MCMatrix objmat = new MCMatrix(3, 3);\r
826     objmat.setIdentity();\r
827 \r
828     if ( (evt.getModifiers() & Event.META_MASK) != 0)\r
829     {\r
830       objmat.rotatez( (float) ( (mx - omx)));\r
831     }\r
832     else\r
833     {\r
834       objmat.rotatex( (float) ( (my - omy)));\r
835       objmat.rotatey( (float) ( (omx - mx)));\r
836     }\r
837 \r
838     //Alter the bonds\r
839     for (int ii = 0; ii < pdb.chains.size(); ii++)\r
840     {\r
841       Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
842 \r
843       for (int i = 0; i < bonds.size(); i++)\r
844       {\r
845         Bond tmpBond = (Bond) bonds.elementAt(i);\r
846 \r
847         //Translate the bond so the centre is 0,0,0\r
848         tmpBond.translate( -centre[0], -centre[1], -centre[2]);\r
849 \r
850         //Now apply the rotation matrix\r
851         tmpBond.start = objmat.vectorMultiply(tmpBond.start);\r
852         tmpBond.end = objmat.vectorMultiply(tmpBond.end);\r
853 \r
854         //Now translate back again\r
855         tmpBond.translate(centre[0], centre[1], centre[2]);\r
856       }\r
857     }\r
858 \r
859     objmat = null;\r
860 \r
861     omx = mx;\r
862     omy = my;\r
863 \r
864     dragging = true;\r
865 \r
866     redrawneeded = true;\r
867 \r
868     repaint();\r
869   }\r
870 \r
871   public void mouseReleased(MouseEvent evt)\r
872   {\r
873     dragging = false;\r
874     return;\r
875   }\r
876 \r
877   void drawLabels(Graphics g)\r
878   {\r
879 \r
880     for (int ii = 0; ii < pdb.chains.size(); ii++)\r
881     {\r
882       PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
883 \r
884       if (chain.isVisible)\r
885       {\r
886         Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
887 \r
888         for (int i = 0; i < bonds.size(); i++)\r
889         {\r
890           Bond tmpBond = (Bond) bonds.elementAt(i);\r
891 \r
892           if (tmpBond.at1.isSelected)\r
893           {\r
894             labelAtom(g, tmpBond, 1);\r
895           }\r
896 \r
897           if (tmpBond.at2.isSelected)\r
898           {\r
899 \r
900             labelAtom(g, tmpBond, 2);\r
901           }\r
902         }\r
903       }\r
904     }\r
905   }\r
906 \r
907   public void labelAtom(Graphics g, Bond b, int n)\r
908   {\r
909     g.setFont(font);\r
910 \r
911     if (n == 1)\r
912     {\r
913       int xstart = (int) ( ( (b.start[0] - centre[0]) * scale) +\r
914                           (getSize().width / 2));\r
915       int ystart = (int) ( ( (b.start[1] - centre[1]) * scale) +\r
916                           (getSize().height / 2));\r
917 \r
918       g.setColor(Color.red);\r
919       g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
920     }\r
921 \r
922     if (n == 2)\r
923     {\r
924       int xstart = (int) ( ( (b.end[0] - centre[0]) * scale) +\r
925                           (getSize().width / 2));\r
926       int ystart = (int) ( ( (b.end[1] - centre[1]) * scale) +\r
927                           (getSize().height / 2));\r
928 \r
929       g.setColor(Color.red);\r
930       g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
931     }\r
932   }\r
933 \r
934   int foundchain = -1;\r
935   public Atom findAtom(int x, int y)\r
936   {\r
937     Atom fatom = null;\r
938 \r
939     foundchain = -1;\r
940 \r
941     for (int ii = 0; ii < pdb.chains.size(); ii++)\r
942     {\r
943       PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
944       int truex;\r
945       Bond tmpBond = null;\r
946 \r
947       if (chain.isVisible)\r
948       {\r
949         Vector bonds = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
950 \r
951         for (int i = 0; i < bonds.size(); i++)\r
952         {\r
953           tmpBond = (Bond) bonds.elementAt(i);\r
954 \r
955           truex = (int) ( ( (tmpBond.start[0] - centre[0]) * scale) +\r
956                          (getSize().width / 2));\r
957 \r
958           if (Math.abs(truex - x) <= 2)\r
959           {\r
960             int truey = (int) ( ( (tmpBond.start[1] - centre[1]) * scale) +\r
961                                (getSize().height / 2));\r
962 \r
963             if (Math.abs(truey - y) <= 2)\r
964             {\r
965               fatom = tmpBond.at1;\r
966               foundchain = ii;\r
967               break;\r
968             }\r
969           }\r
970         }\r
971 \r
972         // Still here? Maybe its the last bond\r
973 \r
974         truex = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +\r
975                        (getSize().width / 2));\r
976 \r
977         if (Math.abs(truex - x) <= 2)\r
978         {\r
979           int truey = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +\r
980                              (getSize().height / 2));\r
981 \r
982           if (Math.abs(truey - y) <= 2)\r
983           {\r
984             fatom = tmpBond.at2;\r
985             foundchain = ii;\r
986             break;\r
987           }\r
988         }\r
989 \r
990       }\r
991 \r
992       if (fatom != null) //)&& chain.ds != null)\r
993       {\r
994         chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
995       }\r
996     }\r
997 \r
998     return fatom;\r
999   }\r
1000 \r
1001   public void update(Graphics g)\r
1002   {\r
1003     paint(g);\r
1004   }\r
1005 \r
1006   public void highlightRes(int ii)\r
1007   {\r
1008     if (!seqColoursReady)\r
1009     {\r
1010       return;\r
1011     }\r
1012 \r
1013     if (highlightRes != null\r
1014         && highlightRes.contains( (ii - 1) + ""))\r
1015     {\r
1016       return;\r
1017     }\r
1018 \r
1019     int index = -1;\r
1020     Bond tmpBond;\r
1021     for (index = 0; index < mainchain.bonds.size(); index++)\r
1022     {\r
1023       tmpBond = (Bond) mainchain.bonds.elementAt(index);\r
1024       if (tmpBond.at1.alignmentMapping == ii - 1)\r
1025       {\r
1026         if (highlightBond1 != null)\r
1027         {\r
1028           highlightBond1.at2.isSelected = false;\r
1029         }\r
1030 \r
1031         if (highlightBond2 != null)\r
1032         {\r
1033           highlightBond2.at1.isSelected = false;\r
1034         }\r
1035 \r
1036         highlightBond1 = null;\r
1037         highlightBond2 = null;\r
1038 \r
1039         if (index > 0)\r
1040         {\r
1041           highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);\r
1042           highlightBond1.at2.isSelected = true;\r
1043         }\r
1044 \r
1045         if (index != mainchain.bonds.size())\r
1046         {\r
1047           highlightBond2 = (Bond) mainchain.bonds.elementAt(index);\r
1048           highlightBond2.at1.isSelected = true;\r
1049         }\r
1050 \r
1051         break;\r
1052       }\r
1053     }\r
1054 \r
1055     redrawneeded = true;\r
1056     repaint();\r
1057   }\r
1058 \r
1059   public void setAllchainsVisible(boolean b)\r
1060   {\r
1061     for (int ii = 0; ii < pdb.chains.size(); ii++)\r
1062     {\r
1063       PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
1064       chain.isVisible = b;\r
1065     }\r
1066     mainchain.isVisible = true;\r
1067     findCentre();\r
1068     setupBonds();\r
1069   }\r
1070 \r
1071 \r
1072   //////////////////////////////////\r
1073   ///StructureListener\r
1074   public String getPdbFile()\r
1075   {\r
1076     return "???";\r
1077   }\r
1078 \r
1079 \r
1080   String lastMessage;\r
1081   public void mouseOverStructure(int pdbResNum, String chain)\r
1082   {\r
1083       if (lastMessage == null || !lastMessage.equals(pdbResNum+chain))\r
1084         ssm.mouseOverStructure(pdbResNum, chain, pdbentry.getFile());\r
1085 \r
1086       lastMessage = pdbResNum+chain;\r
1087   }\r
1088 \r
1089   StringBuffer resetLastRes = new StringBuffer();\r
1090   StringBuffer eval = new StringBuffer();\r
1091 \r
1092   public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile)\r
1093   {\r
1094     if (!seqColoursReady)\r
1095     {\r
1096       return;\r
1097     }\r
1098 \r
1099     if (highlightRes != null\r
1100         && highlightRes.contains( (atomIndex - 1) + ""))\r
1101     {\r
1102       return;\r
1103     }\r
1104 \r
1105     int index = -1;\r
1106     Bond tmpBond;\r
1107     for (index = 0; index < mainchain.bonds.size(); index++)\r
1108     {\r
1109       tmpBond = (Bond) mainchain.bonds.elementAt(index);\r
1110       if (tmpBond.at1.atomIndex == atomIndex)\r
1111       {\r
1112         if (highlightBond1 != null)\r
1113         {\r
1114           highlightBond1.at2.isSelected = false;\r
1115         }\r
1116 \r
1117         if (highlightBond2 != null)\r
1118         {\r
1119           highlightBond2.at1.isSelected = false;\r
1120         }\r
1121 \r
1122         highlightBond1 = null;\r
1123         highlightBond2 = null;\r
1124 \r
1125         if (index > 0)\r
1126         {\r
1127           highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);\r
1128           highlightBond1.at2.isSelected = true;\r
1129         }\r
1130 \r
1131         if (index != mainchain.bonds.size())\r
1132         {\r
1133           highlightBond2 = (Bond) mainchain.bonds.elementAt(index);\r
1134           highlightBond2.at1.isSelected = true;\r
1135         }\r
1136 \r
1137         break;\r
1138       }\r
1139     }\r
1140 \r
1141     redrawneeded = true;\r
1142     repaint();\r
1143   }\r
1144 \r
1145   public void updateColours(Object source)\r
1146   {\r
1147     AlignmentPanel ap = (AlignmentPanel) source;\r
1148     colourBySequence(ap.getSequenceRenderer(),\r
1149                      ap.av.getShowSequenceFeatures() ?\r
1150                      ap.getFeatureRenderer() : null);\r
1151     redrawneeded = true;\r
1152     repaint();\r
1153   }\r
1154 \r
1155 \r
1156 }\r