int screenY = 0;
final int screenYMax = endRes - startRes;
int blockStart = startRes;
- int blockEnd = endRes;
+ int blockEnd = endRes; // equals blockStart + screenYMax - screenY;
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
Iterator<int[]> regions = hidden.iterator();
if (hideStart <= blockStart)
{
blockStart += (hideEnd - hideStart) + 1;
+ blockEnd += (hideEnd - hideStart) + 1;
continue;
}
* draw up to just before the next hidden region, or the end of
* the visible region, whichever comes first
*/
- blockEnd = Math.min(hideStart - 1,
- blockStart + screenYMax - screenY);
+ blockEnd = Math.min(blockEnd, hideStart - 1);
g1.translate(screenY * avcharWidth, 0);
draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
g1.translate(-screenY * avcharWidth, 0);
screenY += blockEnd - blockStart + 1;
blockStart = hideEnd + 1;
+ blockEnd = blockStart + screenYMax - screenY;
if (screenY > screenYMax)
{
if (screenY <= screenYMax)
{
// remaining visible region to render
- blockEnd = blockStart + screenYMax - screenY;
g1.translate(screenY * avcharWidth, 0);
draw(g1, blockStart, blockEnd, startSeq, endSeq, offset);
-
g1.translate(-screenY * avcharWidth, 0);
}
}
}
/**
+ * return an iterator over visible segments between the given start and end
+ * boundaries
+ *
+ * @param start
+ * (first column - inclusive from 0)
+ * @param end
+ * (last column - inclusive)
+ * @param useVisibleCoords
+ * if true, start and end are visible column positions, not absolute
+ * positions
+ */
+ public Iterator<int[]> getVisibleBlocksIterator(int start, int end,
+ boolean useVisibleCoords)
+ {
+ if (useVisibleCoords)
+ {
+ // TODO
+ // we should really just convert start and end here with
+ // adjustForHiddenColumns
+ // and then create a VisibleBlocksIterator
+ // but without a cursor this will be horribly slow in some situations
+ // ... so until then...
+ return new VisibleBlocksVisBoundsIterator(start, end, true);
+ }
+ else
+ {
+ return new VisibleBlocksIterator(start, end, true);
+ }
+ }
+
+ /**
* An iterator which iterates over hidden column regions in a range.
*/
private class BoundedHiddenColsIterator implements Iterator<int[]>
}
}
+ /**
+ * An iterator which iterates over visible regions in a range as visible
+ * column positions.
+ */
+ public class VisibleBlocksVisBoundsIterator implements Iterator<int[]>
+ {
+ private List<int[]> vcontigs = new ArrayList<>();
+
+ private int currentPosition = 0;
+
+ private boolean endsAtHidden = true;
+
+ VisibleBlocksVisBoundsIterator(int start, int end, boolean usecopy)
+ {
+ try
+ {
+ if (usecopy)
+ {
+ LOCK.readLock().lock();
+ }
+
+ if (hiddenColumns != null && hiddenColumns.size() > 0)
+ {
+ int blockStart = start;
+ int blockEnd = end;
+ int hiddenSoFar = 0;
+ int visSoFar = 0;
+ int maxVisible = end - start;
+
+ // iterate until a region begins within (start,end]
+ int i = 0;
+ while ((i < hiddenColumns.size())
+ && (hiddenColumns.get(i)[0] <= blockStart + hiddenSoFar))
+ {
+ hiddenSoFar += hiddenColumns.get(i)[1] - hiddenColumns.get(i)[0]
+ + 1;
+ i++;
+ }
+
+ blockStart += hiddenSoFar; // convert start to absolute position
+ blockEnd += hiddenSoFar; // convert end too in
+
+ // iterate from start to end, adding each hidden region. Positions are
+ // absolute, and all regions which *overlap* [start,end] are used.
+ while (i < hiddenColumns.size()
+ && (hiddenColumns.get(i)[0] <= blockEnd))
+ {
+ int[] region = hiddenColumns.get(i);
+
+ blockEnd = Math.min(blockEnd, region[0] - 1);
+
+ int[] contig = new int[] { blockStart, blockEnd };
+ vcontigs.add(contig);
+
+ visSoFar += blockEnd - blockStart + 1;
+ blockStart = region[1] + 1;
+ blockEnd = end + hiddenSoFar;
+ hiddenSoFar += region[1] - region[0] + 1;
+
+ i++;
+ }
+ if (visSoFar < maxVisible)
+ {
+ blockEnd = blockStart + maxVisible - visSoFar;
+ int[] contig = new int[] { blockStart,
+ blockEnd };
+ vcontigs.add(contig);
+
+ endsAtHidden = false;
+ }
+ }
+ else
+ {
+ int[] contig = new int[] { start, end };
+ vcontigs.add(contig);
+ endsAtHidden = false;
+ }
+ } finally
+ {
+ if (usecopy)
+ {
+ LOCK.readLock().unlock();
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return (currentPosition < vcontigs.size());
+ }
+
+ @Override
+ public int[] next()
+ {
+ int[] result = vcontigs.get(currentPosition);
+ currentPosition++;
+ return result;
+ }
+
+ public boolean endsAtHidden()
+ {
+ return endsAtHidden;
+ }
+ }
+
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.HiddenColumns.VisibleBlocksVisBoundsIterator;
import jalview.datamodel.SearchResultsI;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
int screenY = 0;
final int screenYMax = endRes - startRes;
int blockStart = startRes;
- int blockEnd = endRes;
+ int blockEnd = endRes; // equals blockStart + screenYMax - screenY;
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- Iterator<int[]> regions = hidden.iterator();
+ VisibleBlocksVisBoundsIterator regions = (VisibleBlocksVisBoundsIterator) hidden
+ .getVisibleBlocksIterator(startRes, endRes, true);// hidden.iterator();
while (regions.hasNext())
{
int[] region = regions.next();
- int hideStart = region[0];
+ blockEnd = region[1];
+ blockStart = region[0];
+/* int hideStart = region[0];
int hideEnd = region[1];
if (hideStart <= blockStart)
{
- blockStart += (hideEnd - hideStart) + 1;
+ blockStart += (hideEnd - hideStart) + 1; // convert startRes to an
+ // absolute value
+ blockEnd += (hideEnd - hideStart) + 1;
continue;
}
-
+*/
/*
* draw up to just before the next hidden region, or the end of
* the visible region, whichever comes first
*/
- blockEnd = Math.min(hideStart - 1,
- blockStart + screenYMax - screenY);
+// blockEnd = Math.min(hideStart - 1,
+// blockEnd);
g1.translate(screenY * charWidth, 0);
draw(g1, blockStart, blockEnd, startSeq, endSeq, yOffset);
* draw the downline of the hidden column marker (ScalePanel draws the
* triangle on top) if we reached it
*/
- if (av.getShowHiddenMarkers() && blockEnd == hideStart - 1)
+ if (av.getShowHiddenMarkers()
+ && (regions.hasNext() || regions.endsAtHidden()))// blockEnd ==
+ // hideStart - 1)
{
g1.setColor(Color.blue);
g1.translate(-screenY * charWidth, 0);
screenY += blockEnd - blockStart + 1;
- blockStart = hideEnd + 1;
-
+ /* blockStart = hideEnd + 1;
+ blockEnd = blockStart + screenYMax - screenY;
+
if (screenY > screenYMax)
{
// already rendered last block
return;
- }
+ }*/
}
- if (screenY <= screenYMax)
+ /* if (screenY <= screenYMax)
{
// remaining visible region to render
blockEnd = blockStart + screenYMax - screenY;
g1.translate(screenY * charWidth, 0);
draw(g1, blockStart, blockEnd, startSeq, endSeq, yOffset);
-
+
g1.translate(-screenY * charWidth, 0);
- }
+ }*/
}
}