JAL-629 Fasta sequence id reading whitespace fix. Flexioble pae json keys and structu...
[jalview.git] / src / jalview / appletgui / #OverviewPanel.java#
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.appletgui;
22
23 import jalview.datamodel.SequenceI;
24 import jalview.viewmodel.OverviewDimensions;
25 import jalview.datamodel.AlignmentI;
26 import jalview.renderer.seqfeatures.FeatureColourFinder;
27
28 import java.awt.Color;
29 import java.awt.Dimension;
30 import java.awt.Frame;
31 import java.awt.Graphics;
32 import java.awt.Image;
33 import java.awt.Panel;
34 import java.awt.event.ComponentAdapter;
35 import java.awt.event.ComponentEvent;
36 import java.awt.event.MouseEvent;
37 import java.awt.event.MouseListener;
38 import java.awt.event.MouseMotionListener;
39
40 public class OverviewPanel extends Panel implements Runnable,
41         MouseMotionListener, MouseListener
42 {
43   private OverviewDimensions od;
44
45   private Image miniMe;
46
47   private Image offscreen;
48
49   private AlignViewport av;
50
51   private AlignmentPanel ap;
52
53   private boolean resizing = false;
54
55   // This is set true if the user resizes whilst
56   // the overview is being calculated
57   private boolean resizeAgain = false;
58
59   // Can set different properties in this seqCanvas than
60   // main visible SeqCanvas
61   private SequenceRenderer sr;
62
63   private FeatureRenderer fr;
64
65   private Frame nullFrame;
66
67   public OverviewPanel(AlignmentPanel alPanel)
68   {
69     this.av = alPanel.av;
70     this.ap = alPanel;
71     setLayout(null);
72     nullFrame = new Frame();
73     nullFrame.addNotify();
74
75     sr = new SequenceRenderer(av);
76     sr.graphics = nullFrame.getGraphics();
77     sr.renderGaps = false;
78     sr.forOverview = true;
79     fr = new FeatureRenderer(av);
80
81     od = new OverviewDimensions(av.getRanges(), av.isShowAnnotation());
82
83     setSize(new Dimension(od.getWidth(), od.getHeight()));
84     addComponentListener(new ComponentAdapter()
85     {
86
87       @Override
88       public void componentResized(ComponentEvent evt)
89       {
90         if ((getWidth() != od.getWidth())
91                 || (getHeight() != (od.getHeight())))
92         {
93           updateOverviewImage();
94         }
95       }
96     });
97
98     addMouseMotionListener(this);
99
100     addMouseListener(this);
101
102     updateOverviewImage();
103
104   }
105
106   @Override
107   public void mouseEntered(MouseEvent evt)
108   {
109   }
110
111   @Override
112   public void mouseExited(MouseEvent evt)
113   {
114   }
115
116   @Override
117   public void mouseClicked(MouseEvent evt)
118   {
119   }
120
121   @Override
122   public void mouseMoved(MouseEvent evt)
123   {
124   }
125
126   @Override
127   public void mousePressed(MouseEvent evt)
128   {
129     mouseAction(evt);
130   }
131
132   @Override
133   public void mouseReleased(MouseEvent evt)
134   {
135     mouseAction(evt);
136   }
137
138   @Override
139   public void mouseDragged(MouseEvent evt)
140   {
141     mouseAction(evt);
142   }
143
144   private void mouseAction(MouseEvent evt)
145   {
146     od.updateViewportFromMouse(evt.getX(), evt.getY(), av.getAlignment()
147             .getHiddenSequences(), av.getColumnSelection(), av
148             .getRanges());
149     ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
150     ap.paintAlignment(false);
151   }
152
153   /**
154    * Updates the overview image when the related alignment panel is updated
155    */
156   public void updateOverviewImage()
157   {
158     if (resizing)
159     {
160       resizeAgain = true;
161       return;
162     }
163
164     if (av.isShowSequenceFeatures())
165     {
166       fr.transferSettings(ap.seqPanel.seqCanvas.fr);
167     }
168
169     resizing = true;
170
171     if ((getSize().width > 0) && (getSize().height > 0))
172     {
173       od.setWidth(getSize().width);
174       od.setHeight(getSize().height);
175     }
176     setSize(new Dimension(od.getWidth(), od.getHeight()));
177
178     Thread thread = new Thread(this);
179     thread.start();
180     repaint();
181   }
182
183   @Override
184   public void run()
185   {
186     miniMe = null;
187
188     if (av.isShowSequenceFeatures())
189     {
190       fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
191     }
192
193     if (getSize().width > 0 && getSize().height > 0)
194     {
195       od.setWidth(getSize().width);
196       od.setHeight(getSize().height);
197     }
198
199     setSize(new Dimension(od.getWidth(), od.getHeight()));
200
201     miniMe = nullFrame.createImage(od.getWidth(), od.getHeight());
202     offscreen = nullFrame.createImage(od.getWidth(), od.getHeight());
203
204     Graphics mg = miniMe.getGraphics();
205 <<<<<<< HEAD
206
207     int alwidth = av.getAlignment().getWidth();
208     int alheight = av.getAlignment().getAbsoluteHeight();
209     float sampleCol = alwidth / (float) od.getWidth();
210     float sampleRow = alheight / (float) od.getSequencesHeight();
211 =======
212     float sampleCol = (float) alwidth / (float) width;
213     float sampleRow = (float) alheight / (float) sequencesHeight;
214
215     int lastcol = 0, lastrow = 0;
216     int xstart = 0, ystart = 0;
217     Color color = Color.yellow;
218     int row, col, sameRow = 0, sameCol = 0;
219     jalview.datamodel.SequenceI seq;
220     final boolean hasHiddenRows = av.hasHiddenRows(), hasHiddenCols = av
221             .hasHiddenColumns();
222     boolean hiddenRow = false;
223     AlignmentI alignment = av.getAlignment();
224
225     FeatureColourFinder finder = new FeatureColourFinder(fr);
226     for (row = 0; row <= sequencesHeight; row++)
227     {
228       if (resizeAgain)
229       {
230         break;
231       }
232       if ((int) (row * sampleRow) == lastrow)
233       {
234         sameRow++;
235         continue;
236       }
237
238       hiddenRow = false;
239       if (hasHiddenRows)
240       {
241         seq = alignment.getHiddenSequences().getHiddenSequence(lastrow);
242         if (seq == null)
243         {
244           int index = alignment.getHiddenSequences()
245                   .findIndexWithoutHiddenSeqs(lastrow);
246
247           seq = alignment.getSequenceAt(index);
248         }
249         else
250         {
251           hiddenRow = true;
252         }
253       }
254       else
255       {
256         seq = alignment.getSequenceAt(lastrow);
257       }
258
259       for (col = 0; col < width; col++)
260       {
261         if ((int) (col * sampleCol) == lastcol
262                 && (int) (row * sampleRow) == lastrow)
263         {
264           sameCol++;
265           continue;
266         }
267
268         lastcol = (int) (col * sampleCol);
269
270         if (seq.getLength() > lastcol)
271         {
272           color = sr.getResidueColour(seq, lastcol, finder);
273         }
274         else
275         {
276           color = Color.white;
277         }
278
279         if (hiddenRow
280                 || (hasHiddenCols && !av.getColumnSelection().isVisible(
281                         lastcol)))
282         {
283           color = color.darker().darker();
284         }
285
286         mg.setColor(color);
287         if (sameCol == 1 && sameRow == 1)
288         {
289           mg.drawLine(xstart, ystart, xstart, ystart);
290         }
291         else
292         {
293           mg.fillRect(xstart, ystart, sameCol, sameRow);
294         }
295 >>>>>>> bug/JAL-2436featureRendererThreading
296
297     buildImage(sampleRow, sampleCol, mg);
298
299     if (av.isShowAnnotation())
300     {
301       for (int col = 0; col < od.getWidth() && !resizeAgain; col++)
302       {
303         mg.translate(col, od.getSequencesHeight());
304         ap.annotationPanel.renderer.drawGraph(mg,
305                 av.getAlignmentConservationAnnotation(),
306                 av.getAlignmentConservationAnnotation().annotations,
307                 (int) (sampleCol) + 1, od.getGraphHeight(),
308                 (int) (col * sampleCol), (int) (col * sampleCol) + 1);
309         mg.translate(-col, -od.getSequencesHeight());
310       }
311     }
312     System.gc();
313
314     resizing = false;
315
316     setBoxPosition();
317
318     if (resizeAgain)
319     {
320       resizeAgain = false;
321       updateOverviewImage();
322     }
323   }
324
325   /*
326    * Build the overview panel image
327    */
328   private void buildImage(float sampleRow, float sampleCol, Graphics mg)
329   {
330     int lastcol = 0;
331     int lastrow = 0;
332     int xstart = 0;
333     int ystart = 0;
334     Color color = Color.yellow;
335     int sameRow = 0;
336     int sameCol = 0;
337
338     SequenceI seq = null;
339
340     final boolean hasHiddenCols = av.hasHiddenColumns();
341     boolean hiddenRow = false;
342
343     for (int row = 0; row <= od.getSequencesHeight() && !resizeAgain; row++)
344     {
345       if ((int) (row * sampleRow) == lastrow)
346       {
347         sameRow++;
348       }
349       else
350       {
351         // get the sequence which would be at alignment index 'lastrow' if no
352         // columns were hidden, and determine whether it is hidden or not
353         hiddenRow = av.getAlignment().isHidden(lastrow);
354         seq = av.getAlignment().getSequenceAtAbsoluteIndex(lastrow);
355
356         for (int col = 0; col < od.getWidth(); col++)
357         {
358           if ((int) (col * sampleCol) == lastcol
359                   && (int) (row * sampleRow) == lastrow)
360           {
361             sameCol++;
362           }
363           else
364           {
365             lastcol = (int) (col * sampleCol);
366
367             color = getColumnColourFromSequence(seq, hiddenRow,
368                     hasHiddenCols, lastcol);
369
370             mg.setColor(color);
371             if (sameCol == 1 && sameRow == 1)
372             {
373               mg.drawLine(xstart, ystart, xstart, ystart);
374             }
375             else
376             {
377               mg.fillRect(xstart, ystart, sameCol, sameRow);
378             }
379
380             xstart = col;
381             sameCol = 1;
382           }
383         }
384         lastrow = (int) (row * sampleRow);
385         ystart = row;
386         sameRow = 1;
387       }
388     }
389   }
390
391   /*
392    * Find the colour of a sequence at a specified column position
393    */
394   private Color getColumnColourFromSequence(
395           jalview.datamodel.SequenceI seq, boolean hiddenRow,
396           boolean hasHiddenCols, int lastcol)
397   {
398     Color color;
399     if (seq.getLength() > lastcol)
400     {
401       color = sr.getResidueBoxColour(seq, lastcol);
402
403       if (av.isShowSequenceFeatures())
404       {
405         color = fr.findFeatureColour(color, seq, lastcol);
406       }
407     }
408     else
409     {
410       color = Color.white;
411     }
412
413     if (hiddenRow
414             || (hasHiddenCols && !av.getColumnSelection()
415                     .isVisible(lastcol)))
416     {
417       color = color.darker().darker();
418     }
419     return color;
420   }
421
422   /**
423    * Update the overview panel box when the associated alignment panel is
424    * changed
425    * 
426    */
427   public void setBoxPosition()
428   {
429     od.setBoxPosition(av.getAlignment()
430             .getHiddenSequences(), av.getColumnSelection(), av.getRanges());
431     repaint();
432   }
433
434   @Override
435   public void update(Graphics g)
436   {
437     paint(g);
438   }
439
440   @Override
441   public void paint(Graphics g)
442   {
443     Graphics og = offscreen.getGraphics();
444     if (miniMe != null)
445     {
446       og.drawImage(miniMe, 0, 0, this);
447       og.setColor(Color.red);
448       od.drawBox(og);
449       g.drawImage(offscreen, 0, 0, this);
450     }
451   }
452
453 }