X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fjalview%2Fviewmodel%2FOverviewDimensions.java;h=b34c85d352b4bdc5d053f2b116e31ba5c60d5138;hb=7f4da0a2b0c10f158a03dbfce8878e67e90c4a68;hp=17f56c9f9380d4aabb638e874891b926430a16da;hpb=aa6643d51133a8541dcbe30191b344aa09907a5f;p=jalview.git diff --git a/src/jalview/viewmodel/OverviewDimensions.java b/src/jalview/viewmodel/OverviewDimensions.java index 17f56c9..b34c85d 100644 --- a/src/jalview/viewmodel/OverviewDimensions.java +++ b/src/jalview/viewmodel/OverviewDimensions.java @@ -20,7 +20,10 @@ */ package jalview.viewmodel; -import jalview.api.AlignViewportI; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.HiddenSequences; + +import java.awt.Graphics; public class OverviewDimensions { @@ -35,12 +38,6 @@ public class OverviewDimensions private static final int MAX_SEQ_HEIGHT = 300; - private AlignViewportI av; - - private float scalew = 1f; - - private float scaleh = 1f; - // width of the overview panel private int width; @@ -63,30 +60,38 @@ public class OverviewDimensions // height of box private int boxHeight = -1; + // scroll position in viewport corresponding to boxX private int scrollCol = -1; + // scroll position in viewport corresponding to boxY private int scrollRow = -1; - public OverviewDimensions(AlignViewportI avi) + /** + * Create an OverviewDimensions object + * + * @param props + * positional properties of the viewport + * @param showAnnotationPanel + * true if the annotation panel is to be shown, false otherwise + */ + public OverviewDimensions(ViewportPositionProps props, + boolean showAnnotationPanel) { - this.av = avi; - // scale the initial size of overviewpanel to shape of alignment - float initialScale = (float) av.getAlignment().getWidth() - / (float) av.getAlignment().getHeight(); + float initialScale = (float) props.getAbsoluteAlignmentWidth() + / (float) props.getAbsoluteAlignmentHeight(); - // TODO: in applet this was getSequenceConsensusHash() - // check if it makes any functional difference - if (av.getAlignmentConservationAnnotation() == null) + if (!showAnnotationPanel) { graphHeight = 0; } - if (av.getAlignment().getWidth() > av.getAlignment().getHeight()) + if (props.getAbsoluteAlignmentWidth() > props + .getAbsoluteAlignmentHeight()) { // wider width = MAX_WIDTH; - sequencesHeight = (int) (MAX_WIDTH / initialScale); + sequencesHeight = Math.round(MAX_WIDTH / initialScale); if (sequencesHeight < MIN_SEQ_HEIGHT) { sequencesHeight = MIN_SEQ_HEIGHT; @@ -95,7 +100,7 @@ public class OverviewDimensions else { // taller - width = (int) (MAX_WIDTH * initialScale); + width = Math.round(MAX_WIDTH * initialScale); sequencesHeight = MAX_SEQ_HEIGHT; if (width < MIN_WIDTH) @@ -107,118 +112,169 @@ public class OverviewDimensions /** * Check box dimensions and scroll positions and correct if necessary + * + * @param mousex + * x position in overview panel + * @param mousey + * y position in overview panel + * @param hiddenSeqs + * hidden sequences + * @param hiddenCols + * hidden columns + * @param props + * viewport position properties */ - public void checkValid() + public void updateViewportFromMouse(int mousex, int mousey, + HiddenSequences hiddenSeqs, ColumnSelection hiddenCols, + ViewportPositionProps props) { - if (boxY < 0) - { - boxY = 0; - } + int x = mousex; + int y = mousey; - if (boxY > (sequencesHeight - boxHeight)) + int alwidth = props.getAbsoluteAlignmentWidth(); + int alheight = props.getAbsoluteAlignmentHeight(); + + if (x < 0) { - boxY = sequencesHeight - boxHeight + 1; + x = 0; } - if (boxX < 0) + if (y < 0) { - boxX = 0; + y = 0; } - if (boxX > (width - boxWidth)) + // + // Convert x value to residue position + // + + // need to determine where scrollCol should be, given x + // to do this also need to know width of viewport, and some hidden column + // correction + + // convert x to residues - this is an absolute position + int xAsRes = Math.round((float) x * alwidth / width); + + // get viewport width in residues + int vpwidth = props.getEndRes() - props.getStartRes() + 1; + + // get where x should be when accounting for hidden cols + // if x is in a hidden col region, shift to left - but we still need + // absolute position + // so convert back after getting visible region position + int visXAsRes = hiddenCols.findColumnPosition(xAsRes); + + // check in case we went off the edge of the alignment + int visAlignWidth = hiddenCols.findColumnPosition(alwidth - 1); + if (visXAsRes + vpwidth - 1 > visAlignWidth) { - if (av.hasHiddenColumns()) + // went past the end of the alignment, adjust backwards + + // if last position was before the end of the alignment, need to update + if ((scrollCol + vpwidth - 1) < visAlignWidth) { - // Try smallest possible box - boxWidth = (int) ((av.getEndRes() - av.getStartRes() + 1) - * av.getCharWidth() * scalew); + visXAsRes = hiddenCols.findColumnPosition(hiddenCols + .findColumnNToLeft(vpwidth - 1, alwidth - 1)); + } + else + { + visXAsRes = scrollCol; } - boxX = width - boxWidth; } - scrollCol = (int) (boxX / scalew / av.getCharWidth()); - scrollRow = (int) (boxY / scaleh / av.getCharHeight()); + // + // Convert y value to sequence position + // + + // convert y to residues + int yAsSeq = Math.round((float) y * alheight / sequencesHeight); - if (av.hasHiddenColumns()) + // get viewport height in sequences + // add 1 because height includes both endSeq and startSeq + int vpheight = props.getEndSeq() - props.getStartSeq() + 1; + + // get where y should be when accounting for hidden rows + // if y is in a hidden row region, shift up - but we still need absolute + // position, + // so convert back after getting visible region position + yAsSeq = hiddenSeqs.adjustForHiddenSeqs(hiddenSeqs + .findIndexWithoutHiddenSeqs(yAsSeq)); + + // check in case we went off the edge of the alignment + int visAlignHeight = hiddenSeqs.findIndexWithoutHiddenSeqs(alheight); + int visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq); + if (visYAsRes + vpheight - 1 > visAlignHeight) { - if (!av.getColumnSelection().isVisible(scrollCol)) + // went past the end of the alignment, adjust backwards + if ((scrollRow + vpheight - 1) < visAlignHeight) { - return; + visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(hiddenSeqs + .findIndexNAboveRow(vpheight - 1, alheight - 1)); + } + else + { + visYAsRes = scrollRow; } - - scrollCol = av.getColumnSelection().findColumnPosition(scrollCol); } - if (av.hasHiddenRows()) - { - scrollRow = av.getAlignment().getHiddenSequences() - .findIndexWithoutHiddenSeqs(scrollRow); - } + // update scroll values + scrollCol = visXAsRes; + scrollRow = visYAsRes; + } /** * Update the overview panel box when the associated alignment panel is * changed * + * @param hiddenSeqs + * hidden sequences + * @param hiddenCols + * hidden columns + * @param props + * viewport position properties */ - public void setBoxPosition() + public void setBoxPosition(HiddenSequences hiddenSeqs, + ColumnSelection hiddenCols, ViewportPositionProps props) { - updateScales(); - - int startRes = av.getStartRes(); - int endRes = av.getEndRes(); - - if (av.hasHiddenColumns()) - { - startRes = av.getColumnSelection().adjustForHiddenColumns(startRes); - endRes = av.getColumnSelection().adjustForHiddenColumns(endRes); - } - - int startSeq = av.getStartSeq(); - int endSeq = av.getEndSeq(); - - if (av.hasHiddenRows()) - { - startSeq = av.getAlignment().getHiddenSequences() - .adjustForHiddenSeqs(startSeq); - - endSeq = av.getAlignment().getHiddenSequences() - .adjustForHiddenSeqs(endSeq); - - } - - boxX = (int) (startRes * av.getCharWidth() * scalew); - boxY = (int) (startSeq * av.getCharHeight() * scaleh); - - if (av.hasHiddenColumns()) - { - boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew); - } - else - { - boxWidth = (int) ((endRes - startRes + 1) * av.getCharWidth() * scalew); - } - - boxHeight = (int) ((endSeq - startSeq) * av.getCharHeight() * scaleh); + int alwidth = props.getAbsoluteAlignmentWidth(); + int alheight = props.getAbsoluteAlignmentHeight(); + + // work with absolute values of startRes and endRes + int startRes = hiddenCols.adjustForHiddenColumns(props.getStartRes()); + int endRes = hiddenCols.adjustForHiddenColumns(props.getEndRes()); + + // work with absolute values of startSeq and endSeq + int startSeq = hiddenSeqs.adjustForHiddenSeqs(props.getStartSeq()); + int endSeq = hiddenSeqs.adjustForHiddenSeqs(props.getEndSeq()); + + // boxX, boxY is the x,y location equivalent to startRes, startSeq + boxX = Math.round((float) startRes * width / alwidth); + boxY = Math.round((float) startSeq * sequencesHeight / alheight); + + // boxWidth is the width in residues translated to pixels + // since the box includes both the start and end residues, add 1 to the + // difference + boxWidth = Math + .round((float) (endRes - startRes + 1) * width / alwidth); + // boxHeight is the height in sequences translated to pixels + boxHeight = Math.round((float) (endSeq - startSeq + 1) + * sequencesHeight + / alheight); } /** - * Update width and height scales in terms of the alignment width and height + * Draw the overview panel's viewport box on a graphics object + * + * @param g + * the graphics object to draw on */ - public void updateScales() + public void drawBox(Graphics g) { - int alwidth = av.getAlignment().getWidth(); - int alheight = av.getAlignment().getHeight() - + av.getAlignment().getHiddenSequences().getSize(); - - int fullsizeWidth = alwidth * av.getCharWidth(); - int fullsizeHeight = alheight * av.getCharHeight(); - - scalew = (float) width / fullsizeWidth; - scaleh = (float) sequencesHeight / fullsizeHeight; + g.drawRect(boxX, boxY, boxWidth, boxHeight); + g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2); } - // don't like this, scroll vals are separate from setting code public int getScrollCol() { return scrollCol; @@ -229,36 +285,32 @@ public class OverviewDimensions return scrollRow; } + // TODO should be removed, when unit test has mock Graphics object available + // to check boxX/boxY public int getBoxX() { return boxX; } + // TODO should be removed, when unit test has mock Graphics object available + // to check boxX/boxY public int getBoxY() { return boxY; } + // TODO should be removed, when unit test has mock Graphics object available public int getBoxWidth() { return boxWidth; } + // TODO should be removed, when unit test has mock Graphics object available public int getBoxHeight() { return boxHeight; } - public void setBoxX(int x) - { - boxX = x; - } - - public void setBoxY(int y) - { - boxY = y; - } - public void setWidth(int w) { width = w;