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