X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FOverviewDimensions.java;h=39d0098d2c0a1ca229d5717ed17c45be244aa59a;hb=56ac68efa74c060e03a2b5b805ca8b8872f907e1;hp=1f18a1022fc4327a0fa26e1b6a24a7a94a3fc35a;hpb=1f015ae6034c51f7e7ab619fe428943899755d1c;p=jalview.git diff --git a/src/jalview/viewmodel/OverviewDimensions.java b/src/jalview/viewmodel/OverviewDimensions.java index 1f18a10..39d0098 100644 --- a/src/jalview/viewmodel/OverviewDimensions.java +++ b/src/jalview/viewmodel/OverviewDimensions.java @@ -20,78 +20,84 @@ */ package jalview.viewmodel; -import jalview.datamodel.ColumnSelection; +import jalview.api.AlignmentColsCollectionI; +import jalview.api.AlignmentRowsCollectionI; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.HiddenColumns; import jalview.datamodel.HiddenSequences; +import java.awt.Dimension; import java.awt.Graphics; +import java.awt.Rectangle; -public class OverviewDimensions +public abstract class OverviewDimensions { - // Default width and height values - private static final int DEFAULT_GRAPH_HEIGHT = 20; + protected static final int MAX_WIDTH = 400; + + protected static final int MIN_WIDTH = 120; + + protected static final int MIN_SEQ_HEIGHT = 40; - private static final int MAX_WIDTH = 400; + protected static final int MAX_SEQ_HEIGHT = 300; - private static final int MIN_WIDTH = 120; + private static final int DEFAULT_GRAPH_HEIGHT = 20; + + protected int width; - private static final int MIN_SEQ_HEIGHT = 40; + protected int sequencesHeight; - private static final int MAX_SEQ_HEIGHT = 300; + protected int graphHeight = DEFAULT_GRAPH_HEIGHT; - // width of the overview panel - private int width; + protected int boxX = -1; - // height of sequences part of the overview panel - private int sequencesHeight; + protected int boxY = -1; - // height of the graphs part of the overview panel - private int graphHeight = DEFAULT_GRAPH_HEIGHT; + protected int boxWidth = -1; - // dimensions of box outlining current extent of view in alignment panel - // location of left side of box - private int boxX = -1; + protected int boxHeight = -1; - // location of bottom of box - private int boxY = -1; + protected int alwidth; - // width of box - private int boxWidth = -1; + protected int alheight; - // height of box - private int boxHeight = -1; + protected float widthRatio; - // scroll position in viewport corresponding to boxX - private int scrollCol = -1; + protected float heightRatio; - // scroll position in viewport corresponding to boxY - private int scrollRow = -1; + private Rectangle vpbox = new Rectangle(); /** * Create an OverviewDimensions object * - * @param props + * @param ranges * positional properties of the viewport * @param showAnnotationPanel * true if the annotation panel is to be shown, false otherwise */ - public OverviewDimensions(ViewportPositionProps props, - boolean showAnnotationPanel) + public OverviewDimensions(ViewportRanges ranges, + boolean showAnnotationPanel, Dimension dim) { - // scale the initial size of overviewpanel to shape of alignment - float initialScale = (float) props.getAbsoluteAlignmentWidth() - / (float) props.getAbsoluteAlignmentHeight(); - if (!showAnnotationPanel) { graphHeight = 0; } - if (props.getAbsoluteAlignmentWidth() > props + // scale the initial size of overviewpanel to shape of alignment + float initialScale = (float) ranges.getAbsoluteAlignmentWidth() + / (float) ranges.getAbsoluteAlignmentHeight(); + + if (dim != null) + { + width = dim.width; + sequencesHeight = dim.height; + return; + } + if (ranges.getAbsoluteAlignmentWidth() > ranges .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; @@ -100,7 +106,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) @@ -111,229 +117,239 @@ public class OverviewDimensions } /** - * Check box dimensions and scroll positions and correct if necessary + * Draw the overview panel's viewport box on a graphics object * - * @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 + * @param g + * the graphics object to draw on */ - public void updateViewportFromMouse(int mousex, int mousey, - HiddenSequences hiddenSeqs, ColumnSelection hiddenCols, - ViewportPositionProps props) + public void drawBox(Graphics g) { - int x = mousex; - int y = mousey; - - int alwidth = props.getAbsoluteAlignmentWidth(); - int alheight = props.getAbsoluteAlignmentHeight(); - - if (x < 0) - { - x = 0; - } - else if (x >= alwidth) - { - x = alwidth - 1; - } - - if (y < 0) - { - y = 0; - } - else if (y >= alheight) - { - y = alheight - 1; - } - - // - // 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 - xAsRes = hiddenCols.adjustForHiddenColumns(hiddenCols - .findColumnPosition(xAsRes)); - - // get where end res should be by adding the viewport width on - int endRes = xAsRes + vpwidth; - - // check in case we went off the edge of the alignment - if (endRes > alwidth) - { - // went past the end of the alignment, adjust backwards - endRes = alwidth; - // recalc xAsRes backwards from endRes - xAsRes = endRes - vpwidth; - } - - // - // Convert y value to sequence position - // - - // convert y to residues - int yAsSeq = Math.round((float) y * alheight / sequencesHeight); - - // get viewport height in sequences - int vpheight = props.getEndSeq() - props.getStartSeq() + 1; + // System.out.println("OD drawBox " + boxX + " " + boxY + " " + boxWidth + // + " " + boxHeight); + updateBox(); + g.drawRect(boxX, boxY, boxWidth, boxHeight); + g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2); + } - // 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)); + public int getBoxX() + { + return boxX; + } - // get where end seq should be by adding the viewport height on - int endSeq = yAsSeq + vpheight; + public int getBoxY() + { + return boxY; + } - // check in case we went off the edge of the alignment - if (endSeq > alheight) - { - // went past the end of the alignment, adjust backwards - endSeq = alheight; - // recalc yAsSeq backwards from endSeq - yAsSeq = endSeq - vpheight + 1; - } + public int getBoxWidth() + { + return boxWidth; + } - // convert absolute positions back to visible alignment positions for - // viewport scrolling - scrollCol = hiddenCols.findColumnPosition(xAsRes); - scrollRow = hiddenSeqs.findIndexWithoutHiddenSeqs(yAsSeq); + public int getBoxHeight() + { + return boxHeight; } /** - * Update the overview panel box when the associated alignment panel is - * changed + * Returns the width of the Overview in pixels * - * @param hiddenSeqs - * hidden sequences - * @param hiddenCols - * hidden columns - * @param props - * viewport position properties + * @return */ - public void setBoxPosition(HiddenSequences hiddenSeqs, - ColumnSelection hiddenCols, ViewportPositionProps props) + public int getWidth() { - 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 - 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); + return width; } /** - * Draw the overview panel's viewport box on a graphics object + * Returns the height of the Overview in pixels * - * @param g - * the graphics object to draw on + * @return */ - public void drawBox(Graphics g) - { - 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; - } - - public int getScrollRow() + public int getHeight() { - return scrollRow; + return sequencesHeight + graphHeight; } - // TODO should be removed, when unit test has mock Graphics object available - // to check boxX/boxY - public int getBoxX() + /** + * Returns the height of the sequence alignment in the Overview in pixels + * + * @return + */ + public int getSequencesHeight() { - return boxX; + return sequencesHeight; } - // TODO should be removed, when unit test has mock Graphics object available - // to check boxX/boxY - public int getBoxY() + public int getGraphHeight() { - return boxY; + return graphHeight; } - // TODO should be removed, when unit test has mock Graphics object available - public int getBoxWidth() + public float getPixelsPerCol() { - return boxWidth; + resetAlignmentDims(); + return 1 / widthRatio; } - // TODO should be removed, when unit test has mock Graphics object available - public int getBoxHeight() + public float getPixelsPerSeq() { - return boxHeight; + resetAlignmentDims(); + return 1 / heightRatio; } public void setWidth(int w) { width = w; + widthRatio = (float) alwidth / width; } public void setHeight(int h) { + // BH 2019 problem was that component.resize() can come + // after setBoxPosition(). + // Solution was to move setting of box dimensions to paint sequencesHeight = h - graphHeight; + heightRatio = (float) alheight / sequencesHeight; } - public int getWidth() - { - return width; - } + /** + * Update the viewport location from a mouse click in the overview panel + * + * @param mousex + * x location of mouse + * @param mousey + * y location of mouse + * @param hiddenSeqs + * the alignment's hidden sequences + * @param hiddenCols + * the alignment's hidden columns + */ + public abstract void updateViewportFromMouse(int mousex, int mousey, + HiddenSequences hiddenSeqs, HiddenColumns hiddenCols); - public int getHeight() + /** + * Update the viewport location from a mouse drag within the overview's box + * + * @param mousex + * x location of mouse + * @param mousey + * y location of mouse + * @param hiddenSeqs + * the alignment's hidden sequences + * @param hiddenCols + * the alignment's hidden columns + */ + public abstract void adjustViewportFromMouse(int mousex, int mousey, + HiddenSequences hiddenSeqs, HiddenColumns hiddenCols); + + /** + * Initialise dragging from the mouse - must be called on initial mouse click + * before using adjustViewportFromMouse in drag operations + * + * @param mousex + * x location of mouse + * @param mousey + * y location of mouse + * @param hiddenSeqs + * the alignment's hidden sequences + * @param hiddenCols + * the alignment's hidden columns + */ + public abstract void setDragPoint(int x, int y, + HiddenSequences hiddenSeqs, HiddenColumns hiddenCols); + + /* + * Move the viewport so that the top left corner of the overview's box + * is at the mouse position (leftx, topy) + */ + protected abstract void updateViewportFromTopLeft(int leftx, int topy, + HiddenSequences hiddenSeqs, HiddenColumns hiddenCols); + + /** + * Set the overview panel's box position to match the viewport + * + * @param hiddenSeqs + * the alignment's hidden sequences + * @param hiddenCols + * the alignment's hidden columns + */ + public abstract void setBoxPosition(HiddenSequences hiddenSeqs, + HiddenColumns hiddenCols); + + /** + * Get the collection of columns used by this overview dimensions object + * + * @param hiddenCols + * the alignment's hidden columns + * @return a column collection + */ + public abstract AlignmentColsCollectionI getColumns(AlignmentI al); + + /** + * Get the collection of rows used by this overview dimensions object + * + * @param al + * the alignment + * @return a row collection + */ + public abstract AlignmentRowsCollectionI getRows(AlignmentI al); + + /** + * Updates overview dimensions to account for current alignment dimensions + */ + protected abstract void resetAlignmentDims(); + + /* + * Given the box coordinates in residues and sequences, set the box dimensions in the overview window + */ + protected void setBoxPosition(int startRes, int startSeq, int vpwidth, + int vpheight) { - return sequencesHeight + graphHeight; + resetAlignmentDims(); + vpbox = new Rectangle(startRes, startSeq, vpwidth, vpheight); + updateBox(); } - public int getSequencesHeight() + public void updateBox() { - return sequencesHeight; + // boxX, boxY is the x,y location equivalent to startRes, startSeq + int xPos = Math.min(vpbox.x, alwidth - vpbox.width + 1); + boxX = Math.round(xPos / widthRatio); + boxY = Math.round(vpbox.y / heightRatio); + + // boxWidth is the width in residues translated to pixels + boxWidth = Math.max(1, Math.round(vpbox.width / widthRatio)); + + // boxHeight is the height in sequences translated to pixels + boxHeight = Math.max(1, Math.round(vpbox.height / heightRatio)); } - public int getGraphHeight() + /** + * Answers if a mouse position is in the overview's red box + * + * @param x + * mouse x position + * @param y + * mouse y position + * @return true if (x,y) is inside the box + */ + public boolean isPositionInBox(int x, int y) { - return graphHeight; + return (x > boxX && y > boxY && x < boxX + boxWidth + && y < boxY + boxHeight); } -} + + /* + * Given the centre x position, calculate the box's left x position + */ + protected abstract int getLeftXFromCentreX(int mousex, + HiddenColumns hidden); + + /* + * Given the centre y position, calculate the box's top y position + */ + protected abstract int getTopYFromCentreY(int mousey, + HiddenSequences hidden); + +} \ No newline at end of file