import jalview.structure.StructureSelectionManager;
import jalview.util.Comparison;
import jalview.util.MessageManager;
-import jalview.util.Platform;
import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
-import java.awt.Insets;
+import java.awt.Graphics2D;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentAdapter;
}
/**
- * Highlight the given results on the alignment.
+ * Highlight the given results on the alignment
*
*/
public void highlightSearchResults(SearchResultsI results)
{
- boolean scrolled = scrollToPosition(results, 0, true, false);
+ boolean scrolled = scrollToPosition(results, 0, false);
boolean noFastPaint = scrolled && av.getWrapAlignment();
* (if any)
*
* @param searchResults
- * @param redrawOverview
* @return
*/
- public boolean scrollToPosition(SearchResultsI searchResults,
- boolean redrawOverview)
+ public boolean scrollToPosition(SearchResultsI searchResults)
{
- return scrollToPosition(searchResults, 0, redrawOverview, false);
+ return scrollToPosition(searchResults, 0, false);
}
/**
* @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
*/
protected boolean scrollToPosition(SearchResultsI results,
- int verticalOffset, boolean redrawOverview, boolean centre)
+ int verticalOffset, boolean centre)
{
int startv, endv, starts, ends;
ViewportRanges ranges = av.getRanges();
if (av.hasHiddenColumns())
{
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- start = hidden.findColumnPosition(start);
- end = hidden.findColumnPosition(end);
+ start = hidden.absoluteToVisibleColumn(start);
+ end = hidden.absoluteToVisibleColumn(end);
if (start == end)
{
if (!hidden.isVisible(r[0]))
scrollNeeded = ranges.scrollToWrappedVisible(start);
}
- paintAlignment(redrawOverview, false);
+ paintAlignment(false, false);
return scrollNeeded;
}
addNotify();
// TODO: many places call this method and also paintAlignment with various
// different settings. this means multiple redraws are triggered...
- paintAlignment(true, false);
+ paintAlignment(true, av.needToUpdateStructureViews());
}
/**
protected void validateAnnotationDimensions(boolean adjustPanelHeight)
{
int annotationHeight = getAnnotationPanel().adjustPanelHeight();
+ annotationHeight = getAnnotationPanel()
+ .adjustForAlignFrame(adjustPanelHeight, annotationHeight);
- if (adjustPanelHeight)
- {
- 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)
- {
- annotationHeight = Math.min(annotationHeight,
- availableHeight - 2 * rowHeight);
- }
- }
- else
- {
- // maintain same window layout whilst updating sliders
- annotationHeight = annotationScroller.getSize().height;
- }
hscroll.addNotify();
-
annotationScroller.setPreferredSize(
new Dimension(annotationScroller.getWidth(), annotationHeight));
{
annotationScroller.setVisible(true);
annotationSpaceFillerHolder.setVisible(true);
+ validateAnnotationDimensions(false);
}
int canvasWidth = getSeqPanel().seqCanvas.getWidth();
}
else
{
- int width = av.getAlignment().getWidth();
+ int width = av.getAlignment().getVisibleWidth();
int height = av.getAlignment().getHeight();
- if (av.hasHiddenColumns())
- {
- // reset the width to exclude hidden columns
- width = av.getAlignment().getHiddenColumns()
- .findColumnPosition(width);
- }
-
hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
public void paintAlignment(boolean updateOverview,
boolean updateStructures)
{
- final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
- av.isShowAutocalculatedAbove());
- sorter.sort(getAlignment().getAlignmentAnnotation(),
- av.getSortAnnotationsBy());
repaint();
if (updateStructures)
}
/**
+ * Sorts annotations according to currently selected preference
+ */
+ void sortAnnotations()
+ {
+ final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
+ av.isShowAutocalculatedAbove());
+ sorter.sort(getAlignment().getAlignmentAnnotation(),
+ av.getSortAnnotationsBy());
+ }
+
+ /**
* DOCUMENT ME!
*
* @param g
@Override
public void paintComponent(Graphics g)
{
+ invalidate(); // needed so that the id width adjuster works correctly
+
Dimension d = getIdPanel().getIdCanvas().getPreferredSize();
idPanelHolder.setPreferredSize(d);
hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));
+
+ validate(); // needed so that the id width adjuster works correctly
+
+ /*
+ * set scroll bar positions - tried to remove but necessary for split panel to resize correctly
+ * though I still think this call should be elsewhere.
+ */
+ ViewportRanges ranges = av.getRanges();
+ setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
}
/**
}
/**
- * DOCUMENT ME!
- *
- * @param pg
- * DOCUMENT ME!
- * @param pwidth
- * DOCUMENT ME!
- * @param pheight
- * DOCUMENT ME!
- * @param pi
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws PrinterException
- * DOCUMENT ME!
- */
- /**
* Draws the alignment image, including sequence ids, sequences, and
* annotation labels and annotations if shown, on either one or two Graphics
- * context.
+ * contexts.
*
* @param pageWidth
+ * in pixels
* @param pageHeight
- * @param pi
+ * in pixels
+ * @param pageIndex
+ * (0, 1, ...)
* @param idGraphics
* the graphics context for sequence ids and annotation labels
* @param alignmentGraphics
* @return
* @throws PrinterException
*/
- public int printUnwrapped(int pageWidth, int pageHeight, int pi,
+ public int printUnwrapped(int pageWidth, int pageHeight, int pageIndex,
Graphics idGraphics, Graphics alignmentGraphics)
throws PrinterException
{
: idWidth;
FontMetrics fm = getFontMetrics(av.getFont());
- int charHeight = av.getCharHeight();
- int scaleHeight = charHeight + fm.getDescent();
+ final int charHeight = av.getCharHeight();
+ final int scaleHeight = charHeight + fm.getDescent();
idGraphics.setColor(Color.white);
idGraphics.fillRect(0, 0, pageWidth, pageHeight);
/*
* How many sequences and residues can we fit on a printable page?
*/
- int totalRes = (pageWidth - idWidth) / av.getCharWidth();
+ final int totalRes = (pageWidth - idWidth) / av.getCharWidth();
- int totalSeq = (pageHeight - scaleHeight) / charHeight - 1;
+ final int totalSeq = (pageHeight - scaleHeight) / charHeight - 1;
- int alignmentWidth = av.getAlignment().getWidth();
+ final int alignmentWidth = av.getAlignment().getVisibleWidth();
int pagesWide = (alignmentWidth / totalRes) + 1;
- final int startRes = (pi % pagesWide) * totalRes;
- int endRes = (startRes + totalRes) - 1;
+ final int startRes = (pageIndex % pagesWide) * totalRes;
+ final int endRes = Math.min(startRes + totalRes - 1,
+ alignmentWidth - 1);
- if (endRes > (alignmentWidth - 1))
- {
- endRes = alignmentWidth - 1;
- }
-
- final int startSeq = (pi / pagesWide) * totalSeq;
- int endSeq = startSeq + totalSeq;
-
- int alignmentHeight = av.getAlignment().getHeight();
- if (endSeq > alignmentHeight)
- {
- endSeq = alignmentHeight;
- }
+ final int startSeq = (pageIndex / pagesWide) * totalSeq;
+ final int alignmentHeight = av.getAlignment().getHeight();
+ final int endSeq = Math.min(startSeq + totalSeq, alignmentHeight);
int pagesHigh = ((alignmentHeight / totalSeq) + 1) * pageHeight;
pagesHigh /= pageHeight;
- if (pi >= (pagesWide * pagesHigh))
+ if (pageIndex >= (pagesWide * pagesHigh))
{
return Printable.NO_SUCH_PAGE;
}
* then reset to top left (0, 0)
*/
idGraphics.translate(0, scaleHeight);
- idGraphics.setFont(getIdPanel().getIdCanvas().getIdfont());
- Color currentColor = null;
- Color currentTextColor = null;
-
- SequenceI seq;
- for (int i = startSeq; i < endSeq; i++)
- {
- seq = av.getAlignment().getSequenceAt(i);
- if ((av.getSelectionGroup() != null)
- && av.getSelectionGroup().getSequences(null).contains(seq))
- {
- /*
- * gray out ids of sequences in selection group (if any)
- */
- currentColor = Color.gray;
- currentTextColor = Color.black;
- }
- else
- {
- currentColor = av.getSequenceColour(seq);
- currentTextColor = Color.black;
- }
-
- idGraphics.setColor(currentColor);
- idGraphics.fillRect(0, (i - startSeq) * charHeight, idWidth,
- charHeight);
-
- idGraphics.setColor(currentTextColor);
-
- int xPos = 0;
- String displayId = seq.getDisplayId(av.getShowJVSuffix());
- if (av.isRightAlignIds())
- {
- fm = idGraphics.getFontMetrics();
- xPos = idWidth - fm.stringWidth(displayId) - 4;
- }
+ IdCanvas idCanvas = getIdPanel().getIdCanvas();
+ List<SequenceI> selection = av.getSelectionGroup() == null ? null
+ : av.getSelectionGroup().getSequences(null);
+ idCanvas.drawIds((Graphics2D) idGraphics, av, startSeq, endSeq - 1,
+ selection);
- idGraphics.drawString(displayId, xPos,
- (((i - startSeq) * charHeight) + charHeight)
- - (charHeight / 5));
- }
idGraphics.setFont(av.getFont());
idGraphics.translate(0, -scaleHeight);
*/
alignmentGraphics.translate(alignmentGraphicsOffset, scaleHeight);
getSeqPanel().seqCanvas.drawPanelForPrinting(alignmentGraphics, startRes,
- endRes, startSeq, endSeq);
+ endRes, startSeq, endSeq - 1);
alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
if (av.isShowAnnotation() && (endSeq == alignmentHeight))
}
/**
- * DOCUMENT ME!
+ * Prints one page of an alignment in wrapped mode. Returns
+ * Printable.PAGE_EXISTS (0) if a page was drawn, or Printable.NO_SUCH_PAGE if
+ * no page could be drawn (page number out of range).
*
- * @param pg
- * DOCUMENT ME!
- * @param pwidth
- * DOCUMENT ME!
- * @param pheight
- * DOCUMENT ME!
- * @param pi
- * DOCUMENT ME!
+ * @param pageWidth
+ * @param pageHeight
+ * @param pageNumber
+ * (0, 1, ...)
+ * @param g
*
- * @return DOCUMENT ME!
+ * @return
*
* @throws PrinterException
- * DOCUMENT ME!
*/
- public int printWrappedAlignment(int pwidth, int pheight, int pi,
- Graphics pg) throws PrinterException
+ public int printWrappedAlignment(int pageWidth, int pageHeight, int pageNumber,
+ Graphics g) throws PrinterException
{
int annotationHeight = 0;
- AnnotationLabels labels = null;
if (av.isShowAnnotation())
{
annotationHeight = getAnnotationPanel().adjustPanelHeight();
- labels = new AnnotationLabels(av);
}
int hgap = av.getCharHeight();
int idWidth = getVisibleIdWidth(false);
- int maxwidth = av.getAlignment().getWidth();
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
- }
+ int maxwidth = av.getAlignment().getVisibleWidth();
int resWidth = getSeqPanel().seqCanvas
- .getWrappedCanvasWidth(pwidth - idWidth);
+ .getWrappedCanvasWidth(pageWidth - idWidth);
int totalHeight = cHeight * (maxwidth / resWidth + 1);
- pg.setColor(Color.white);
- pg.fillRect(0, 0, pwidth, pheight);
- pg.setFont(av.getFont());
-
- // //////////////
- // Draw the ids
- pg.setColor(Color.black);
-
- pg.translate(0, -pi * pheight);
-
- pg.setClip(0, pi * pheight, pwidth, pheight);
-
- int ypos = hgap;
+ g.setColor(Color.white);
+ g.fillRect(0, 0, pageWidth, pageHeight);
+ g.setFont(av.getFont());
+ g.setColor(Color.black);
- do
- {
- for (int i = 0; i < av.getAlignment().getHeight(); i++)
- {
- pg.setFont(getIdPanel().getIdCanvas().getIdfont());
- SequenceI s = av.getAlignment().getSequenceAt(i);
- String string = s.getDisplayId(av.getShowJVSuffix());
- int xPos = 0;
- if (av.isRightAlignIds())
- {
- FontMetrics fm = pg.getFontMetrics();
- xPos = idWidth - fm.stringWidth(string) - 4;
- }
- pg.drawString(string, xPos,
- ((i * av.getCharHeight()) + ypos + av.getCharHeight())
- - (av.getCharHeight() / 5));
- }
- if (labels != null)
- {
- pg.translate(-3, ypos
- + (av.getAlignment().getHeight() * av.getCharHeight()));
+ /*
+ * method: print the whole wrapped alignment, but with a clip region that
+ * is restricted to the requested page; this supports selective print of
+ * single pages or ranges, (at the cost of some repeated processing in
+ * the 'normal' case, when all pages are printed)
+ */
+ g.translate(0, -pageNumber * pageHeight);
- pg.setFont(av.getFont());
- labels.drawComponent(pg, idWidth);
- pg.translate(+3, -ypos
- - (av.getAlignment().getHeight() * av.getCharHeight()));
- }
+ g.setClip(0, pageNumber * pageHeight, pageWidth, pageHeight);
- ypos += cHeight;
- } while (ypos < totalHeight);
+ /*
+ * draw sequence ids and annotation labels (if shown)
+ */
+ IdCanvas idCanvas = getIdPanel().getIdCanvas();
+ idCanvas.drawIdsWrapped((Graphics2D) g, av, 0, totalHeight);
- pg.translate(idWidth, 0);
+ g.translate(idWidth, 0);
- getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(pg, pwidth - idWidth,
+ getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g, pageWidth - idWidth,
totalHeight, 0);
- if ((pi * pheight) < totalHeight)
+ if ((pageNumber * pageHeight) < totalHeight)
{
return Printable.PAGE_EXISTS;
-
}
else
{
public AlignmentDimension getAlignmentDimension()
{
- int maxwidth = av.getAlignment().getWidth();
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth);
- }
+ int maxwidth = av.getAlignment().getVisibleWidth();
int height = ((av.getAlignment().getHeight() + 1) * av.getCharHeight())
+ getScalePanel().getHeight();
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ .absoluteToVisibleColumn(maxwidth) - 1;
}
int height = ((maxwidth / chunkWidth) + 1) * cHeight;
@Override
public String getViewName()
{
- return av.viewName;
+ return av.getViewName();
}
/**
*/
protected void scrollToCentre(SearchResultsI sr, int verticalOffset)
{
- /*
- * To avoid jumpy vertical scrolling (if some sequences are gapped or not
- * mapped), we can make the scroll-to location a sequence above the one
- * actually mapped.
- */
- SequenceI mappedTo = sr.getResults().get(0).getSequence();
- List<SequenceI> seqs = av.getAlignment().getSequences();
-
- /*
- * This is like AlignmentI.findIndex(seq) but here we are matching the
- * dataset sequence not the aligned sequence
- */
- boolean matched = false;
- for (SequenceI seq : seqs)
- {
- if (mappedTo == seq.getDatasetSequence())
- {
- matched = true;
- break;
- }
- }
- if (!matched)
- {
- return; // failsafe, shouldn't happen
- }
-
- /*
- * Scroll to position but centring the target residue.
- */
- scrollToPosition(sr, verticalOffset, true, true);
+ scrollToPosition(sr, verticalOffset, true);
}
/**