X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2FViewportRanges.java;h=b96ac2829e20f52ec0a435ea817078dbdcd5bfbc;hb=cc4dc8e354640ad8b2c5b522f7a61a469546fa10;hp=4bdaa815caec0d0cf561bb353452f178c10aaa45;hpb=f3d0dc3395aff566e8005e6a6a9a13bf795c14a4;p=jalview.git diff --git a/src/jalview/viewmodel/ViewportRanges.java b/src/jalview/viewmodel/ViewportRanges.java index 4bdaa81..b96ac28 100644 --- a/src/jalview/viewmodel/ViewportRanges.java +++ b/src/jalview/viewmodel/ViewportRanges.java @@ -41,6 +41,8 @@ public class ViewportRanges extends ViewportProperties public static final String STARTRESANDSEQ = "startresandseq"; + public static final String MOVE_VIEWPORT = "move_viewport"; + private boolean wrappedMode = false; // start residue of viewport @@ -95,7 +97,7 @@ public class ViewportRanges extends ViewportProperties */ public int getVisibleAlignmentWidth() { - return al.getWidth() - al.getHiddenColumns().getSize(); + return al.getVisibleWidth(); } /** @@ -110,7 +112,7 @@ public class ViewportRanges extends ViewportProperties * Set first residue visible in the viewport, and retain the current width. * Fires a property change event. * - * @param res + * @param res * residue position */ public void setStartRes(int res) @@ -134,13 +136,25 @@ public class ViewportRanges extends ViewportProperties int[] oldvalues = updateStartEndRes(start, end); int oldstartres = oldvalues[0]; int oldendres = oldvalues[1]; + + if (oldstartres == startRes && oldendres == endRes) + { + return; // BH 2019.07.27 standard check for no changes + } + // "STARTRES" is a misnomer here -- really "STARTORENDRES" + // note that this could be "no change" if the range is just being expanded changeSupport.firePropertyChange(STARTRES, oldstartres, startRes); if (oldstartres == startRes) { + // only caught in ViewportRangesTest + // No listener cares about this + // "ENDRES" is a misnomer here -- really "ENDONLYRES" + // BH 2019.07.27 adds end change check + // fire only if only the end is changed // event won't be fired if start positions are same // fire an event for the end positions in case they changed - changeSupport.firePropertyChange(ENDRES, oldendres, endRes); + changeSupport.firePropertyChange(ENDRES, oldendres, endRes); } } @@ -247,34 +261,16 @@ public class ViewportRanges extends ViewportProperties */ private int[] updateStartEndSeq(int start, int end) { - int oldstartseq = this.startSeq; - int visibleHeight = getVisibleAlignmentHeight(); - if (start > visibleHeight - 1) - { - startSeq = Math.max(visibleHeight - 1, 0); - } - else if (start < 0) - { - startSeq = 0; - } - else - { - startSeq = start; - } +// if (end == 3 && this.endSeq == 14 || end == 13 && this.endSeq == 3) { +// new NullPointerException().printStackTrace(System.out); +// System.out.println("ViewportRange updateStartEndSeq " + start + " " + end + " " + Thread.currentThread()); +// } + int oldstartseq = this.startSeq; int oldendseq = this.endSeq; - if (end >= visibleHeight) - { - endSeq = Math.max(visibleHeight - 1, 0); - } - else if (end < 0) - { - endSeq = 0; - } - else - { - endSeq = end; - } + int max = getVisibleAlignmentHeight() - 1; + startSeq = Math.max(0, Math.min(start, max)); + endSeq = Math.max(0, Math.min(end, max)); return new int[] { oldstartseq, oldendseq }; } @@ -283,12 +279,12 @@ public class ViewportRanges extends ViewportProperties * event. * * @param seq - * sequence position + * sequence position in the range [0, height) */ public void setEndSeq(int seq) { - int height = getViewportHeight(); - setStartEndSeq(seq - height + 1, seq); + // BH 2018.04.18 added safety for seq < 0; comment about not being >= height + setStartEndSeq(Math.max(0, seq + 1 - getViewportHeight()), seq); } /** @@ -389,21 +385,15 @@ public class ViewportRanges extends ViewportProperties */ public void setViewportStartAndWidth(int start, int w) { - int vpstart = start; - if (vpstart < 0) - { - vpstart = 0; - } - - /* - * if not wrapped, don't leave white space at the right margin - */ + int vpstart = Math.max(0, start); + if (!wrappedMode) { - if ((w <= getVisibleAlignmentWidth()) - && (vpstart + w - 1 > getVisibleAlignmentWidth() - 1)) + // if not wrapped, don't leave white space at the right margin + int maxStart = getVisibleAlignmentWidth() - w; + if (maxStart >= 0) { - vpstart = getVisibleAlignmentWidth() - w; + vpstart = Math.min(vpstart, maxStart); } } @@ -422,17 +412,14 @@ public class ViewportRanges extends ViewportProperties */ public void setViewportStartAndHeight(int start, int h) { - int vpstart = start; - if (vpstart < 0) + int vpstart = Math.max(0, start); + int maxStart = getVisibleAlignmentHeight() - h; + if (maxStart > 0) { - vpstart = 0; - } - else if ((h <= getVisibleAlignmentHeight()) - && (vpstart + h - 1 > getVisibleAlignmentHeight() - 1)) - // viewport height is less than the full alignment and we are running off - // the bottom - { - vpstart = getVisibleAlignmentHeight() - h; + // can't start higher than vertical extent will allow + // (viewport height is less than the full alignment + // and we are running off the bottom) + vpstart = Math.min(vpstart, maxStart); } setStartEndSeq(vpstart, vpstart + h - 1); } @@ -542,18 +529,33 @@ public class ViewportRanges extends ViewportProperties * the startRes changed, else false. * * @param res - * residue position to scroll to + * residue position to scroll to NB visible position not absolute + * alignment position * @return */ public boolean scrollToWrappedVisible(int res) { - int oldStartRes = startRes; - int width = getViewportWidth(); - - if (res >= oldStartRes && res < oldStartRes + width) + int newStartRes = calcWrappedStartResidue(res); + if (newStartRes == startRes) { return false; } + setStartRes(newStartRes); + + return true; + } + + /** + * Calculate wrapped start residue from visible start residue + * + * @param res + * visible start residue + * @return left column of panel res will be located in + */ + private int calcWrappedStartResidue(int res) + { + int oldStartRes = startRes; + int width = getViewportWidth(); boolean up = res < oldStartRes; int widthsToScroll = Math.abs((res - oldStartRes) / width); @@ -569,19 +571,16 @@ public class ViewportRanges extends ViewportProperties { newStartRes = 0; } - - setStartRes(newStartRes); - - return true; + return newStartRes; } /** * Scroll so that (x,y) is visible. Fires a property change event. * * @param x - * x position in alignment + * x position in alignment (absolute position) * @param y - * y position in alignment + * y position in alignment (absolute position) */ public void scrollToVisible(int x, int y) { @@ -593,16 +592,16 @@ public class ViewportRanges extends ViewportProperties { scrollUp(false); } - + HiddenColumns hidden = al.getHiddenColumns(); - while (x < hidden.adjustForHiddenColumns(startRes)) + while (x < hidden.visibleToAbsoluteColumn(startRes)) { if (!scrollRight(false)) { break; } } - while (x > hidden.adjustForHiddenColumns(endRes)) + while (x > hidden.visibleToAbsoluteColumn(endRes)) { if (!scrollRight(true)) { @@ -612,6 +611,62 @@ public class ViewportRanges extends ViewportProperties } /** + * Set the viewport location so that a position is visible + * + * @param x + * column to be visible: absolute position in alignment + * @param y + * row to be visible: absolute position in alignment + */ + public boolean setViewportLocation(int x, int y) + { + boolean changedLocation = false; + + // convert the x,y location to visible coordinates + int visX = al.getHiddenColumns().absoluteToVisibleColumn(x); + int visY = al.getHiddenSequences().findIndexWithoutHiddenSeqs(y); + + // if (vis_x,vis_y) is already visible don't do anything + if (startRes > visX || visX > endRes + || startSeq > visY && visY > endSeq) + { + int[] old = new int[] { startRes, startSeq }; + int[] newresseq; + if (wrappedMode) + { + int newstartres = calcWrappedStartResidue(visX); + setStartRes(newstartres); + newresseq = new int[] { startRes, startSeq }; + } + else + { + // set the viewport x location to contain vis_x + int newstartres = visX; + int width = getViewportWidth(); + if (newstartres + width - 1 > getVisibleAlignmentWidth() - 1) + { + newstartres = getVisibleAlignmentWidth() - width; + } + updateStartEndRes(newstartres, newstartres + width - 1); + + // set the viewport y location to contain vis_y + int newstartseq = visY; + int height = getViewportHeight(); + if (newstartseq + height - 1 > getVisibleAlignmentHeight() - 1) + { + newstartseq = getVisibleAlignmentHeight() - height; + } + updateStartEndSeq(newstartseq, newstartseq + height - 1); + + newresseq = new int[] { startRes, startSeq }; + } + changedLocation = true; + changeSupport.firePropertyChange(MOVE_VIEWPORT, old, newresseq); + } + return changedLocation; + } + + /** * Adjust sequence position for page up. Fires a property change event. */ public void pageUp() @@ -722,4 +777,10 @@ public class ViewportRanges extends ViewportProperties return maxScroll; } + + + @Override + public String toString() { + return "[ViewportRange " + startSeq + "-" + endSeq + ", "+ startRes + "-" + endRes + "]"; + } }