{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0]);
+ }
}
}
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (propertyName.equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(((int[]) evt.getNewValue())[1]
+ - ((int[]) evt.getOldValue())[1]);
+ }
}
}
// Here we only want to fastpaint on a scroll, with resize using a normal
// paint, so scroll events are identified as changes to the horizontal or
// vertical start value.
- if (evt.getPropertyName().equals(ViewportRanges.STARTRES))
+ if (evt.getPropertyName().equals(ViewportRanges.STARTRES)
+ || evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ))
{
// scroll event, repaint panel
repaint();
if (!av.getWrapAlignment())
{
int scrollX = 0;
- if (eventName.equals(ViewportRanges.STARTRES))
+ if (eventName.equals(ViewportRanges.STARTRES)
+ || eventName.equals(ViewportRanges.STARTRESANDSEQ))
{
// Make sure we're not trying to draw a panel
// larger than the visible window
+ if (eventName.equals(ViewportRanges.STARTRES))
+ {
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ }
+ else
+ {
+ scrollX = ((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0];
+ }
ViewportRanges vpRanges = av.getRanges();
- scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
int range = vpRanges.getEndRes() - vpRanges.getStartRes();
if (scrollX > range)
{
// scroll
fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(scrollX, ((int[]) evt.getNewValue())[1]
+ - ((int[]) evt.getOldValue())[1]);
+ }
}
}
@Override
public void paintComponent(Graphics g)
{
+ super.paintComponent(g);
+
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0]);
+ }
}
}
frame.setResizable(resizable);
frame.setMaximizable(resizable);
frame.setIconifiable(resizable);
+ frame.setOpaque(true);
if (frame.getX() < 1 && frame.getY() < 1)
{
@Override
public void paintComponent(Graphics g)
{
+ super.paintComponent(g);
+
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
+ else if (propertyName.equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ fastPaint(((int[]) evt.getNewValue())[1]
+ - ((int[]) evt.getOldValue())[1]);
+ }
}
}
@Override
public void paintComponent(Graphics g)
{
+ super.paintComponent(g);
+
/*
* shouldn't get called in wrapped mode as the scale above is
* drawn instead by SeqCanvas.drawNorthScale
// Here we only want to fastpaint on a scroll, with resize using a normal
// paint, so scroll events are identified as changes to the horizontal or
// vertical start value.
- if (evt.getPropertyName().equals(ViewportRanges.STARTRES))
+ if (evt.getPropertyName().equals(ViewportRanges.STARTRES)
+ || evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ))
{
// scroll event, repaint panel
repaint();
int transX = 0;
int transY = 0;
- gg.copyArea(horizontal * charWidth, vertical * charHeight,
- img.getWidth(), img.getHeight(), -horizontal * charWidth,
- -vertical * charHeight);
+ gg.copyArea(horizontal * charWidth, vertical * charHeight,
+ img.getWidth(), img.getHeight(), -horizontal * charWidth,
+ -vertical * charHeight);
- if (horizontal > 0) // scrollbar pulled right, image to the left
- {
- transX = (endRes - startRes - horizontal) * charWidth;
- startRes = endRes - horizontal;
- }
- else if (horizontal < 0)
- {
- endRes = startRes - horizontal;
- }
- else if (vertical > 0) // scroll down
- {
- startSeq = endSeq - vertical;
-
- if (startSeq < ranges.getStartSeq())
- { // ie scrolling too fast, more than a page at a time
- startSeq = ranges.getStartSeq();
+ if (horizontal > 0) // scrollbar pulled right, image to the left
+ {
+ transX = (endRes - startRes - horizontal) * charWidth;
+ startRes = endRes - horizontal;
}
- else
+ else if (horizontal < 0)
{
- transY = img.getHeight() - ((vertical + 1) * charHeight);
+ endRes = startRes - horizontal;
}
- }
- else if (vertical < 0)
- {
- endSeq = startSeq - vertical;
- if (endSeq > ranges.getEndSeq())
+ if (vertical > 0) // scroll down
{
- endSeq = ranges.getEndSeq();
+ startSeq = endSeq - vertical;
+
+ if (startSeq < ranges.getStartSeq())
+ { // ie scrolling too fast, more than a page at a time
+ startSeq = ranges.getStartSeq();
+ }
+ else
+ {
+ transY = img.getHeight() - ((vertical + 1) * charHeight);
+ }
+ }
+ else if (vertical < 0)
+ {
+ endSeq = startSeq - vertical;
+
+ if (endSeq > ranges.getEndSeq())
+ {
+ endSeq = ranges.getEndSeq();
+ }
}
- }
- gg.translate(transX, transY);
- drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
- gg.translate(-transX, -transY);
+ gg.translate(transX, transY);
+ drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
+ gg.translate(-transX, -transY);
- repaint();
+ repaint();
} finally
{
fastpainting = false;
int canvasWidth,
int canvasHeight, int startRes)
{
- int charHeight = av.getCharHeight();
- int charWidth = av.getCharWidth();
-
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
// height gap above each panel
int hgap = charHeight;
if (av.getScaleAboveWrapped())
private void drawUnwrappedSelection(Graphics2D g, SequenceGroup group,
int startRes, int endRes, int startSeq, int endSeq, int offset)
{
- int charWidth = av.getCharWidth();
-
+ int charWidth = av.getCharWidth();
+
if (!av.hasHiddenColumns())
{
drawPartialGroupOutline(g, group, startRes, endRes, startSeq, endSeq,
int startRes, int endRes, int startSeq, int endSeq,
int verticalOffset)
{
- int charHeight = av.getCharHeight();
- int charWidth = av.getCharWidth();
-
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
int visWidth = (endRes - startRes + 1) * charWidth;
int oldY = -1;
}
int scrollX = 0;
- if (eventName.equals(ViewportRanges.STARTRES))
+ if (eventName.equals(ViewportRanges.STARTRES)
+ || eventName.equals(ViewportRanges.STARTRESANDSEQ))
{
// Make sure we're not trying to draw a panel
// larger than the visible window
+ if (eventName.equals(ViewportRanges.STARTRES))
+ {
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ }
+ else
+ {
+ scrollX = ((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0];
+ }
ViewportRanges vpRanges = av.getRanges();
- scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
- int range = vpRanges.getViewportWidth();
+
+ int range = vpRanges.getEndRes() - vpRanges.getStartRes();
if (scrollX > range)
{
scrollX = range;
{
scrollX = -range;
}
- }
- // Both scrolling and resizing change viewport ranges: scrolling changes
- // both start and end points, but resize only changes end values.
- // Here we only want to fastpaint on a scroll, with resize using a normal
- // paint, so scroll events are identified as changes to the horizontal or
- // vertical start value.
-
- // scroll - startres and endres both change
- if (eventName.equals(ViewportRanges.STARTRES))
- {
- if (av.getWrapAlignment())
+ // Both scrolling and resizing change viewport ranges: scrolling changes
+ // both start and end points, but resize only changes end values.
+ // Here we only want to fastpaint on a scroll, with resize using a normal
+ // paint, so scroll events are identified as changes to the horizontal or
+ // vertical start value.
+ if (eventName.equals(ViewportRanges.STARTRES))
+ {
+ if (av.getWrapAlignment())
+ {
+ fastPaintWrapped(scrollX);
+ }
+ else
+ {
+ fastPaint(scrollX, 0);
+ }
+ }
+ else if (eventName.equals(ViewportRanges.STARTSEQ))
{
- fastPaintWrapped(scrollX);
+ // scroll
+ fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
}
- else
+ else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
{
fastPaint(scrollX, 0);
+ // bizarrely, we only need to scroll on the x value here as fastpaint
+ // copies the full height of the image anyway. Passing in the y value
+ // causes nasty repaint artefacts, which only disappear on a full
+ // repaint.
}
}
- else if (eventName.equals(ViewportRanges.STARTSEQ))
- {
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
- }
}
/**
}
}
- // update viewport
- ranges.setStartRes(xAsRes);
- ranges.setStartSeq(yAsSeq);
+ ranges.setStartResAndSeq(xAsRes, yAsSeq);
}
@Override
}
// update viewport
- ranges.setStartRes(visXAsRes);
- ranges.setStartSeq(visYAsSeq);
+ ranges.setStartResAndSeq(visXAsRes, visYAsSeq);
}
/**
import jalview.datamodel.HiddenColumns;
/**
- * Slightly less embryonic class which: Supplies and updates viewport properties
- * relating to position such as: start and end residues and sequences; ideally
- * will serve hidden columns/rows too. Intention also to support calculations
- * for positioning, scrolling etc. such as finding the middle of the viewport,
- * checking for scrolls off screen
+ * Supplies and updates viewport properties relating to position such as: start
+ * and end residues and sequences; ideally will serve hidden columns/rows too.
+ * Intention also to support calculations for positioning, scrolling etc. such
+ * as finding the middle of the viewport, checking for scrolls off screen
*/
public class ViewportRanges extends ViewportProperties
{
public static final String ENDSEQ = "endseq";
+ public static final String STARTRESANDSEQ = "startresandseq";
+
private boolean wrappedMode = false;
// start residue of viewport
*/
public void setStartEndRes(int start, int end)
{
+ int[] oldvalues = updateStartEndRes(start, end);
+ int oldstartres = oldvalues[0];
+ int oldendres = oldvalues[1];
+
+ changeSupport.firePropertyChange(STARTRES, oldstartres, startRes);
+ if (oldstartres == startRes)
+ {
+ // 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);
+ }
+ }
+
+ /**
+ * Update start and end residue values, adjusting for width constraints if
+ * necessary
+ *
+ * @param start
+ * start residue
+ * @param end
+ * end residue
+ * @return array containing old start and end residue values
+ */
+ private int[] updateStartEndRes(int start, int end)
+ {
int oldstartres = this.startRes;
/*
{
endRes = end;
}
-
- changeSupport.firePropertyChange(STARTRES, oldstartres, startRes);
- if (oldstartres == startRes)
- {
- // 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);
- }
+ return new int[] { oldstartres, oldendres };
}
/**
*/
public void setStartEndSeq(int start, int end)
{
+ int[] oldvalues = updateStartEndSeq(start, end);
+ int oldstartseq = oldvalues[0];
+ int oldendseq = oldvalues[1];
+
+ changeSupport.firePropertyChange(STARTSEQ, oldstartseq, startSeq);
+ if (oldstartseq == startSeq)
+ {
+ // event won't be fired if start positions are the same
+ // fire in case the end positions changed
+ changeSupport.firePropertyChange(ENDSEQ, oldendseq, endSeq);
+ }
+ }
+
+ /**
+ * Update start and end sequence values, adjusting for height constraints if
+ * necessary
+ *
+ * @param start
+ * start sequence
+ * @param end
+ * end sequence
+ * @return array containing old start and end sequence values
+ */
+ private int[] updateStartEndSeq(int start, int end)
+ {
int oldstartseq = this.startSeq;
int visibleHeight = getVisibleAlignmentHeight();
if (start > visibleHeight - 1)
{
endSeq = end;
}
-
- changeSupport.firePropertyChange(STARTSEQ, oldstartseq, startSeq);
- if (oldstartseq == startSeq)
- {
- // event won't be fired if start positions are the same
- // fire in case the end positions changed
- changeSupport.firePropertyChange(ENDSEQ, oldendseq, endSeq);
- }
+ return new int[] { oldstartseq, oldendseq };
}
/**
}
/**
+ * Set start residue and start sequence together (fires single event)
+ *
+ * @param res
+ * the start residue
+ * @param seq
+ * the start sequence
+ */
+ public void setStartResAndSeq(int res, int seq)
+ {
+ int width = getViewportWidth();
+ int[] oldresvalues = updateStartEndRes(res, res + width - 1);
+
+ int startseq = seq;
+ int height = getViewportHeight();
+ if (startseq + height - 1 > getVisibleAlignmentHeight() - 1)
+ {
+ startseq = getVisibleAlignmentHeight() - height;
+ }
+ int[] oldseqvalues = updateStartEndSeq(startseq, startseq + height - 1);
+
+ int[] old = new int[] { oldresvalues[0], oldseqvalues[0] };
+ int[] newresseq = new int[] { startRes, startSeq };
+ changeSupport.firePropertyChange(STARTRESANDSEQ, old, newresseq);
+ }
+
+ /**
* Get start residue of viewport
*/
public int getStartRes()
vr.setEndSeq(al.getHeight());
assertEquals(vr.getEndSeq(), al.getHeight() - 1);
- // vr.setEndRes(al.getHeight() - 1);
vr.setEndSeq(al.getHeight() - 1);
assertEquals(vr.getEndSeq(), al.getHeight() - 1);
}
}
@Test(groups = { "Functional" })
+ public void testSetStartResAndSeq()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportHeight(10);
+ vr.setStartResAndSeq(3, 6);
+ assertEquals(vr.getStartRes(), 3);
+ assertEquals(vr.getStartSeq(), 6);
+ assertEquals(vr.getEndRes(), 3 + vr.getViewportWidth() - 1);
+ assertEquals(vr.getEndSeq(), 6 + vr.getViewportHeight() - 1);
+
+ vr.setStartResAndSeq(10, 25);
+ assertEquals(vr.getStartRes(), 10);
+ assertEquals(vr.getStartSeq(), 19);
+ assertEquals(vr.getEndRes(), 10 + vr.getViewportWidth() - 1);
+ assertEquals(vr.getEndSeq(), 19 + vr.getViewportHeight() - 1);
+ }
+
+ @Test(groups = { "Functional" })
public void testSetViewportHeight()
{
ViewportRanges vr = new ViewportRanges(al);
// one event fired when startRes is called with new value
vr.setStartRes(4);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
// no event fired for same value
l.reset();
vr.setStartSeq(4);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.setStartSeq(4);
l.reset();
vr.setEndSeq(10);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.setEndSeq(10);
l.reset();
vr.setStartEndRes(2, 15);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
vr.setStartEndRes(2, 15);
// check new value fired by event is corrected startres
vr.setStartEndRes(-1, 5);
- assertTrue(l.verify(1, Arrays.asList("startres"), Arrays.asList(0)));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES),
+ Arrays.asList(0)));
l.reset();
// check new value fired by event is corrected endres
vr.setStartEndRes(0, -1);
- assertTrue(l.verify(1, Arrays.asList("endres"), Arrays.asList(0)));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDRES),
+ Arrays.asList(0)));
l.reset();
vr.setStartEndSeq(2, 15);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.setStartEndSeq(2, 15);
// check new value fired by event is corrected startseq
vr.setStartEndSeq(-1, 5);
- assertTrue(l.verify(1, Arrays.asList("startseq"), Arrays.asList(0)));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ),
+ Arrays.asList(0)));
l.reset();
// check new value fired by event is corrected endseq
vr.setStartEndSeq(0, -1);
- assertTrue(l.verify(1, Arrays.asList("endseq"), Arrays.asList(0)));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDSEQ),
+ Arrays.asList(0)));
l.reset();
// reset for later tests
// test viewport height and width setting triggers event
vr.setViewportHeight(10);
- assertTrue(l.verify(1, Arrays.asList("endseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDSEQ)));
l.reset();
vr.setViewportWidth(18);
- assertTrue(l.verify(1, Arrays.asList("endres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDRES)));
l.reset();
// already has seq start set to 2, so triggers endseq
vr.setViewportStartAndHeight(2, 16);
- assertTrue(l.verify(1, Arrays.asList("endseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.ENDSEQ)));
l.reset();
vr.setViewportStartAndWidth(1, 14);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
// test page up/down triggers event
vr.pageUp();
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.pageDown();
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
// test scrolling triggers event
vr.scrollUp(true);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.scrollUp(false);
- assertTrue(l.verify(1, Arrays.asList("startseq")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTSEQ)));
l.reset();
vr.scrollRight(true);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
vr.scrollRight(false);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
l.reset();
vr.scrollToVisible(10, 10);
assertTrue(l.verify(4,
- Arrays.asList("startseq", "startseq", "startseq", "startseq")));
+ Arrays.asList(ViewportRanges.STARTSEQ, ViewportRanges.STARTSEQ,
+ ViewportRanges.STARTSEQ, ViewportRanges.STARTSEQ)));
l.reset();
/*
l.reset();
vr.scrollToWrappedVisible(25);
- assertTrue(l.verify(1, Arrays.asList("startres")));
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRES)));
+ l.reset();
+
+ // test setStartResAndSeq triggers one event
+ vr.setStartResAndSeq(5, 7);
+ assertTrue(l.verify(1, Arrays.asList(ViewportRanges.STARTRESANDSEQ),
+ Arrays.asList(5, 7)));
+
+ l.reset();
}
@Test(groups = { "Functional" })
{
firecount++;
events.add(evt.getPropertyName());
- newvalues.add((Integer) evt.getNewValue());
+ if (evt.getPropertyName().equals(ViewportRanges.STARTRESANDSEQ))
+ {
+ newvalues.add(((int[]) evt.getNewValue())[0]);
+ newvalues.add(((int[]) evt.getNewValue())[1]);
+ }
+ else
+ {
+ newvalues.add((Integer) evt.getNewValue());
+ }
}
public boolean verify(int count, List<String> eventslist,