{
final FeatureRenderer fr;
- final SequenceRenderer sr;
+ final SequenceRenderer seqRdr;
BufferedImage img;
int cursorY = 0;
+ int charHeight = 0;
+
+ int charWidth = 0;
+
+ boolean fastpainting = false;
+
/**
* Creates a new SeqCanvas object.
*
this.av = ap.av;
updateViewport();
fr = new FeatureRenderer(ap);
- sr = new SequenceRenderer(av);
+ seqRdr = new SequenceRenderer(av);
setLayout(new BorderLayout());
PaintRefresher.Register(this, av.getSequenceSetId());
setBackground(Color.white);
public SequenceRenderer getSequenceRenderer()
{
- return sr;
+ return seqRdr;
}
public FeatureRenderer getFeatureRenderer()
return fr;
}
- int charHeight = 0, charWidth = 0;
-
private void updateViewport()
{
charHeight = av.getCharHeight();
}
}
- boolean fastpainting = false;
/**
* need to make this thread safe move alignment rendering in response to
updateViewport();
- // img is a cached version of the last view we drew
- // selectImage will hold any selection we have
- // lcimg is a local *copy* of img which we'll draw selectImage on top of
-
ViewportRanges ranges = av.getRanges();
+
+ int width = getWidth();
+ int height = getHeight();
+
+ width -= (width % charWidth);
+ height -= (height % charHeight);
+
+ // selectImage is the selection group outline image
BufferedImage selectImage = drawSelectionGroup(
- av.getRanges().getStartRes(), av.getRanges().getEndRes(),
+ ranges.getStartRes(), ranges.getEndRes(),
ranges.getStartSeq(), ranges.getEndSeq());
if (fastPaint || (getVisibleRect().width != g.getClipBounds().width)
{
BufferedImage lcimg = buildLocalImage(selectImage);
g.drawImage(lcimg, 0, 0, this);
-
fastPaint = false;
- return;
}
+ else if ((width > 0) && (height > 0))
+ {
+ // img is a cached version of the last view we drew, if any
+ // if we have no img or the size has changed, make a new one
+ if (img == null || width != img.getWidth()
+ || height != img.getHeight())
+ {
+ img = setupImage();
+ if (img == null)
+ {
+ return;
+ }
+ gg = (Graphics2D) img.getGraphics();
+ gg.setFont(av.getFont());
+ }
- int width = getWidth();
- int height = getHeight();
+ if (av.antiAlias)
+ {
+ gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ }
- width -= (width % charWidth);
- height -= (height % charHeight);
+ gg.setColor(Color.white);
+ gg.fillRect(0, 0, img.getWidth(), img.getHeight());
- if ((width < 1) || (height < 1))
- {
- return;
- }
-
- if (img == null || width != img.getWidth() || height != img.getHeight())
- {
- img = setupImage();
- gg = (Graphics2D) img.getGraphics();
- gg.setFont(av.getFont());
- }
- if (img == null)
- {
- return;
- }
+ if (av.getWrapAlignment())
+ {
+ drawWrappedPanel(gg, getWidth(), getHeight(), ranges.getStartRes());
+ }
+ else
+ {
+ drawPanel(gg, ranges.getStartRes(), ranges.getEndRes(),
+ ranges.getStartSeq(), ranges.getEndSeq(), 0);
+ }
-
- if (av.antiAlias)
- {
- gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
- }
-
- gg.setColor(Color.white);
- gg.fillRect(0, 0, img.getWidth(), img.getHeight());
-
- if (av.getWrapAlignment())
- {
- drawWrappedPanel(gg, getWidth(), getHeight(), ranges.getStartRes());
- }
- else
- {
- drawPanel(gg, ranges.getStartRes(), ranges.getEndRes(),
- ranges.getStartSeq(), ranges.getEndSeq(), 0);
+ // lcimg is a local *copy* of img which we'll draw selectImage on top of
+ BufferedImage lcimg = buildLocalImage(selectImage);
+ g.drawImage(lcimg, 0, 0, this);
}
-
- BufferedImage lcimg = buildLocalImage(selectImage);
- g.drawImage(lcimg, 0, 0, this);
}
/*
}
}
- public void drawWrappedSelection(Graphics2D g, SequenceGroup group,
+ /*
+ * Draw a selection group over a wrapped alignment
+ */
+ private void drawWrappedSelection(Graphics2D g, SequenceGroup group,
int canvasWidth,
int canvasHeight, int startRes)
{
+ // height gap above each panel
int hgap = charHeight;
if (av.getScaleAboveWrapped())
{
int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / charWidth;
int cHeight = av.getAlignment().getHeight() * charHeight;
+ int startx = startRes;
int endx;
- int ypos = hgap;
+ int ypos = hgap; // vertical offset
int maxwidth = av.getAlignment().getWidth();
if (av.hasHiddenColumns())
.findColumnPosition(maxwidth);
}
- while ((ypos <= canvasHeight) && (startRes < maxwidth))
+ // chop the wrapped alignment extent up into panel-sized blocks and treat
+ // each block as if it were a block from an unwrapped alignment
+ while ((ypos <= canvasHeight) && (startx < maxwidth))
{
- endx = startRes + cWidth - 1;
+ // set end value to be start + width, or maxwidth, whichever is smaller
+ endx = startx + cWidth - 1;
if (endx > maxwidth)
{
g.translate(LABEL_WEST, 0);
- drawUnwrappedSelection(g, group, startRes, endx, 0,
+ drawUnwrappedSelection(g, group, startx, endx, 0,
av.getAlignment().getHeight() - 1,
ypos);
g.translate(-LABEL_WEST, 0);
+ // update vertical offset
ypos += cHeight + getAnnotationHeight() + hgap;
- startRes += cWidth;
+ // update horizontal offset
+ startx += cWidth;
}
}
int endSeq, int offset)
{
g.setFont(av.getFont());
- sr.prepare(g, av.isRenderGaps());
+ seqRdr.prepare(g, av.isRenderGaps());
SequenceI nextSeq;
// empty
continue;
}
- sr.drawSequence(nextSeq, av.getAlignment().findAllGroups(nextSeq),
+ seqRdr.drawSequence(nextSeq, av.getAlignment().findAllGroups(nextSeq),
startRes, endRes, offset + ((i - startSeq) * charHeight));
if (av.isShowSequenceFeatures())
{
for (int r = 0; r < visibleResults.length; r += 2)
{
- sr.drawHighlightedText(nextSeq, visibleResults[r],
+ seqRdr.drawHighlightedText(nextSeq, visibleResults[r],
visibleResults[r + 1], (visibleResults[r] - startRes)
* charWidth, offset
+ ((i - startSeq) * charHeight));
if (av.cursorMode && cursorY == i && cursorX >= startRes
&& cursorX <= endRes)
{
- sr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * charWidth,
+ seqRdr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * charWidth,
offset + ((i - startSeq) * charHeight));
}
}
// set up drawing colour
Graphics2D g = (Graphics2D) selectionImage.getGraphics();
- // g.translate(LABEL_WEST, 0);
+
// set background to transparent
g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
g.fillRect(0, 0, selectionImage.getWidth(), selectionImage.getHeight());
+ // set up foreground to draw red dashed line
g.setComposite(AlphaComposite.Src);
g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 3f, new float[]
return selectionImage;
}
+ /*
+ * Draw a selection group over an unwrapped alignment
+ * @param g graphics object to draw with
+ * @param group selection group
+ * @param startRes start residue of area to draw
+ * @param endRes end residue of area to draw
+ * @param startSeq start sequence of area to draw
+ * @param endSeq end sequence of area to draw
+ * @param offset vertical offset (used when called from wrapped alignment code)
+ */
private void drawUnwrappedSelection(Graphics2D g, SequenceGroup group,
int startRes, int endRes, int startSeq, int endSeq, int offset)
{