X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAlignmentPanel.java;h=4c662147d4304f42463603aa95332cf0aa1fa0fb;hb=8edebdd9789b2d93fb8f9db24b8be2c1e6317690;hp=be8e592c5aaa7d26cc6da3da71a139da2403e603;hpb=b13f521553582ef2fbfd7815ae25e23284babdea;p=jalview.git
diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java
index be8e592..4c66214 100644
--- a/src/jalview/gui/AlignmentPanel.java
+++ b/src/jalview/gui/AlignmentPanel.java
@@ -1,6 +1,6 @@
/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
*
* This file is part of Jalview.
*
@@ -21,6 +21,7 @@
package jalview.gui;
import jalview.analysis.AnnotationSorter;
+import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.bin.Cache;
import jalview.datamodel.AlignmentI;
@@ -28,11 +29,14 @@ import jalview.datamodel.SearchResults;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.io.HTMLOutput;
import jalview.jbgui.GAlignmentPanel;
import jalview.math.AlignmentDimension;
import jalview.schemes.ResidueProperties;
import jalview.structure.StructureSelectionManager;
+import jalview.util.ImageMaker;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.BorderLayout;
import java.awt.Color;
@@ -41,6 +45,7 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
+import java.awt.Insets;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.print.PageFormat;
@@ -51,6 +56,7 @@ import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
+import java.util.List;
import javax.swing.SwingUtilities;
@@ -90,13 +96,17 @@ public class AlignmentPanel extends GAlignmentPanel implements
int vextent = 0;
+ /*
+ * Flag set while scrolling to follow complementary cDNA/protein scroll. When
+ * true, suppresses invoking the same method recursively.
+ */
+ private boolean followingComplementScroll;
+
/**
* Creates a new AlignmentPanel object.
*
* @param af
- * DOCUMENT ME!
* @param av
- * DOCUMENT ME!
*/
public AlignmentPanel(AlignFrame af, final AlignViewport av)
{
@@ -122,8 +132,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
setScrollValues(0, 0);
- setAnnotationVisible(av.isShowAnnotation());
-
hscroll.addAdjustmentListener(this);
vscroll.addAdjustmentListener(this);
@@ -141,9 +149,14 @@ public class AlignmentPanel extends GAlignmentPanel implements
});
fontChanged();
adjustAnnotationHeight();
-
+ updateLayout();
}
+ @Override
+ public AlignViewportI getAlignViewport()
+ {
+ return av;
+ }
public void alignmentChanged()
{
av.alignmentChanged(this);
@@ -163,9 +176,10 @@ public class AlignmentPanel extends GAlignmentPanel implements
// to prevent drawing old image
FontMetrics fm = getFontMetrics(av.getFont());
- scalePanelHolder.setPreferredSize(new Dimension(10, av.charHeight
+ scalePanelHolder.setPreferredSize(new Dimension(10, av.getCharHeight()
+ fm.getDescent()));
- idSpaceFillerPanel1.setPreferredSize(new Dimension(10, av.charHeight
+ idSpaceFillerPanel1.setPreferredSize(new Dimension(10, av
+ .getCharHeight()
+ fm.getDescent()));
getIdPanel().getIdCanvas().gg = null;
@@ -173,6 +187,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
getAnnotationPanel().adjustPanelHeight();
Dimension d = calculateIdWidth();
+
d.setSize(d.width + 4, d.height);
getIdPanel().getIdCanvas().setPreferredSize(d);
hscrollFillerPanel.setPreferredSize(d);
@@ -181,6 +196,10 @@ public class AlignmentPanel extends GAlignmentPanel implements
{
overviewPanel.setBoxPosition();
}
+ if (this.alignFrame.getSplitViewContainer() != null)
+ {
+ ((SplitFrame) this.alignFrame.getSplitViewContainer()).adjustLayout();
+ }
repaint();
}
@@ -195,11 +214,21 @@ public class AlignmentPanel extends GAlignmentPanel implements
public Dimension calculateIdWidth()
{
// calculate sensible default width when no preference is available
-
- int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
- int maxwidth = Math.max(20,
- Math.min(afwidth - 200, 2 * afwidth / 3));
- return calculateIdWidth(maxwidth);
+ Dimension r = null;
+ if (av.getIdWidth() < 0)
+ {
+ int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
+ int maxwidth = Math.max(20, Math.min(afwidth - 200, 2 * afwidth / 3));
+ r = calculateIdWidth(maxwidth);
+ av.setIdWidth(r.width);
+ }
+ else
+ {
+ r = new Dimension();
+ r.width = av.getIdWidth();
+ r.height = 0;
+ }
+ return r;
}
/**
@@ -272,33 +301,52 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
/**
- * scroll the view to show the position of the highlighted region in results
+ * Scroll the view to show the position of the highlighted region in results
* (if any) and redraw the overview
*
* @param results
*/
public boolean scrollToPosition(SearchResults results)
{
- return scrollToPosition(results, true);
+ return scrollToPosition(results, 0, true, false);
}
/**
- * scroll the view to show the position of the highlighted region in results
+ * Scroll the view to show the position of the highlighted region in results
+ * (if any)
+ *
+ * @param searchResults
+ * @param redrawOverview
+ * @return
+ */
+ public boolean scrollToPosition(SearchResults searchResults, boolean redrawOverview)
+ {
+ return scrollToPosition(searchResults, 0, redrawOverview, false);
+ }
+
+ /**
+ * Scroll the view to show the position of the highlighted region in results
* (if any)
*
* @param results
+ * @param verticalOffset
+ * if greater than zero, allows scrolling to a position below the
+ * first displayed sequence
* @param redrawOverview
* - when set, the overview will be recalculated (takes longer)
+ * @param centre
+ * if true, try to centre the search results horizontally in the view
* @return false if results were not found
*/
public boolean scrollToPosition(SearchResults results,
- boolean redrawOverview)
+ int verticalOffset,
+ boolean redrawOverview, boolean centre)
{
- int startv, endv, starts, ends, width;
+ int startv, endv, starts, ends;
// TODO: properly locate search results in view when large numbers of hidden
// columns exist before highlighted region
// do we need to scroll the panel?
- // TODO: tons of nullpointereexceptions raised here.
+ // TODO: tons of nullpointerexceptions raised here.
if (results != null && results.getSize() > 0 && av != null
&& av.getAlignment() != null)
{
@@ -318,6 +366,17 @@ public class AlignmentPanel extends GAlignmentPanel implements
int end = r[1];
// System.err.println("Seq : "+seqIndex+" Scroll to "+start+","+end); //
// DEBUG
+
+ /*
+ * To centre results, scroll to positions half the visible width
+ * left/right of the start/end positions
+ */
+ if (centre)
+ {
+ int offset = (av.getEndRes() - av.getStartRes() + 1) / 2 - 1;
+ start = Math.max(start - offset, 0);
+ end = Math.min(end + offset, seq.getEnd() - 1);
+ }
if (start < 0)
{
return false;
@@ -339,24 +398,47 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
}
}
- if (!av.wrapAlignment)
+
+ /*
+ * allow for offset of target sequence (actually scroll to one above it)
+ */
+ seqIndex = Math.max(0, seqIndex - verticalOffset);
+
+ if (!av.getWrapAlignment())
{
if ((startv = av.getStartRes()) >= start)
{
- setScrollValues(start - 1, seqIndex);
+ /*
+ * Scroll left to make start of search results visible
+ */
+ // setScrollValues(start - 1, seqIndex); // plus one residue
+ setScrollValues(start, seqIndex);
}
else if ((endv = av.getEndRes()) <= end)
{
- setScrollValues(startv + 1 + end - endv, seqIndex);
+ /*
+ * Scroll right to make end of search results visible
+ */
+ // setScrollValues(startv + 1 + end - endv, seqIndex); // plus one
+ setScrollValues(startv + end - endv, seqIndex);
}
else if ((starts = av.getStartSeq()) > seqIndex)
{
+ /*
+ * Scroll up to make start of search results visible
+ */
setScrollValues(av.getStartRes(), seqIndex);
}
else if ((ends = av.getEndSeq()) <= seqIndex)
{
+ /*
+ * Scroll down to make end of search results visible
+ */
setScrollValues(av.getStartRes(), starts + seqIndex - ends + 1);
}
+ /*
+ * Else results are already visible - no need to scroll
+ */
}
else
{
@@ -412,7 +494,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
public void setAnnotationVisible(boolean b)
{
- if (!av.wrapAlignment)
+ if (!av.getWrapAlignment())
{
annotationSpaceFillerHolder.setVisible(b);
annotationScroller.setVisible(b);
@@ -443,58 +525,61 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
protected void validateAnnotationDimensions(boolean adjustPanelHeight)
{
- int height = getAnnotationPanel().adjustPanelHeight();
-
- int theight = av.getCharHeight()
- * (av.getAlignment().getHeight() + (!av.hasHiddenRows() ? 0
- : av.getAlignment().getHiddenSequences().getSize()));
- float sscaling = (float) (theight / (1.0 * theight + height));
- float ascaling = (float) (height * 1.0 / alignFrame.getHeight());
- int rheight = alignFrame.getHeight() - height - av.getCharHeight();
+ int annotationHeight = getAnnotationPanel().adjustPanelHeight();
+
if (adjustPanelHeight)
{
- // NOTE: this logic is different in the applet. Need a better algorithm to
- // define behaviour
- // try and set height according to alignment
- if (ascaling > 0 && sscaling < 0.5)
- {
- // if the alignment is too big then
- // default is 0.5 split
- height = alignFrame.getHeight() / 2;
- }
- else
+ int rowHeight = av.getCharHeight();
+ int alignmentHeight = rowHeight * av.getAlignment().getHeight();
+
+ /*
+ * Estimate available height in the AlignFrame for alignment +
+ * annotations. Deduct an estimate for title bar, menu bar, scale panel,
+ * hscroll, status bar (as these are not laid out we can't inspect their
+ * actual heights). Insets gives frame borders.
+ */
+ int stuff = Platform.isAMac() ? 80 : 100;
+ Insets insets = alignFrame.getInsets();
+ int availableHeight = alignFrame.getHeight() - stuff - insets.top
+ - insets.bottom;
+
+ /*
+ * If not enough vertical space, maximize annotation height while keeping
+ * at least two rows of alignment visible
+ */
+ if (annotationHeight + alignmentHeight > availableHeight)
{
- // if space for more than one sequence row left when annotation is fully
- // displayed then set height to annotation height
- // otherwise, leave at least two lines of sequence shown.
- height = (rheight > av.getCharHeight()) ? height
- : (-av.getCharHeight() * 3 + (int) (alignFrame.getHeight() * (1 - sscaling)));
+ annotationHeight = Math.min(annotationHeight, availableHeight - 2
+ * rowHeight);
}
}
else
{
// maintain same window layout whilst updating sliders
- height = annotationScroller.getSize().height;
+ annotationHeight = annotationScroller.getSize().height;
}
hscroll.addNotify();
annotationScroller.setPreferredSize(new Dimension(annotationScroller
- .getWidth(), height));
+ .getWidth(), annotationHeight));
annotationSpaceFillerHolder.setPreferredSize(new Dimension(
- annotationSpaceFillerHolder.getWidth(), height));
- annotationScroller.validate();// repaint();
+ annotationSpaceFillerHolder.getWidth(), annotationHeight));
+ annotationScroller.validate();
annotationScroller.addNotify();
}
/**
- * DOCUMENT ME!
+ * update alignment layout for viewport settings
*
* @param wrap
* DOCUMENT ME!
*/
- public void setWrapAlignment(boolean wrap)
+ public void updateLayout()
{
+ fontChanged();
+ setAnnotationVisible(av.isShowAnnotation());
+ boolean wrap = av.getWrapAlignment();
av.startSeq = 0;
scalePanelHolder.setVisible(!wrap);
hscroll.setVisible(!wrap);
@@ -605,10 +690,11 @@ public class AlignmentPanel extends GAlignmentPanel implements
width = av.getColumnSelection().findColumnPosition(width);
}
- av.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av.charWidth)) - 1);
+ av.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av
+ .getCharWidth())) - 1);
- hextent = getSeqPanel().seqCanvas.getWidth() / av.charWidth;
- vextent = getSeqPanel().seqCanvas.getHeight() / av.charHeight;
+ hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
+ vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
if (hextent > width)
{
@@ -652,7 +738,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
public void adjustmentValueChanged(AdjustmentEvent evt)
{
-
int oldX = av.getStartRes();
int oldY = av.getStartSeq();
@@ -735,6 +820,18 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
}
}
+ /*
+ * If there is one, scroll the (Protein/cDNA) complementary alignment to
+ * match, unless we are ourselves doing that.
+ */
+ if (isFollowingComplementScroll())
+ {
+ setFollowingComplementScroll(false);
+ }
+ else
+ {
+ av.scrollComplementaryAlignment();
+ }
}
/**
@@ -859,7 +956,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
{
int idWidth = getVisibleIdWidth(false);
FontMetrics fm = getFontMetrics(av.getFont());
- int scaleHeight = av.charHeight + fm.getDescent();
+ int scaleHeight = av.getCharHeight() + fm.getDescent();
pg.setColor(Color.white);
pg.fillRect(0, 0, pwidth, pheight);
@@ -949,7 +1046,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
pg.setColor(currentColor);
- pg.fillRect(0, (i - startSeq) * av.charHeight, idWidth,
+ pg.fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth,
av.getCharHeight());
pg.setColor(currentTextColor);
@@ -966,7 +1063,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
pg.drawString(
seq.getDisplayId(av.getShowJVSuffix()),
xPos,
- (((i - startSeq) * av.charHeight) + av.getCharHeight())
+ (((i - startSeq) * av.getCharHeight()) + av.getCharHeight())
- (av.getCharHeight() / 5));
}
@@ -981,7 +1078,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
// draw annotation - need to offset for current scroll position
int offset = -getAlabels().getScrollOffset();
pg.translate(0, offset);
- pg.translate(-idWidth - 3, (endSeq - startSeq) * av.charHeight + 3);
+ pg.translate(-idWidth - 3, (endSeq - startSeq) * av.getCharHeight()
+ + 3);
getAlabels().drawComponent(pg, idWidth);
pg.translate(idWidth + 3, 0);
getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(), av,
@@ -1012,7 +1110,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
public int printWrappedAlignment(Graphics pg, int pwidth, int pheight,
int pi) throws PrinterException
{
-
int annotationHeight = 0;
AnnotationLabels labels = null;
if (av.isShowAnnotation())
@@ -1021,13 +1118,13 @@ public class AlignmentPanel extends GAlignmentPanel implements
labels = new AnnotationLabels(av);
}
- int hgap = av.charHeight;
- if (av.scaleAboveWrapped)
+ int hgap = av.getCharHeight();
+ if (av.getScaleAboveWrapped())
{
- hgap += av.charHeight;
+ hgap += av.getCharHeight();
}
- int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap
+ int cHeight = av.getAlignment().getHeight() * av.getCharHeight() + hgap
+ annotationHeight;
int idWidth = getVisibleIdWidth(false);
@@ -1071,18 +1168,19 @@ public class AlignmentPanel extends GAlignmentPanel implements
xPos = idWidth - fm.stringWidth(string) - 4;
}
pg.drawString(string, xPos,
- ((i * av.charHeight) + ypos + av.charHeight)
- - (av.charHeight / 5));
+ ((i * av.getCharHeight()) + ypos + av.getCharHeight())
+ - (av.getCharHeight() / 5));
}
if (labels != null)
{
pg.translate(-3, ypos
- + (av.getAlignment().getHeight() * av.charHeight));
+ + (av.getAlignment().getHeight() * av.getCharHeight()));
pg.setFont(av.getFont());
labels.drawComponent(pg, idWidth);
pg.translate(+3, -ypos
- - (av.getAlignment().getHeight() * av.charHeight));
+ - (av.getAlignment().getHeight() * av
+ .getCharHeight()));
}
ypos += cHeight;
@@ -1141,7 +1239,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
return idwidth.intValue() + 4;
}
- void makeAlignmentImage(jalview.util.ImageMaker.TYPE type, File file)
+ void makeAlignmentImage(ImageMaker.TYPE type, File file)
{
long progress = System.currentTimeMillis();
headless = (System.getProperty("java.awt.headless") != null && System
@@ -1149,8 +1247,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
if (alignFrame != null && !headless)
{
alignFrame.setProgressBar(MessageManager.formatMessage(
- "status.saving_file",
- new String[]
+ "status.saving_file", new Object[]
{ type.getLabel() }), progress);
}
try
@@ -1158,14 +1255,14 @@ public class AlignmentPanel extends GAlignmentPanel implements
AlignmentDimension aDimension = getAlignmentDimension();
try
{
- jalview.util.ImageMaker im;
+ ImageMaker im;
final String imageAction, imageTitle;
- if (type == jalview.util.ImageMaker.TYPE.PNG)
+ if (type == ImageMaker.TYPE.PNG)
{
imageAction = "Create PNG image from alignment";
imageTitle = null;
}
- else if (type == jalview.util.ImageMaker.TYPE.EPS)
+ else if (type == ImageMaker.TYPE.EPS)
{
imageAction = "Create EPS file from alignment";
imageTitle = alignFrame.getTitle();
@@ -1176,7 +1273,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
imageTitle = alignFrame.getTitle();
}
- im = new jalview.util.ImageMaker(this, type, imageAction,
+ im = new ImageMaker(this, type, imageAction,
aDimension.getWidth(), aDimension.getHeight(), file,
imageTitle);
if (av.getWrapAlignment())
@@ -1225,9 +1322,9 @@ public class AlignmentPanel extends GAlignmentPanel implements
maxwidth = av.getColumnSelection().findColumnPosition(maxwidth);
}
- int height = ((av.getAlignment().getHeight() + 1) * av.charHeight)
+ int height = ((av.getAlignment().getHeight() + 1) * av.getCharHeight())
+ getScalePanel().getHeight();
- int width = getVisibleIdWidth(false) + (maxwidth * av.charWidth);
+ int width = getVisibleIdWidth(false) + (maxwidth * av.getCharWidth());
if (av.getWrapAlignment())
{
@@ -1262,7 +1359,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
public void makeEPS(File epsFile)
{
- makeAlignmentImage(jalview.util.ImageMaker.TYPE.EPS, epsFile);
+ makeAlignmentImage(ImageMaker.TYPE.EPS, epsFile);
}
/**
@@ -1270,12 +1367,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
public void makePNG(File pngFile)
{
- makeAlignmentImage(jalview.util.ImageMaker.TYPE.PNG, pngFile);
+ makeAlignmentImage(ImageMaker.TYPE.PNG, pngFile);
}
public void makeSVG(File svgFile)
{
- makeAlignmentImage(jalview.util.ImageMaker.TYPE.SVG, svgFile);
+ makeAlignmentImage(ImageMaker.TYPE.SVG, svgFile);
}
public void makePNGImageMap(File imgMapFile, String imageName)
{
@@ -1283,7 +1380,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
// ////////////////////////////////////////////
int idWidth = getVisibleIdWidth(false);
FontMetrics fm = getFontMetrics(av.getFont());
- int scaleHeight = av.charHeight + fm.getDescent();
+ int scaleHeight = av.getCharHeight() + fm.getDescent();
// Gen image map
// ////////////////////////////////
@@ -1295,14 +1392,14 @@ public class AlignmentPanel extends GAlignmentPanel implements
.getAlignment().getWidth(), g, gSize, f, fSize, sy;
StringBuffer text = new StringBuffer();
PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));
- out.println(jalview.io.HTMLOutput.getImageMapHTML());
+ out.println(HTMLOutput.getImageMapHTML());
out.println(""
+ "