From 875193c17720b95fa13a38703b1dd63949e12ca9 Mon Sep 17 00:00:00 2001 From: kiramt Date: Mon, 13 Nov 2017 15:53:12 +0000 Subject: [PATCH] JAL-2811 Add layer for cursor in SeqCanvas --- src/jalview/gui/SeqCanvas.java | 74 ++++++++++++++++++++++++++++++--- src/jalview/gui/SequenceRenderer.java | 25 +++++++---- 2 files changed, 86 insertions(+), 13 deletions(-) diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index 2a9c704..bd2862a 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -364,11 +364,14 @@ public class SeqCanvas extends JComponent implements ViewportListenerI ranges.getStartRes(), ranges.getEndRes(), ranges.getStartSeq(), ranges.getEndSeq()); + BufferedImage cursorImage = drawCursor(ranges.getStartRes(), + ranges.getEndRes(), ranges.getStartSeq(), ranges.getEndSeq()); + if ((img != null) && (fastPaint || (getVisibleRect().width != g.getClipBounds().width) || (getVisibleRect().height != g.getClipBounds().height))) { - BufferedImage lcimg = buildLocalImage(selectImage); + BufferedImage lcimg = buildLocalImage(selectImage, cursorImage); g.drawImage(lcimg, 0, 0, this); fastPaint = false; } @@ -408,7 +411,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI } // lcimg is a local *copy* of img which we'll draw selectImage on top of - BufferedImage lcimg = buildLocalImage(selectImage); + BufferedImage lcimg = buildLocalImage(selectImage, cursorImage); g.drawImage(lcimg, 0, 0, this); } } @@ -493,7 +496,8 @@ public class SeqCanvas extends JComponent implements ViewportListenerI * Make a local image by combining the cached image img * with any selection */ - private BufferedImage buildLocalImage(BufferedImage selectImage) + private BufferedImage buildLocalImage(BufferedImage selectImage, + BufferedImage cursorImage) { // clone the cached image BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(), @@ -508,6 +512,12 @@ public class SeqCanvas extends JComponent implements ViewportListenerI AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); g2d.drawImage(selectImage, 0, 0, this); } + // overlay cursor on lcimg + if (cursorImage != null) + { + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); + g2d.drawImage(cursorImage, 0, 0, this); + } g2d.dispose(); return lcimg; @@ -1142,12 +1152,12 @@ public class SeqCanvas extends JComponent implements ViewportListenerI } } - if (av.cursorMode && cursorY == i && cursorX >= startRes + /* if (av.cursorMode && cursorY == i && cursorX >= startRes && cursorX <= endRes) { seqRdr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * charWidth, offset + ((i - startSeq) * charHeight)); - } + }*/ } if (av.getSelectionGroup() != null @@ -1245,6 +1255,60 @@ public class SeqCanvas extends JComponent implements ViewportListenerI return selectionImage; } + /** + * Draw the cursor as a separate image and overlay + * + * @param startRes + * start residue of area to draw cursor in + * @param endRes + * end residue of area to draw cursor in + * @param startSeq + * start sequence of area to draw cursor in + * @param endSeq + * end sequence of are to draw cursor in + * @return a transparent image of the same size as the sequence canvas, with + * the cursor drawn on it, if any + */ + private BufferedImage drawCursor(int startRes, int endRes, int startSeq, + int endSeq) + { + // define our cursor image + BufferedImage cursorImage = null; + + if (av.cursorMode && cursorY >= startSeq && cursorY <= endSeq + && cursorX >= startRes && cursorX <= endRes) + { + // get a new image of the correct size + cursorImage = setupImage(); + Graphics2D g = (Graphics2D) cursorImage.getGraphics(); + + // get the character the cursor is drawn at + SequenceI seq = av.getAlignment().getSequenceAt(cursorY); + char s = seq.getCharAt(cursorX); + + int offset = 0; + if (av.getWrapAlignment()) + { + // work out the correct offset for the cursor + offset = wrappedSpaceAboveAlignment; + int currentWidth = 0; + while ((currentWidth < wrappedVisibleWidths) + && (currentWidth < cursorX)) + { + offset += wrappedRepeatHeightPx; + currentWidth++; + } + } + + seqRdr.drawCursor(g, s, + (cursorX - startRes) * av.getCharWidth(), + offset + ((cursorY - startSeq) * av.getCharHeight())); + g.dispose(); + } + + return cursorImage; + } + /* * Set up graphics for selection group */ diff --git a/src/jalview/gui/SequenceRenderer.java b/src/jalview/gui/SequenceRenderer.java index 0a1e8ef..81b394b 100755 --- a/src/jalview/gui/SequenceRenderer.java +++ b/src/jalview/gui/SequenceRenderer.java @@ -481,21 +481,30 @@ public class SequenceRenderer implements jalview.api.SequenceRenderer } } - public void drawCursor(SequenceI seq, int res, int x1, int y1) + /** + * Draw a sequence canvas cursor + * + * @param g + * graphics context to draw on + * @param s + * character to draw at cursor + * @param x1 + * x position of cursor in graphics context + * @param y1 + * y position of cursor in graphics context + */ + public void drawCursor(Graphics g, char s, int x1, int y1) { int pady = av.getCharHeight() / 5; int charOffset = 0; - graphics.setColor(Color.black); - graphics.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight()); + g.setColor(Color.black); + g.fillRect(x1, y1, av.getCharWidth(), av.getCharHeight()); if (av.isValidCharWidth()) { - graphics.setColor(Color.white); - - char s = seq.getCharAt(res); - + g.setColor(Color.white); charOffset = (av.getCharWidth() - fm.charWidth(s)) / 2; - graphics.drawString(String.valueOf(s), charOffset + x1, + g.drawString(String.valueOf(s), charOffset + x1, (y1 + av.getCharHeight()) - pady); } -- 1.7.10.2