public void highlightSearchResults(SearchResultsI results)
{
updateViewport();
+
+ /*
+ * for now, don't attempt fastpaint if wrapped format
+ */
+ if (av.getWrapAlignment())
+ {
+ av.setSearchResults(results);
+ repaint();
+ return;
+ }
+
fastpainting = true;
fastPaint = true;
+ try
+ {
+ /*
+ * to avoid redrawing the whole visible region, we instead
+ * redraw just the minimal regions to remove previous highlights
+ * and add new ones
+ */
+ SearchResultsI previous = av.getSearchResults();
+ av.setSearchResults(results);
+ boolean redrawn = drawMappedPositions(previous);
+ redrawn |= drawMappedPositions(results);
+ if (redrawn)
+ {
+ repaint();
+ }
+ } finally
+ {
+ fastpainting = false;
+ }
+ }
+
+ /**
+ * Redraws the minimal rectangle in the visible region (if any) that includes
+ * mapped positions of the given search results. Whether or not positions are
+ * highlighted depends on the SearchResults set on the Viewport. This allows
+ * this method to be called to either clear or set highlighting. Answers true
+ * if any positions were drawn (in which case a repaint is still required),
+ * else false.
+ *
+ * @param results
+ * @return
+ */
+ protected boolean drawMappedPositions(SearchResultsI results)
+ {
+ if (results == null)
+ {
+ return false;
+ }
+
/*
- * calculate the minimal rectangle to draw that includes
- * both the new and any existing search results
+ * calculate the minimal rectangle to redraw that
+ * includes both new and existing search results
*/
- SearchResultsI previous = av.getSearchResults();
int firstSeq = Integer.MAX_VALUE;
int lastSeq = -1;
int firstCol = Integer.MAX_VALUE;
boolean matchFound = false;
ViewportRanges ranges = av.getRanges();
+ int firstVisibleColumn = ranges.getStartRes();
+ int lastVisibleColumn = ranges.getEndRes();
+ AlignmentI alignment = av.getAlignment();
+ if (av.hasHiddenColumns())
+ {
+ firstVisibleColumn = alignment.getHiddenColumns()
+ .adjustForHiddenColumns(firstVisibleColumn);
+ lastVisibleColumn = alignment.getHiddenColumns()
+ .adjustForHiddenColumns(lastVisibleColumn);
+ }
+
for (int seqNo = ranges.getStartSeq(); seqNo <= ranges
.getEndSeq(); seqNo++)
{
- SequenceI seq = av.getAlignment().getSequenceAt(seqNo);
- if (previous != null)
+ SequenceI seq = alignment.getSequenceAt(seqNo);
+
+ int[] visibleResults = results.getResults(seq, firstVisibleColumn,
+ lastVisibleColumn);
+ if (visibleResults != null)
{
- /*
- * find the bounding rectangle enclosing last search results
- */
- int[] visibleResults = previous.getResults(seq,
- ranges.getStartRes(), ranges.getEndRes());
- if (visibleResults != null)
+ for (int i = 0; i < visibleResults.length - 1; i += 2)
{
- int firstMatchedColumn = visibleResults[0];
- int lastMatchedColumn = visibleResults[visibleResults.length - 1];
- if (firstMatchedColumn <= ranges.getEndRes()
- && lastMatchedColumn >= ranges.getStartRes())
+ int firstMatchedColumn = visibleResults[i];
+ int lastMatchedColumn = visibleResults[i + 1];
+ if (firstMatchedColumn <= lastVisibleColumn
+ && lastMatchedColumn >= firstVisibleColumn)
{
/*
- * a previous search results match in the visible region
+ * found a search results match in the visible region -
* remember the first and last sequence matched, and the first
* and last visible columns in the matched positions
*/
firstSeq = Math.min(firstSeq, seqNo);
lastSeq = Math.max(lastSeq, seqNo);
firstMatchedColumn = Math.max(firstMatchedColumn,
- ranges.getStartRes());
+ firstVisibleColumn);
lastMatchedColumn = Math.min(lastMatchedColumn,
- ranges.getEndRes());
+ lastVisibleColumn);
firstCol = Math.min(firstCol, firstMatchedColumn);
lastCol = Math.max(lastCol, lastMatchedColumn);
}
}
}
-
- /*
- * and repeat for the new search results
- */
- int[] visibleResults = results.getResults(seq, ranges.getStartRes(),
- ranges.getEndRes());
- if (visibleResults != null)
- {
- int firstMatchedColumn = visibleResults[0];
- int lastMatchedColumn = visibleResults[visibleResults.length - 1];
- if (firstMatchedColumn <= ranges.getEndRes()
- && lastMatchedColumn >= ranges.getStartRes())
- {
- matchFound = true;
- firstSeq = Math.min(firstSeq, seqNo);
- lastSeq = Math.max(lastSeq, seqNo);
- firstMatchedColumn = Math.max(firstMatchedColumn,
- ranges.getStartRes());
- lastMatchedColumn = Math.min(lastMatchedColumn,
- ranges.getEndRes());
- firstCol = Math.min(firstCol, firstMatchedColumn);
- lastCol = Math.max(lastCol, lastMatchedColumn);
- }
- }
}
- av.setSearchResults(results);
-
if (matchFound)
{
+ if (av.hasHiddenColumns())
+ {
+ firstCol = alignment.getHiddenColumns()
+ .findColumnPosition(firstCol);
+ lastCol = alignment.getHiddenColumns().findColumnPosition(lastCol);
+ }
int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth();
int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight();
gg.translate(transX, transY);
drawPanel(gg, firstCol, lastCol, firstSeq, lastSeq, 0);
gg.translate(-transX, -transY);
-
- repaint();
}
- fastpainting = false; // todo in finally block?
+ return matchFound;
}
@Override