X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FOverviewDimensions.java;fp=src%2Fjalview%2Fviewmodel%2FOverviewDimensions.java;h=43680b57d5870f70b0be5b9eecd1749d7520b853;hb=d5bcc3830eab04e6db816e1c2ad8fce1dc189612;hp=0000000000000000000000000000000000000000;hpb=3ebdd4e28382e38a181aae1eed71549f603f9025;p=jalview.git diff --git a/src/jalview/viewmodel/OverviewDimensions.java b/src/jalview/viewmodel/OverviewDimensions.java new file mode 100644 index 0000000..43680b5 --- /dev/null +++ b/src/jalview/viewmodel/OverviewDimensions.java @@ -0,0 +1,343 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.viewmodel; + +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.HiddenSequences; + +import java.awt.Graphics; + +public class OverviewDimensions +{ + // Default width and height values + private static final int DEFAULT_GRAPH_HEIGHT = 20; + + private static final int MAX_WIDTH = 400; + + private static final int MIN_WIDTH = 120; + + private static final int MIN_SEQ_HEIGHT = 40; + + private static final int MAX_SEQ_HEIGHT = 300; + + // width of the overview panel + private int width; + + // height of sequences part of the overview panel + private int sequencesHeight; + + // height of the graphs part of the overview panel + private int graphHeight = DEFAULT_GRAPH_HEIGHT; + + // dimensions of box outlining current extent of view in alignment panel + // location of left side of box + private int boxX = -1; + + // location of bottom of box + private int boxY = -1; + + // width of box + private int boxWidth = -1; + + // 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; + + /** + * Create an OverviewDimensions object + * + * @param ranges + * positional properties of the viewport + * @param showAnnotationPanel + * true if the annotation panel is to be shown, false otherwise + */ + public OverviewDimensions(ViewportRanges ranges, + boolean showAnnotationPanel) + { + // scale the initial size of overviewpanel to shape of alignment + float initialScale = (float) ranges.getAbsoluteAlignmentWidth() + / (float) ranges.getAbsoluteAlignmentHeight(); + + if (!showAnnotationPanel) + { + graphHeight = 0; + } + + if (ranges.getAbsoluteAlignmentWidth() > ranges + .getAbsoluteAlignmentHeight()) + { + // wider + width = MAX_WIDTH; + sequencesHeight = Math.round(MAX_WIDTH / initialScale); + if (sequencesHeight < MIN_SEQ_HEIGHT) + { + sequencesHeight = MIN_SEQ_HEIGHT; + } + } + else + { + // taller + width = Math.round(MAX_WIDTH * initialScale); + sequencesHeight = MAX_SEQ_HEIGHT; + + if (width < MIN_WIDTH) + { + width = MIN_WIDTH; + } + } + } + + /** + * 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 ranges + * viewport position properties + */ + public void updateViewportFromMouse(int mousex, int mousey, + HiddenSequences hiddenSeqs, ColumnSelection hiddenCols, + ViewportRanges ranges) + { + int x = mousex; + int y = mousey; + + int alwidth = ranges.getAbsoluteAlignmentWidth(); + int alheight = ranges.getAbsoluteAlignmentHeight(); + + if (x < 0) + { + x = 0; + } + + if (y < 0) + { + y = 0; + } + + // + // 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 = ranges.getEndRes() - ranges.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) + { + // 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) + { + visXAsRes = hiddenCols.findColumnPosition(hiddenCols + .subtractVisibleColumns(vpwidth - 1, alwidth - 1)); + } + else + { + visXAsRes = scrollCol; + } + } + + // + // Convert y value to sequence position + // + + // convert y to residues + int yAsSeq = Math.round((float) y * alheight / sequencesHeight); + + // get viewport height in sequences + // add 1 because height includes both endSeq and startSeq + int vpheight = ranges.getEndSeq() - ranges.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) + { + // went past the end of the alignment, adjust backwards + if ((scrollRow + vpheight - 1) < visAlignHeight) + { + visYAsRes = hiddenSeqs.findIndexWithoutHiddenSeqs(hiddenSeqs + .subtractVisibleRows(vpheight - 1, alheight - 1)); + } + else + { + visYAsRes = 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 ranges + * viewport position properties + */ + public void setBoxPosition(HiddenSequences hiddenSeqs, + ColumnSelection hiddenCols, ViewportRanges ranges) + { + int alwidth = ranges.getAbsoluteAlignmentWidth(); + int alheight = ranges.getAbsoluteAlignmentHeight(); + + // work with absolute values of startRes and endRes + int startRes = hiddenCols.adjustForHiddenColumns(ranges.getStartRes()); + int endRes = hiddenCols.adjustForHiddenColumns(ranges.getEndRes()); + + // work with absolute values of startSeq and endSeq + int startSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.getStartSeq()); + int endSeq = hiddenSeqs.adjustForHiddenSeqs(ranges.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); + } + + /** + * Draw the overview panel's viewport box on a graphics object + * + * @param g + * the graphics object to draw on + */ + public void drawBox(Graphics g) + { + g.drawRect(boxX, boxY, boxWidth, boxHeight); + g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2); + } + + public int getScrollCol() + { + return scrollCol; + } + + public int getScrollRow() + { + 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 setWidth(int w) + { + width = w; + } + + public void setHeight(int h) + { + sequencesHeight = h - graphHeight; + } + + public int getWidth() + { + return width; + } + + public int getHeight() + { + return sequencesHeight + graphHeight; + } + + public int getSequencesHeight() + { + return sequencesHeight; + } + + public int getGraphHeight() + { + return graphHeight; + } +}