2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.appletgui;
23 import jalview.datamodel.AlignmentI;
24 import jalview.renderer.AnnotationRenderer;
26 import java.awt.Color;
27 import java.awt.Dimension;
28 import java.awt.Frame;
29 import java.awt.Graphics;
30 import java.awt.Image;
31 import java.awt.Panel;
32 import java.awt.event.ComponentAdapter;
33 import java.awt.event.ComponentEvent;
34 import java.awt.event.MouseEvent;
35 import java.awt.event.MouseListener;
36 import java.awt.event.MouseMotionListener;
38 public class OverviewPanel extends Panel implements Runnable,
39 MouseMotionListener, MouseListener
49 final AnnotationRenderer renderer = new AnnotationRenderer();
55 public int width, sequencesHeight;
59 int boxX = -1, boxY = -1, boxWidth = -1, boxHeight = -1;
61 boolean resizing = false;
63 // Can set different properties in this seqCanvas than
64 // main visible SeqCanvas
67 FeatureRendererAndEditor fr;
71 public OverviewPanel(AlignmentPanel ap)
76 nullFrame = new Frame();
77 nullFrame.addNotify();
79 sr = new SequenceRenderer(av);
80 sr.graphics = nullFrame.getGraphics();
81 sr.renderGaps = false;
82 sr.forOverview = true;
83 fr = new FeatureRendererAndEditor(av);
85 // scale the initial size of overviewpanel to shape of alignment
86 float initialScale = (float) av.getAlignment().getWidth()
87 / (float) av.getAlignment().getHeight();
89 if (av.getSequenceConsensusHash() == null)
94 if (av.getAlignment().getWidth() > av.getAlignment().getHeight())
98 sequencesHeight = (int) (400f / initialScale);
99 if (sequencesHeight < 40)
101 sequencesHeight = 40;
107 width = (int) (400f * initialScale);
108 sequencesHeight = 300;
115 setSize(new Dimension(width, sequencesHeight + graphHeight));
116 addComponentListener(new ComponentAdapter()
120 public void componentResized(ComponentEvent evt)
122 if (getSize().width != width
123 || getSize().height != sequencesHeight + graphHeight)
125 updateOverviewImage();
130 addMouseMotionListener(this);
132 addMouseListener(this);
134 updateOverviewImage();
139 public void mouseEntered(MouseEvent evt)
144 public void mouseExited(MouseEvent evt)
149 public void mouseClicked(MouseEvent evt)
154 public void mouseMoved(MouseEvent evt)
159 public void mousePressed(MouseEvent evt)
167 public void mouseReleased(MouseEvent evt)
175 public void mouseDragged(MouseEvent evt)
189 if (boxY > (sequencesHeight - boxHeight))
191 boxY = sequencesHeight - boxHeight + 1;
199 if (boxX > (width - boxWidth))
201 if (av.hasHiddenColumns())
203 // Try smallest possible box
204 boxWidth = (int) ((av.endRes - av.startRes + 1) * av.getCharWidth() * scalew);
206 boxX = width - boxWidth;
209 int col = (int) (boxX / scalew / av.getCharWidth());
210 int row = (int) (boxY / scaleh / av.getCharHeight());
212 if (av.hasHiddenColumns())
214 if (!av.getColumnSelection().isVisible(col))
219 col = av.getColumnSelection().findColumnPosition(col);
222 if (av.hasHiddenRows())
224 row = av.getAlignment().getHiddenSequences()
225 .findIndexWithoutHiddenSeqs(row);
228 ap.setScrollValues(col, row);
229 ap.paintAlignment(false);
235 public void updateOverviewImage()
243 if (av.isShowSequenceFeatures())
245 fr.transferSettings(ap.seqPanel.seqCanvas.fr);
250 if ((getSize().width > 0) && (getSize().height > 0))
252 width = getSize().width;
253 sequencesHeight = getSize().height - graphHeight;
255 setSize(new Dimension(width, sequencesHeight + graphHeight));
257 Thread thread = new Thread(this);
262 // This is set true if the user resizes whilst
263 // the overview is being calculated
264 boolean resizeAgain = false;
270 int alwidth = av.getAlignment().getWidth();
271 int alheight = av.getAlignment().getHeight()
272 + av.getAlignment().getHiddenSequences().getSize();
274 if (av.isShowSequenceFeatures())
276 fr.transferSettings(ap.getFeatureRenderer());
279 if (getSize().width > 0 && getSize().height > 0)
281 width = getSize().width;
282 sequencesHeight = getSize().height - graphHeight;
285 setSize(new Dimension(width, sequencesHeight + graphHeight));
287 int fullsizeWidth = alwidth * av.getCharWidth();
288 int fullsizeHeight = alheight * av.getCharHeight();
290 scalew = (float) width / (float) fullsizeWidth;
291 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
293 miniMe = nullFrame.createImage(width, sequencesHeight + graphHeight);
294 offscreen = nullFrame.createImage(width, sequencesHeight + graphHeight);
296 Graphics mg = miniMe.getGraphics();
297 float sampleCol = (float) alwidth / (float) width;
298 float sampleRow = (float) alheight / (float) sequencesHeight;
300 int lastcol = 0, lastrow = 0;
301 int xstart = 0, ystart = 0;
302 Color color = Color.yellow;
303 int row, col, sameRow = 0, sameCol = 0;
304 jalview.datamodel.SequenceI seq;
305 final boolean hasHiddenRows = av.hasHiddenRows(), hasHiddenCols = av
307 boolean hiddenRow = false;
308 AlignmentI alignment = av.getAlignment();
309 for (row = 0; row <= sequencesHeight; row++)
311 if ((int) (row * sampleRow) == lastrow)
320 seq = alignment.getHiddenSequences().getHiddenSequence(lastrow);
323 int index = alignment.getHiddenSequences()
324 .findIndexWithoutHiddenSeqs(lastrow);
326 seq = alignment.getSequenceAt(index);
335 seq = alignment.getSequenceAt(lastrow);
338 for (col = 0; col < width; col++)
340 if ((int) (col * sampleCol) == lastcol
341 && (int) (row * sampleRow) == lastrow)
347 lastcol = (int) (col * sampleCol);
349 if (seq.getLength() > lastcol)
351 color = sr.getResidueBoxColour(seq, lastcol);
353 if (av.isShowSequenceFeatures())
355 color = fr.findFeatureColour(color, seq, lastcol);
360 color = Color.white; // White
364 || (hasHiddenCols && !av.getColumnSelection().isVisible(
367 color = color.darker().darker();
371 if (sameCol == 1 && sameRow == 1)
373 mg.drawLine(xstart, ystart, xstart, ystart);
377 mg.fillRect(xstart, ystart, sameCol, sameRow);
383 lastrow = (int) (row * sampleRow);
388 if (av.getAlignmentConservationAnnotation() != null)
390 renderer.updateFromAlignViewport(av);
391 for (col = 0; col < width; col++)
393 lastcol = (int) (col * sampleCol);
395 mg.translate(col, sequencesHeight);
396 renderer.drawGraph(mg, av.getAlignmentConservationAnnotation(),
397 av.getAlignmentConservationAnnotation().annotations,
398 (int) (sampleCol) + 1, graphHeight,
399 (int) (col * sampleCol), (int) (col * sampleCol) + 1);
400 mg.translate(-col, -sequencesHeight);
413 updateOverviewImage();
417 public void setBoxPosition()
419 int fullsizeWidth = av.getAlignment().getWidth() * av.getCharWidth();
420 int fullsizeHeight = (av.getAlignment().getHeight() + av.getAlignment()
421 .getHiddenSequences().getSize())
422 * av.getCharHeight();
424 int startRes = av.getStartRes();
425 int endRes = av.getEndRes();
427 if (av.hasHiddenColumns())
429 startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);
430 endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);
433 int startSeq = av.startSeq;
434 int endSeq = av.endSeq;
436 if (av.hasHiddenRows())
438 startSeq = av.getAlignment().getHiddenSequences()
439 .adjustForHiddenSeqs(startSeq);
441 endSeq = av.getAlignment().getHiddenSequences()
442 .adjustForHiddenSeqs(endSeq);
446 scalew = (float) width / (float) fullsizeWidth;
447 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
449 boxX = (int) (startRes * av.getCharWidth() * scalew);
450 boxY = (int) (startSeq * av.getCharHeight() * scaleh);
452 if (av.hasHiddenColumns())
454 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
458 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
461 boxHeight = (int) ((endSeq - startSeq) * av.getCharHeight() * scaleh);
467 public void update(Graphics g)
473 public void paint(Graphics g)
475 Graphics og = offscreen.getGraphics();
478 og.drawImage(miniMe, 0, 0, this);
479 og.setColor(Color.red);
480 og.drawRect(boxX, boxY, boxWidth, boxHeight);
481 og.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
482 g.drawImage(offscreen, 0, 0, this);