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();
273 if (av.isShowSequenceFeatures())
275 fr.transferSettings(ap.getFeatureRenderer());
278 if (getSize().width > 0 && getSize().height > 0)
280 width = getSize().width;
281 sequencesHeight = getSize().height - graphHeight;
284 setSize(new Dimension(width, sequencesHeight + graphHeight));
286 int fullsizeWidth = alwidth * av.getCharWidth();
287 int fullsizeHeight = alheight * av.getCharHeight();
289 scalew = (float) width / (float) fullsizeWidth;
290 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
292 miniMe = nullFrame.createImage(width, sequencesHeight + graphHeight);
293 offscreen = nullFrame.createImage(width, sequencesHeight + graphHeight);
295 Graphics mg = miniMe.getGraphics();
296 float sampleCol = (float) alwidth / (float) width;
297 float sampleRow = (float) alheight / (float) sequencesHeight;
299 int lastcol = 0, lastrow = 0;
300 int xstart = 0, ystart = 0;
301 Color color = Color.yellow;
302 int row, col, sameRow = 0, sameCol = 0;
303 jalview.datamodel.SequenceI seq;
304 final boolean hasHiddenRows = av.hasHiddenRows(), hasHiddenCols = av
306 boolean hiddenRow = false;
307 AlignmentI alignment = av.getAlignment();
308 for (row = 0; row <= sequencesHeight; row++)
310 if ((int) (row * sampleRow) == lastrow)
319 seq = alignment.getHiddenSequences().getHiddenSequence(lastrow);
322 int index = alignment.getHiddenSequences()
323 .findIndexWithoutHiddenSeqs(lastrow);
325 seq = alignment.getSequenceAt(index);
334 seq = alignment.getSequenceAt(lastrow);
337 for (col = 0; col < width; col++)
339 if ((int) (col * sampleCol) == lastcol
340 && (int) (row * sampleRow) == lastrow)
346 lastcol = (int) (col * sampleCol);
348 if (seq.getLength() > lastcol)
350 color = sr.getResidueBoxColour(seq, lastcol);
352 if (av.isShowSequenceFeatures())
354 color = fr.findFeatureColour(color, seq, lastcol);
359 color = Color.white; // White
363 || (hasHiddenCols && !av.getColumnSelection().isVisible(
366 color = color.darker().darker();
370 if (sameCol == 1 && sameRow == 1)
372 mg.drawLine(xstart, ystart, xstart, ystart);
376 mg.fillRect(xstart, ystart, sameCol, sameRow);
382 lastrow = (int) (row * sampleRow);
387 if (av.getAlignmentConservationAnnotation() != null)
389 renderer.updateFromAlignViewport(av);
390 for (col = 0; col < width; col++)
392 lastcol = (int) (col * sampleCol);
394 mg.translate(col, sequencesHeight);
395 renderer.drawGraph(mg, av.getAlignmentConservationAnnotation(),
396 av.getAlignmentConservationAnnotation().annotations,
397 (int) (sampleCol) + 1, graphHeight,
398 (int) (col * sampleCol), (int) (col * sampleCol) + 1);
399 mg.translate(-col, -sequencesHeight);
412 updateOverviewImage();
416 public void setBoxPosition()
418 int fullsizeWidth = av.getAlignment().getWidth() * av.getCharWidth();
419 int fullsizeHeight = (av.getAlignment().getHeight() + av.getAlignment()
420 .getHiddenSequences().getSize())
421 * av.getCharHeight();
423 int startRes = av.getStartRes();
424 int endRes = av.getEndRes();
426 if (av.hasHiddenColumns())
428 startRes = av.getColumnSelection().adjustForHiddenColumns(startRes);
429 endRes = av.getColumnSelection().adjustForHiddenColumns(endRes);
432 int startSeq = av.startSeq;
433 int endSeq = av.endSeq;
435 if (av.hasHiddenRows())
437 startSeq = av.getAlignment().getHiddenSequences()
438 .adjustForHiddenSeqs(startSeq);
440 endSeq = av.getAlignment().getHiddenSequences()
441 .adjustForHiddenSeqs(endSeq);
445 scalew = (float) width / (float) fullsizeWidth;
446 scaleh = (float) sequencesHeight / (float) fullsizeHeight;
448 boxX = (int) (startRes * av.getCharWidth() * scalew);
449 boxY = (int) (startSeq * av.getCharHeight() * scaleh);
451 if (av.hasHiddenColumns())
453 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
457 boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew);
460 boxHeight = (int) ((endSeq - startSeq) * av.getCharHeight() * scaleh);
466 public void update(Graphics g)
472 public void paint(Graphics g)
474 Graphics og = offscreen.getGraphics();
477 og.drawImage(miniMe, 0, 0, this);
478 og.setColor(Color.red);
479 og.drawRect(boxX, boxY, boxWidth, boxHeight);
480 og.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
481 g.drawImage(offscreen, 0, 0, this);