case KeyEvent.VK_PAGE_UP:
if (viewport.getWrapAlignment())
{
- alignPanel.scrollUp(true);
+ ranges.scrollUp(true);
}
else
{
- alignPanel.setScrollValues(ranges.getStartRes(),
- 2 * ranges.getStartSeq() - ranges.getEndSeq());
+ ranges.pageUp();
}
break;
case KeyEvent.VK_PAGE_DOWN:
if (viewport.getWrapAlignment())
{
- alignPanel.scrollUp(false);
+ ranges.scrollUp(false);
}
else
{
- alignPanel
- .setScrollValues(ranges.getStartRes(), ranges.getEndSeq());
+ ranges.pageDown();
}
break;
int seqOffset = findComplementScrollTarget(sr);
if (!sr.isEmpty())
{
- complementPanel.setFollowingComplementScroll(true);
+ complementPanel.setToScrollComplementPanel(false);
complementPanel.scrollToCentre(sr, seqOffset);
+ complementPanel.setToScrollComplementPanel(true);
}
}
import jalview.datamodel.SearchResultsI;
import jalview.datamodel.SequenceI;
import jalview.structure.StructureSelectionManager;
+import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import java.awt.BorderLayout;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
+import java.beans.PropertyChangeEvent;
import java.util.List;
public class AlignmentPanel extends Panel implements AdjustmentListener,
- AlignmentViewPanel
+ AlignmentViewPanel, ViewportListenerI
{
public AlignViewport av;
@Override
public void componentResized(ComponentEvent evt)
{
- setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
+ // reset the viewport ranges when the alignment panel is resized
+ // in particular, this initialises the end residue value when Jalview
+ // is initialised
+ if (av.getWrapAlignment())
+ {
+ int widthInRes = seqPanel.seqCanvas
+ .getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
+ vpRanges.setViewportWidth(widthInRes);
+ }
+ else
+ {
+ int widthInRes = seqPanel.seqCanvas.getWidth()
+ / av.getCharWidth();
+ int heightInSeq = seqPanel.seqCanvas.getHeight()
+ / av.getCharHeight();
+
+ vpRanges.setViewportWidth(widthInRes);
+ vpRanges.setViewportHeight(heightInSeq);
+ }
+ // setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
if (getSize().height > 0
&& annotationPanelHolder.getSize().height > 0)
{
}
}
});
+ av.getRanges().addPropertyChangeListener(this);
}
@Override
annotationPanel.repaint();
validate();
repaint();
-
- if (overviewPanel != null)
- {
- overviewPanel.updateOverviewImage();
- }
}
public void setIdWidth(int w, int h)
}
else
{
- scrollToWrappedVisible(start);
- }
- if (redrawOverview && overviewPanel != null)
- {
- overviewPanel.setBoxPosition();
+ vpRanges.scrollToWrappedVisible(start);
}
+
paintAlignment(redrawOverview);
return true;
}
- void scrollToWrappedVisible(int res)
- {
- int cwidth = seqPanel.seqCanvas
- .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
- if (res <= vpRanges.getStartRes()
- || res >= (vpRanges.getStartRes() + cwidth))
- {
- vscroll.setValue(res / cwidth);
- vpRanges.setStartRes(vscroll.getValue() * cwidth);
- }
- }
-
public OverviewPanel getOverviewPanel()
{
return overviewPanel;
int vextent = 0;
- // return value is true if the scroll is valid
- public boolean scrollUp(boolean up)
+ public void setScrollValues(int xpos, int ypos)
{
- if (up)
+ int x = xpos;
+ int y = ypos;
+
+ if (av.getWrapAlignment())
{
- if (vscroll.getValue() < 1)
- {
- return false;
- }
- setScrollValues(hscroll.getValue(), vscroll.getValue() - 1);
+ setScrollingForWrappedPanel(x);
}
else
{
- if (vextent + vscroll.getValue() >= av.getAlignment().getHeight())
- {
- return false;
- }
- setScrollValues(hscroll.getValue(), vscroll.getValue() + 1);
- }
-
- repaint();
- return true;
- }
+ int width = av.getAlignment().getWidth();
+ int height = av.getAlignment().getHeight();
- public boolean scrollRight(boolean right)
- {
- if (!right)
- {
- if (hscroll.getValue() < 1)
+ if (av.hasHiddenColumns())
{
- return false;
+ width = av.getAlignment().getHiddenColumns()
+ .findColumnPosition(width);
}
- setScrollValues(hscroll.getValue() - 1, vscroll.getValue());
- }
- else
- {
- if (hextent + hscroll.getValue() >= av.getAlignment().getWidth())
+ if (x < 0)
{
- return false;
+ x = 0;
}
- setScrollValues(hscroll.getValue() + 1, vscroll.getValue());
- }
- repaint();
- return true;
- }
-
- public void setScrollValues(int x, int y)
- {
- int width = av.getAlignment().getWidth();
- int height = av.getAlignment().getHeight();
-
- if (av.hasHiddenColumns())
- {
- width = av.getAlignment().getHiddenColumns()
- .findColumnPosition(width);
- }
- if (x < 0)
- {
- x = 0;
- }
+ hextent = seqPanel.seqCanvas.getSize().width / av.getCharWidth();
+ vextent = seqPanel.seqCanvas.getSize().height / av.getCharHeight();
+ if (hextent > width)
+ {
+ hextent = width;
+ }
- hextent = seqPanel.seqCanvas.getSize().width / av.getCharWidth();
- vextent = seqPanel.seqCanvas.getSize().height / av.getCharHeight();
-
- if (hextent > width)
- {
- hextent = width;
- }
+ if (vextent > height)
+ {
+ vextent = height;
+ }
- if (vextent > height)
- {
- vextent = height;
- }
+ if ((hextent + x) > width)
+ {
+ System.err.println("hextent was " + hextent + " and x was " + x);
- if ((hextent + x) > width)
- {
- // System.err.println("hextent was " + hextent + " and x was " + x);
- //
- x = width - hextent;
- }
+ x = width - hextent;
+ }
- if ((vextent + y) > height)
- {
- y = height - vextent;
- }
+ if ((vextent + y) > height)
+ {
+ y = height - vextent;
+ }
- if (y < 0)
- {
- y = 0;
- }
+ if (y < 0)
+ {
+ y = 0;
+ }
- if (x < 0)
- {
- System.err.println("x was " + x);
- x = 0;
- }
+ if (x < 0)
+ {
+ System.err.println("x was " + x);
+ x = 0;
+ }
- vpRanges.setStartSeq(y);
- vpRanges.setEndSeq(y + vextent);
- vpRanges.setStartRes(x);
- vpRanges.setEndRes((x + (seqPanel.seqCanvas.getSize().width / av
- .getCharWidth())) - 1);
+ hscroll.setValues(x, hextent, 0, width);
+ vscroll.setValues(y, vextent, 0, height);
- hscroll.setValues(x, hextent, 0, width);
- vscroll.setValues(y, vextent, 0, height);
+ // AWT scrollbar does not fire adjustmentValueChanged for setValues
+ // so also call adjustment code!
+ adjustHorizontal(x);
+ adjustVertical(y);
- if (overviewPanel != null)
- {
- overviewPanel.setBoxPosition();
+ sendViewPosition();
}
- sendViewPosition();
-
}
+ /**
+ * Respond to adjustment event when horizontal or vertical scrollbar is
+ * changed
+ *
+ * @param evt
+ * adjustment event encoding whether apvscroll, hscroll or vscroll
+ * changed
+ */
@Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
- int oldX = vpRanges.getStartRes();
- int oldY = vpRanges.getStartSeq();
-
+ // Note that this event is NOT fired by the AWT scrollbar when setValues is
+ // called. Instead manually call adjustHorizontal and adjustVertical
+ // directly.
if (evt == null || evt.getSource() == apvscroll)
{
annotationPanel.setScrollOffset(apvscroll.getValue(), false);
alabels.setScrollOffset(apvscroll.getValue(), false);
- // annotationPanel.image=null;
- // alabels.image=null;
- // alabels.repaint();
- // annotationPanel.repaint();
}
if (evt == null || evt.getSource() == hscroll)
{
int x = hscroll.getValue();
- vpRanges.setStartRes(x);
- vpRanges.setEndRes(x + seqPanel.seqCanvas.getSize().width
- / av.getCharWidth() - 1);
+ adjustHorizontal(x);
}
if (evt == null || evt.getSource() == vscroll)
{
int offy = vscroll.getValue();
- if (av.getWrapAlignment())
- {
- int rowSize = seqPanel.seqCanvas
- .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
- vpRanges.setStartRes(vscroll.getValue() * rowSize);
- vpRanges.setEndRes((vscroll.getValue() + 1) * rowSize);
- }
- else
- {
- vpRanges.setStartSeq(offy);
- vpRanges.setEndSeq(offy + seqPanel.seqCanvas.getSize().height
- / av.getCharHeight() - 1);
- }
+ adjustVertical(offy);
}
- if (overviewPanel != null)
+ }
+
+ private void adjustHorizontal(int x)
+ {
+ int oldX = vpRanges.getStartRes();
+ int oldwidth = vpRanges.getViewportWidth();
+ int width = seqPanel.seqCanvas.getWidth() / av.getCharWidth();
+
+ // if we're scrolling to the position we're already at, stop
+ // this prevents infinite recursion of events when the scroll/viewport
+ // ranges values are the same
+ if ((x == oldX) && (width == oldwidth))
{
- overviewPanel.setBoxPosition();
+ return;
}
+ vpRanges.setViewportStartAndWidth(x, width);
- int scrollX = vpRanges.getStartRes() - oldX;
- int scrollY = vpRanges.getStartSeq() - oldY;
-
- if (av.getWrapAlignment() || !fastPaint || av.MAC)
+ if (av.getWrapAlignment() || !fastPaint)
{
repaint();
}
- else
+ sendViewPosition();
+ }
+
+ private void adjustVertical(int offy)
+ {
+ int oldX = vpRanges.getStartRes();
+ int oldwidth = vpRanges.getViewportWidth();
+ int oldY = vpRanges.getStartSeq();
+ int oldheight = vpRanges.getViewportHeight();
+
+ if (av.getWrapAlignment())
{
- // Make sure we're not trying to draw a panel
- // larger than the visible window
- if (scrollX > vpRanges.getEndRes() - vpRanges.getStartRes())
+ int rowSize = seqPanel.seqCanvas
+ .getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
+
+ // if we're scrolling to the position we're already at, stop
+ // this prevents infinite recursion of events when the scroll/viewport
+ // ranges values are the same
+ if ((offy * rowSize == oldX) && (oldwidth == rowSize))
{
- scrollX = vpRanges.getEndRes() - vpRanges.getStartRes();
+ return;
}
- else if (scrollX < vpRanges.getStartRes() - vpRanges.getEndRes())
+ else if (offy > -1)
{
- scrollX = vpRanges.getStartRes() - vpRanges.getEndRes();
+ vpRanges.setViewportStartAndWidth(offy * rowSize, rowSize);
}
+ }
+ else
+ {
+ int height = seqPanel.seqCanvas.getHeight() / av.getCharHeight();
- idPanel.idCanvas.fastPaint(scrollY);
- seqPanel.seqCanvas.fastPaint(scrollX, scrollY);
-
- scalePanel.repaint();
- if (av.isShowAnnotation())
+ // if we're scrolling to the position we're already at, stop
+ // this prevents infinite recursion of events when the scroll/viewport
+ // ranges values are the same
+ if ((offy == oldY) && (height == oldheight))
{
- annotationPanel.fastPaint(vpRanges.getStartRes() - oldX);
+ return;
}
+ vpRanges.setViewportStartAndHeight(offy, height);
}
- sendViewPosition();
-
- /*
- * If there is one, scroll the (Protein/cDNA) complementary alignment to
- * match, unless we are ourselves doing that.
- */
- if (isFollowingComplementScroll())
- {
- setFollowingComplementScroll(false);
- }
- else
+ if (av.getWrapAlignment() || !fastPaint)
{
- AlignmentPanel ap = getComplementPanel();
- av.scrollComplementaryAlignment(ap);
+ repaint();
}
-
+ sendViewPosition();
}
/**
* This is like AlignmentI.findIndex(seq) but here we are matching the
* dataset sequence not the aligned sequence
*/
- int sequenceIndex = 0;
boolean matched = false;
for (SequenceI seq : seqs)
{
matched = true;
break;
}
- sequenceIndex++;
}
if (!matched)
{
* Scroll to position but centring the target residue. Also set a state flag
* to prevent adjustmentValueChanged performing this recursively.
*/
- setFollowingComplementScroll(true);
- // this should be scrollToPosition(sr,verticalOffset,
scrollToPosition(sr, seqOffset, true, true);
}
idPanel.idCanvas.setSize(d.width, canvasHeight);
}
- if (av.getWrapAlignment())
- {
- int maxwidth = av.getAlignment().getWidth();
-
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
- }
-
- int canvasWidth = seqPanel.seqCanvas
- .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
-
- if (canvasWidth > 0)
- {
- int max = maxwidth / canvasWidth;
- vscroll.setMaximum(1 + max);
- vscroll.setUnitIncrement(1);
- vscroll.setVisibleAmount(1);
- }
- }
- else
- {
- setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
- }
+ setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
seqPanel.seqCanvas.repaint();
idPanel.idCanvas.repaint();
}
+ /*
+ * Set vertical scroll bar parameters for wrapped panel
+ * @param res
+ * the residue to scroll to
+ */
+ private void setScrollingForWrappedPanel(int res)
+ {
+ // get the width of the alignment in residues
+ int maxwidth = av.getAlignment().getWidth();
+ if (av.hasHiddenColumns())
+ {
+ maxwidth = av.getAlignment().getHiddenColumns()
+ .findColumnPosition(maxwidth) - 1;
+ }
+
+ // get the width of the canvas in residues
+ int canvasWidth = seqPanel.seqCanvas
+ .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
+ if (canvasWidth > 0)
+ {
+ // position we want to scroll to is number of canvasWidth's to get there
+ int current = res / canvasWidth;
+
+ // max scroll position: add one because extent is 1 and scrollbar value
+ // can only be set to at most max - extent
+ int max = maxwidth / canvasWidth + 1;
+ vscroll.setUnitIncrement(1);
+ vscroll.setValues(current, 1, 0, max);
+ }
+ }
+
protected Panel sequenceHolderPanel = new Panel();
protected Scrollbar vscroll = new Scrollbar();
/*
* Flag set while scrolling to follow complementary cDNA/protein scroll. When
- * true, suppresses invoking the same method recursively.
+ * false, suppresses invoking the same method recursively.
*/
- private boolean followingComplementScroll;
+ private boolean scrollComplementaryPanel = true;
private void jbInit() throws Exception
{
*
* @param b
*/
- protected void setFollowingComplementScroll(boolean b)
+ protected void setToScrollComplementPanel(boolean b)
+ {
+ this.scrollComplementaryPanel = b;
+ }
+
+ /**
+ * Get whether to scroll complement panel
+ *
+ * @return true if cDNA/protein complement panels should be scrolled
+ */
+ protected boolean isSetToScrollComplementPanel()
{
- this.followingComplementScroll = b;
+ return this.scrollComplementaryPanel;
}
- protected boolean isFollowingComplementScroll()
+ @Override
+ /**
+ * Property change event fired when a change is made to the viewport ranges
+ * object associated with this alignment panel's viewport
+ */
+ public void propertyChange(PropertyChangeEvent evt)
{
- return this.followingComplementScroll;
+ // update this panel's scroll values based on the new viewport ranges values
+ int x = vpRanges.getStartRes();
+ int y = vpRanges.getStartSeq();
+ setScrollValues(x, y);
+
+ // now update any complementary alignment (its viewport ranges object
+ // is different so does not get automatically updated)
+ if (isSetToScrollComplementPanel())
+ {
+ setToScrollComplementPanel(false);
+ av.scrollComplementaryAlignment(getComplementPanel());
+ setToScrollComplementPanel(true);
+ }
+
}
}
import jalview.util.Comparison;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import jalview.viewmodel.ViewportListenerI;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
+import java.beans.PropertyChangeEvent;
public class AnnotationPanel extends Panel implements AwtRenderPanelI,
AdjustmentListener, ActionListener, MouseListener,
- MouseMotionListener
+ MouseMotionListener, ViewportListenerI
{
AlignViewport av;
{
this.av = av;
renderer = new AnnotationRenderer();
+ av.getRanges().addPropertyChangeListener(this);
}
@Override
return null;
}
}
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // Respond to viewport range changes (e.g. alignment panel was scrolled)
+ if (evt.getPropertyName().equals("startres")
+ || evt.getPropertyName().equals("endres"))
+ {
+ fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ }
}
package jalview.appletgui;
import jalview.datamodel.SequenceI;
+import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
+import java.beans.PropertyChangeEvent;
import java.util.List;
-public class IdCanvas extends Panel
+public class IdCanvas extends Panel implements ViewportListenerI
{
protected AlignViewport av;
setLayout(null);
this.av = av;
PaintRefresher.Register(this, av.getSequenceSetId());
+ av.getRanges().addPropertyChangeListener(this);
}
public void drawIdString(Graphics gg, boolean hiddenRows, SequenceI s,
}
return false;
}
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // Respond to viewport range changes (e.g. alignment panel was scrolled)
+ if (evt.getPropertyName().equals("startseq")
+ || evt.getPropertyName().equals("endseq"))
+ {
+ fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ }
}
if (av.getRanges().getStartSeq() > index
|| av.getRanges().getEndSeq() < index)
{
- alignPanel.setScrollValues(av.getRanges().getStartRes(), index);
+ av.getRanges().setStartSeq(index);
}
}
running = true;
while (running)
{
- if (alignPanel.scrollUp(up))
+ if (av.getRanges().scrollUp(up))
{
// scroll was ok, so add new sequence to selection
int seq = av.getRanges().getStartSeq();
import jalview.viewmodel.OverviewDimensions;
import jalview.viewmodel.OverviewDimensionsHideHidden;
import jalview.viewmodel.OverviewDimensionsShowHidden;
+import jalview.viewmodel.ViewportListenerI;
import java.awt.BorderLayout;
import java.awt.CheckboxMenuItem;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
+import java.beans.PropertyChangeEvent;
public class OverviewPanel extends Panel implements Runnable,
- MouseMotionListener, MouseListener
+ MouseMotionListener, MouseListener, ViewportListenerI
{
private OverviewDimensions od;
add(oviewCanvas, BorderLayout.CENTER);
setSize(new Dimension(od.getWidth(), od.getHeight()));
+
+ av.getRanges().addPropertyChangeListener(this);
+
addComponentListener(new ComponentAdapter()
{
{
od.updateViewportFromMouse(evt.getX(), evt.getY(), av.getAlignment()
.getHiddenSequences(), av.getAlignment().getHiddenColumns());
- ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
ap.paintAlignment(false);
}
}
* changed
*
*/
- public void setBoxPosition()
+ private void setBoxPosition()
{
od.setBoxPosition(av.getAlignment()
.getHiddenSequences(), av
popup.show(this, e.getX(), e.getY());
}
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ setBoxPosition();
+ }
+
/*
* Toggle overview display between showing hidden columns and hiding hidden columns
*/
import jalview.renderer.ScaleRenderer;
import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.util.MessageManager;
+import jalview.viewmodel.ViewportListenerI;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
+import java.beans.PropertyChangeEvent;
import java.util.List;
public class ScalePanel extends Panel implements MouseMotionListener,
- MouseListener
+ MouseListener, ViewportListenerI
{
protected int offy = 4;
addMouseListener(this);
addMouseMotionListener(this);
+ av.getRanges().addPropertyChangeListener(this);
}
@Override
}
}
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // Respond to viewport change events (e.g. alignment panel was scrolled)
+ repaint();
+ }
+
}
import jalview.renderer.ScaleRenderer;
import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.viewmodel.AlignmentViewport;
+import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
+import java.beans.PropertyChangeEvent;
-public class SeqCanvas extends Panel
+public class SeqCanvas extends Panel implements ViewportListenerI
{
FeatureRenderer fr;
sr = new SequenceRenderer(av);
PaintRefresher.Register(this, av.getSequenceSetId());
updateViewport();
+
+ av.getRanges().addPropertyChangeListener(this);
}
int avcharHeight = 0, avcharWidth = 0;
av.setWrappedWidth(cWidth);
- av.getRanges().setEndRes(av.getRanges().getStartRes() + cWidth);
+ av.getRanges().setEndRes(av.getRanges().getStartRes() + cWidth - 1);
int endx;
int ypos = hgap;
repaint();
}
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if (!av.getWrapAlignment())
+ {
+ if (evt.getPropertyName().equals("startres")
+ || evt.getPropertyName().equals("endres"))
+ {
+ // Make sure we're not trying to draw a panel
+ // larger than the visible window
+ ViewportRanges vpRanges = av.getRanges();
+ int scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ if (scrollX > vpRanges.getEndRes() - vpRanges.getStartRes())
+ {
+ scrollX = vpRanges.getEndRes() - vpRanges.getStartRes();
+ }
+ else if (scrollX < vpRanges.getStartRes() - vpRanges.getEndRes())
+ {
+ scrollX = vpRanges.getStartRes() - vpRanges.getEndRes();
+ }
+ fastPaint(scrollX, 0);
+ }
+ else if (evt.getPropertyName().equals("startseq")
+ || evt.getPropertyName().equals("endseq"))
+ {
+ fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ }
+
+ }
+
}
endEditing();
if (av.getWrapAlignment())
{
- ap.scrollToWrappedVisible(seqCanvas.cursorX);
+ av.getRanges().scrollToWrappedVisible(seqCanvas.cursorX);
}
else
{
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
while (seqCanvas.cursorY < ranges.getStartSeq())
{
- ap.scrollUp(true);
+ ranges.scrollUp(true);
}
while (seqCanvas.cursorY + 1 > ranges.getEndSeq())
{
- ap.scrollUp(false);
+ ranges.scrollUp(false);
}
while (seqCanvas.cursorX < hidden.adjustForHiddenColumns(ranges
.getStartRes()))
{
- if (!ap.scrollRight(false))
+ if (!ranges.scrollRight(false))
{
break;
}
while (seqCanvas.cursorX > hidden.adjustForHiddenColumns(ranges
.getEndRes()))
{
- if (!ap.scrollRight(true))
+ if (!ranges.scrollRight(true))
{
break;
}
{
if (av.isFollowHighlight())
{
+ // don't allow highlight of protein/cDNA to also scroll a complementary
+ // panel,as this sets up a feedback loop (scrolling panel 1 causes moused
+ // over residue to change abruptly, causing highlighted residue in panel 2
+ // to change, causing a scroll in panel 1 etc)
+ ap.setToScrollComplementPanel(false);
if (ap.scrollToPosition(results, true))
{
ap.alignFrame.repaint();
}
+ ap.setToScrollComplementPanel(true);
}
setStatusMessage(results);
seqCanvas.highlightSearchResults(results);
if (mouseDragging && evt.getY() < 0
&& av.getRanges().getStartSeq() > 0)
{
- running = ap.scrollUp(true);
+ running = av.getRanges().scrollUp(true);
}
if (mouseDragging && evt.getY() >= getSize().height
&& av.getAlignment().getHeight() > av.getRanges()
.getEndSeq())
{
- running = ap.scrollUp(false);
+ running = av.getRanges().scrollUp(false);
}
if (mouseDragging && evt.getX() < 0)
{
- running = ap.scrollRight(false);
+ running = av.getRanges().scrollRight(false);
}
else if (mouseDragging && evt.getX() >= getSize().width)
{
- running = ap.scrollRight(true);
+ running = av.getRanges().scrollRight(true);
}
}
case KeyEvent.VK_PAGE_UP:
if (viewport.getWrapAlignment())
{
- alignPanel.scrollUp(true);
+ vpRanges.scrollUp(true);
}
else
{
- alignPanel.setScrollValues(vpRanges.getStartRes(),
- 2 * vpRanges.getStartSeq() - vpRanges.getEndSeq());
+ vpRanges.pageUp();
}
break;
case KeyEvent.VK_PAGE_DOWN:
if (viewport.getWrapAlignment())
{
- alignPanel.scrollUp(false);
+ vpRanges.scrollUp(false);
}
else
{
- alignPanel.setScrollValues(vpRanges.getStartRes(),
- vpRanges.getEndSeq());
+ vpRanges.pageDown();
}
break;
}
// TODO would like next line without cast but needs more refactoring...
final AlignmentPanel complementPanel = ((AlignViewport) getCodingComplement())
.getAlignPanel();
- complementPanel.setDontScrollComplement(true);
+ complementPanel.setToScrollComplementPanel(false);
complementPanel.scrollToCentre(sr, verticalOffset);
+ complementPanel.setToScrollComplementPanel(true);
}
}
import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import java.awt.BorderLayout;
import java.awt.Insets;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
* @version $Revision: 1.161 $
*/
public class AlignmentPanel extends GAlignmentPanel implements
- AdjustmentListener, Printable, AlignmentViewPanel
+ AdjustmentListener, Printable, AlignmentViewPanel,
+ ViewportListenerI
{
public AlignViewport av;
/*
* Flag set while scrolling to follow complementary cDNA/protein scroll. When
- * true, suppresses invoking the same method recursively.
+ * false, suppresses invoking the same method recursively.
*/
- private boolean dontScrollComplement;
+ private boolean scrollComplementaryPanel = true;
private PropertyChangeListener propertyChangeListener;
hscroll.addAdjustmentListener(this);
vscroll.addAdjustmentListener(this);
+ addComponentListener(new ComponentAdapter()
+ {
+ @Override
+ public void componentResized(ComponentEvent evt)
+ {
+ // reset the viewport ranges when the alignment panel is resized
+ // in particular, this initialises the end residue value when Jalview
+ // is initialised
+ if (av.getWrapAlignment())
+ {
+ int widthInRes = getSeqPanel().seqCanvas
+ .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
+ vpRanges.setViewportWidth(widthInRes);
+ }
+ else
+ {
+ int widthInRes = getSeqPanel().seqCanvas.getWidth()
+ / av.getCharWidth();
+ int heightInSeq = getSeqPanel().seqCanvas.getHeight()
+ / av.getCharHeight();
+
+ vpRanges.setViewportWidth(widthInRes);
+ vpRanges.setViewportHeight(heightInSeq);
+ }
+ }
+
+ });
+
final AlignmentPanel ap = this;
propertyChangeListener = new PropertyChangeListener()
{
}
};
av.addPropertyChangeListener(propertyChangeListener);
+
+ av.getRanges().addPropertyChangeListener(this);
fontChanged();
adjustAnnotationHeight();
updateLayout();
getIdPanel().getIdCanvas().setPreferredSize(d);
hscrollFillerPanel.setPreferredSize(d);
- if (overviewPanel != null)
- {
- overviewPanel.setBoxPosition();
- }
if (this.alignFrame.getSplitViewContainer() != null)
{
((SplitFrame) this.alignFrame.getSplitViewContainer()).adjustLayout();
}
int start = r[0];
int end = r[1];
- // DEBUG
- // System.err.println(this.av.viewName + " Seq : " + seqIndex
- // + " Scroll to " + start + "," + end);
/*
* To centre results, scroll to positions half the visible width
*/
seqIndex = Math.max(0, seqIndex - verticalOffset);
- // System.out.println("start=" + start + ", end=" + end + ", startv="
- // + av.getStartRes() + ", endv=" + av.getEndRes() + ", starts="
- // + av.getStartSeq() + ", ends=" + av.getEndSeq());
if (!av.getWrapAlignment())
{
if ((startv = vpRanges.getStartRes()) >= start)
/*
* Scroll left to make start of search results visible
*/
- // setScrollValues(start - 1, seqIndex); // plus one residue
setScrollValues(start, seqIndex);
}
else if ((endv = vpRanges.getEndRes()) <= end)
/*
* Scroll right to make end of search results visible
*/
- // setScrollValues(startv + 1 + end - endv, seqIndex); // plus one
setScrollValues(startv + end - endv, seqIndex);
}
else if ((starts = vpRanges.getStartSeq()) > seqIndex)
}
else
{
- scrollToWrappedVisible(start);
+ vpRanges.scrollToWrappedVisible(start);
}
}
- if (redrawOverview && overviewPanel != null)
- {
- overviewPanel.setBoxPosition();
- }
+
paintAlignment(redrawOverview);
return true;
}
- void scrollToWrappedVisible(int res)
- {
- int cwidth = getSeqPanel().seqCanvas
- .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
- if (res < vpRanges.getStartRes()
- || res >= (vpRanges.getStartRes() + cwidth))
- {
- vscroll.setValue((res / cwidth));
- vpRanges.setStartRes(vscroll.getValue() * cwidth);
- }
-
- }
-
/**
* DOCUMENT ME!
*
annotationSpaceFillerHolder.setVisible(true);
}
- idSpaceFillerPanel1.setVisible(!wrap);
-
- repaint();
- }
-
- // return value is true if the scroll is valid
- public boolean scrollUp(boolean up)
- {
- if (up)
+ if (wrap)
{
- if (vscroll.getValue() < 1)
- {
- return false;
- }
-
- fastPaint = false;
- vscroll.setValue(vscroll.getValue() - 1);
+ int widthInRes = getSeqPanel().seqCanvas
+ .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
+ vpRanges.setViewportWidth(widthInRes);
}
else
{
- if ((vextent + vscroll.getValue()) >= av.getAlignment().getHeight())
- {
- return false;
- }
+ int widthInRes = (getSeqPanel().seqCanvas.getWidth() / av
+ .getCharWidth()) - 1;
+ int heightInSeq = (getSeqPanel().seqCanvas.getHeight() / av
+ .getCharHeight()) - 1;
- fastPaint = false;
- vscroll.setValue(vscroll.getValue() + 1);
+ vpRanges.setViewportWidth(widthInRes);
+ vpRanges.setViewportHeight(heightInSeq);
}
- fastPaint = true;
+ idSpaceFillerPanel1.setVisible(!wrap);
- return true;
+ repaint();
}
- /**
- * DOCUMENT ME!
- *
- * @param right
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public boolean scrollRight(boolean right)
- {
- if (!right)
- {
- if (hscroll.getValue() < 1)
- {
- return false;
- }
-
- fastPaint = false;
- hscroll.setValue(hscroll.getValue() - 1);
- }
- else
- {
- if ((hextent + hscroll.getValue()) >= av.getAlignment().getWidth())
- {
- return false;
- }
-
- fastPaint = false;
- hscroll.setValue(hscroll.getValue() + 1);
- }
-
- fastPaint = true;
-
- return true;
- }
/**
* Adjust row/column scrollers to show a visible position in the alignment.
* visible row to scroll to
*
*/
- public void setScrollValues(int x, int y)
+ public void setScrollValues(int xpos, int ypos)
{
+ int x = xpos;
+ int y = ypos;
+
if (av == null || av.getAlignment() == null)
{
return;
}
- int width = av.getAlignment().getWidth();
- int height = av.getAlignment().getHeight();
- if (av.hasHiddenColumns())
+ if (av.getWrapAlignment())
{
- // reset the width to exclude hidden columns
- width = av.getAlignment().getHiddenColumns()
- .findColumnPosition(width);
+ setScrollingForWrappedPanel(x);
}
+ else
+ {
+ int width = av.getAlignment().getWidth();
+ int height = av.getAlignment().getHeight();
- hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
- vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
+ if (av.hasHiddenColumns())
+ {
+ // reset the width to exclude hidden columns
+ width = av.getAlignment().getHiddenColumns().findColumnPosition(width);
+ }
- if (hextent > width)
- {
- hextent = width;
- }
+ hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
+ vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
- if (vextent > height)
- {
- vextent = height;
- }
+ if (hextent > width)
+ {
+ hextent = width;
+ }
- if ((hextent + x) > width)
- {
- x = width - hextent;
- }
+ if (vextent > height)
+ {
+ vextent = height;
+ }
- if ((vextent + y) > height)
- {
- y = height - vextent;
- }
+ if ((hextent + x) > width)
+ {
+ x = width - hextent;
+ }
- if (y < 0)
- {
- y = 0;
- }
+ if ((vextent + y) > height)
+ {
+ y = height - vextent;
+ }
- if (x < 0)
- {
- x = 0;
- }
+ if (y < 0)
+ {
+ y = 0;
+ }
- // update endRes after x has (possibly) been adjusted
- vpRanges.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av
- .getCharWidth())) - 1);
+ if (x < 0)
+ {
+ x = 0;
+ }
- /*
- * each scroll adjustment triggers adjustmentValueChanged, which resets the
- * 'do not scroll complement' flag; ensure it is the same for both
- * operations
- */
- boolean flag = isDontScrollComplement();
- hscroll.setValues(x, hextent, 0, width);
- setDontScrollComplement(flag);
- vscroll.setValues(y, vextent, 0, height);
+ // update the scroll values
+ hscroll.setValues(x, hextent, 0, width);
+ vscroll.setValues(y, vextent, 0, height);
+ }
}
/**
- * DOCUMENT ME!
+ * Respond to adjustment event when horizontal or vertical scrollbar is
+ * changed
*
* @param evt
- * DOCUMENT ME!
+ * adjustment event encoding whether hscroll or vscroll changed
*/
@Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
int oldX = vpRanges.getStartRes();
+ int oldwidth = vpRanges.getViewportWidth();
int oldY = vpRanges.getStartSeq();
+ int oldheight = vpRanges.getViewportHeight();
- if (evt.getSource() == hscroll)
- {
- int x = hscroll.getValue();
- vpRanges.setStartRes(x);
- vpRanges.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av
- .getCharWidth())) - 1);
- }
-
- if (evt.getSource() == vscroll)
+ if (av.getWrapAlignment())
{
- int offy = vscroll.getValue();
-
- if (av.getWrapAlignment())
+ if (evt.getSource() == hscroll)
{
- if (offy > -1)
+ return; // no horizontal scroll when wrapped
+ }
+ else if (evt.getSource() == vscroll)
+ {
+ int offy = vscroll.getValue();
+ int rowSize = getSeqPanel().seqCanvas
+ .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
+
+ // if we're scrolling to the position we're already at, stop
+ // this prevents infinite recursion of events when the scroll/viewport
+ // ranges values are the same
+ if ((offy * rowSize == oldX) && (oldwidth == rowSize))
{
- int rowSize = getSeqPanel().seqCanvas
- .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
- vpRanges.setStartRes(offy * rowSize);
- vpRanges.setEndRes((offy + 1) * rowSize);
+ return;
}
- else
+ else if (offy > -1)
{
- // This is only called if file loaded is a jar file that
- // was wrapped when saved and user has wrap alignment true
- // as preference setting
- SwingUtilities.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- setScrollValues(vpRanges.getStartRes(),
- vpRanges.getStartSeq());
- }
- });
+ vpRanges.setViewportStartAndWidth(offy * rowSize, rowSize);
}
}
else
{
- vpRanges.setStartSeq(offy);
- vpRanges.setEndSeq(offy
- + (getSeqPanel().seqCanvas.getHeight() / av.getCharHeight())
- - 1);
+ // This is only called if file loaded is a jar file that
+ // was wrapped when saved and user has wrap alignment true
+ // as preference setting
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ // When updating scrolling to use ViewportChange events, this code
+ // could not be validated and it is not clear if it is now being
+ // called. Log warning here in case it is called and unforeseen
+ // problems occur
+ Cache.log
+ .warn("Unexpected path through code: Wrapped jar file opened with wrap alignment set in preferences");
+
+ // scroll to start of panel
+ vpRanges.setStartRes(0);
+ vpRanges.setStartSeq(0);
+ }
+ });
}
- }
-
- if (overviewPanel != null)
- {
- overviewPanel.setBoxPosition();
- }
-
- int scrollX = vpRanges.getStartRes() - oldX;
- int scrollY = vpRanges.getStartSeq() - oldY;
-
- if (av.getWrapAlignment() || !fastPaint)
- {
repaint();
}
else
{
- // Make sure we're not trying to draw a panel
- // larger than the visible window
- if (scrollX > vpRanges.getEndRes() - vpRanges.getStartRes())
+ // horizontal scroll
+ if (evt.getSource() == hscroll)
{
- scrollX = vpRanges.getEndRes() - vpRanges.getStartRes();
- }
- else if (scrollX < vpRanges.getStartRes() - vpRanges.getEndRes())
- {
- scrollX = vpRanges.getStartRes() - vpRanges.getEndRes();
- }
+ int x = hscroll.getValue();
+ int width = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
- if (scrollX != 0 || scrollY != 0)
+ // if we're scrolling to the position we're already at, stop
+ // this prevents infinite recursion of events when the scroll/viewport
+ // ranges values are the same
+ if ((x == oldX) && (width == oldwidth))
+ {
+ return;
+ }
+ vpRanges.setViewportStartAndWidth(x, width);
+ }
+ else if (evt.getSource() == vscroll)
{
- getIdPanel().getIdCanvas().fastPaint(scrollY);
- getSeqPanel().seqCanvas.fastPaint(scrollX, scrollY);
- getScalePanel().repaint();
-
- if (av.isShowAnnotation() && scrollX != 0)
+ int y = vscroll.getValue();
+ int height = getSeqPanel().seqCanvas.getHeight()
+ / av.getCharHeight();
+
+ // if we're scrolling to the position we're already at, stop
+ // this prevents infinite recursion of events when the scroll/viewport
+ // ranges values are the same
+ if ((y == oldY) && (height == oldheight))
{
- getAnnotationPanel().fastPaint(scrollX);
+ return;
}
+ vpRanges.setViewportStartAndHeight(y, height);
+ }
+ if (!fastPaint)
+ {
+ repaint();
}
- }
- /*
- * If there is one, scroll the (Protein/cDNA) complementary alignment to
- * match, unless we are ourselves doing that.
- */
- if (isDontScrollComplement())
- {
- setDontScrollComplement(false);
- }
- else
- {
- av.scrollComplementaryAlignment();
}
}
validate();
/*
- * set scroll bar positions; first suppress this being 'followed' in any
- * complementary split pane
+ * set scroll bar positions
*/
- setDontScrollComplement(true);
+ setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
+ }
- if (av.getWrapAlignment())
+ /*
+ * Set vertical scroll bar parameters for wrapped panel
+ * @param res
+ * the residue to scroll to
+ */
+ private void setScrollingForWrappedPanel(int res)
+ {
+ // get the width of the alignment in residues
+ int maxwidth = av.getAlignment().getWidth();
+ if (av.hasHiddenColumns())
{
- int maxwidth = av.getAlignment().getWidth();
-
- if (av.hasHiddenColumns())
- {
maxwidth = av.getAlignment().getHiddenColumns()
.findColumnPosition(maxwidth) - 1;
- }
-
- int canvasWidth = getSeqPanel().seqCanvas
- .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
- if (canvasWidth > 0)
- {
- int max = maxwidth
- / getSeqPanel().seqCanvas
- .getWrappedCanvasWidth(getSeqPanel().seqCanvas
- .getWidth()) + 1;
- vscroll.setMaximum(max);
- vscroll.setUnitIncrement(1);
- vscroll.setVisibleAmount(1);
- }
}
- else
+
+ // get the width of the canvas in residues
+ int canvasWidth = getSeqPanel().seqCanvas
+ .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
+ if (canvasWidth > 0)
{
- setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
+ // position we want to scroll to is number of canvasWidth's to get there
+ int current = res / canvasWidth;
+
+ // max scroll position: add one because extent is 1 and scrollbar value
+ // can only be set to at most max - extent
+ int max = maxwidth / canvasWidth + 1;
+ vscroll.setUnitIncrement(1);
+ vscroll.setValues(current, 1, 0, max);
}
}
*
* @param b
*/
- protected void setDontScrollComplement(boolean b)
+ protected void setToScrollComplementPanel(boolean b)
{
- this.dontScrollComplement = b;
+ this.scrollComplementaryPanel = b;
}
- protected boolean isDontScrollComplement()
+ /**
+ * Get whether to scroll complement panel
+ *
+ * @return true if cDNA/protein complement panels should be scrolled
+ */
+ protected boolean isSetToScrollComplementPanel()
{
- return this.dontScrollComplement;
+ return this.scrollComplementaryPanel;
}
/**
}
}
+ @Override
+ /**
+ * Property change event fired when a change is made to the viewport ranges
+ * object associated with this alignment panel's viewport
+ */
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // update this panel's scroll values based on the new viewport ranges values
+ int x = vpRanges.getStartRes();
+ int y = vpRanges.getStartSeq();
+ setScrollValues(x, y);
+
+ // now update any complementary alignment (its viewport ranges object
+ // is different so does not get automatically updated)
+ if (isSetToScrollComplementPanel())
+ {
+ setToScrollComplementPanel(false);
+ av.scrollComplementaryAlignment();
+ setToScrollComplementPanel(true);
+ }
+ }
+
/**
* Set the reference to the PCA/Tree chooser dialog for this panel. This
* reference should be nulled when the dialog is closed.
import jalview.schemes.ResidueProperties;
import jalview.util.Comparison;
import jalview.util.MessageManager;
+import jalview.viewmodel.ViewportListenerI;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
*/
public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
MouseListener, MouseWheelListener, MouseMotionListener,
- ActionListener, AdjustmentListener, Scrollable
+ ActionListener, AdjustmentListener, Scrollable, ViewportListenerI
{
String HELIX = MessageManager.getString("label.helix");
// and then set our own listener to consume all mousewheel events
ap.annotationScroller.addMouseWheelListener(this);
renderer = new AnnotationRenderer();
+
+ av.getRanges().addPropertyChangeListener(this);
}
public AnnotationPanel(AlignViewport av)
e.consume();
if (e.getWheelRotation() > 0)
{
- ap.scrollRight(true);
+ av.getRanges().scrollRight(true);
}
else
{
- ap.scrollRight(false);
+ av.getRanges().scrollRight(false);
}
}
else
renderer.dispose();
}
}
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // Respond to viewport range changes (e.g. alignment panel was scrolled)
+ if (evt.getPropertyName().equals("startres")
+ || evt.getPropertyName().equals("endres"))
+ {
+ fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ }
}
package jalview.gui;
import jalview.datamodel.SequenceI;
+import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
import java.util.List;
import javax.swing.JPanel;
* @author $author$
* @version $Revision$
*/
-public class IdCanvas extends JPanel
+public class IdCanvas extends JPanel implements ViewportListenerI
{
protected AlignViewport av;
setLayout(new BorderLayout());
this.av = av;
PaintRefresher.Register(this, av.getSequenceSetId());
+ av.getRanges().addPropertyChangeListener(this);
}
/**
{
this.idfont = idfont;
}
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // Respond to viewport range changes (e.g. alignment panel was scrolled)
+ if (evt.getPropertyName().equals("startseq")
+ || evt.getPropertyName().equals("endseq"))
+ {
+ fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ }
}
{
if (e.isShiftDown())
{
- alignPanel.scrollRight(true);
+ av.getRanges().scrollRight(true);
}
else
{
- alignPanel.scrollUp(false);
+ av.getRanges().scrollUp(false);
}
}
else
{
if (e.isShiftDown())
{
- alignPanel.scrollRight(false);
+ av.getRanges().scrollRight(false);
}
else
{
- alignPanel.scrollUp(true);
+ av.getRanges().scrollUp(true);
}
}
}
if ((av.getRanges().getStartSeq() > index)
|| (av.getRanges().getEndSeq() < index))
{
- alignPanel.setScrollValues(av.getRanges().getStartRes(), index);
+ av.getRanges().setStartSeq(index);
}
}
while (running)
{
- if (alignPanel.scrollUp(up))
+ if (av.getRanges().scrollUp(up))
{
// scroll was ok, so add new sequence to selection
int seq = av.getRanges().getStartSeq();
af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
.isShowUnconserved() : false);
af.viewport.getRanges().setStartRes(view.getStartRes());
- af.viewport.getRanges().setStartSeq(view.getStartSeq());
+ // startSeq set in af.alignPanel.updateLayout below
af.alignPanel.updateLayout();
ColourSchemeI cs = null;
// apply colourschemes
af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
view.getHeight());
af.viewport.getRanges().setStartRes(view.getStartRes());
- af.viewport.getRanges().setStartSeq(view.getStartSeq());
+ // startSeq set in af.alignPanel.updateLayout below
af.viewport.setShowAnnotation(view.getShowAnnotation());
af.viewport.setAbovePIDThreshold(view.getPidSelected());
af.viewport.setColourText(view.getShowColourText());
import jalview.viewmodel.OverviewDimensions;
import jalview.viewmodel.OverviewDimensionsHideHidden;
import jalview.viewmodel.OverviewDimensionsShowHidden;
+import jalview.viewmodel.ViewportListenerI;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
+import java.beans.PropertyChangeEvent;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JPanel;
* @author $author$
* @version $Revision$
*/
-public class OverviewPanel extends JPanel implements Runnable
+public class OverviewPanel extends JPanel implements Runnable,
+ ViewportListenerI
{
private OverviewDimensions od;
setLayout(new BorderLayout());
add(oviewCanvas, BorderLayout.CENTER);
+ av.getRanges().addPropertyChangeListener(this);
+
addComponentListener(new ComponentAdapter()
{
@Override
|| (getHeight() != (od.getHeight())))
{
updateOverviewImage();
+ setBoxPosition();
}
}
});
od.updateViewportFromMouse(evt.getX(), evt.getY(), av
.getAlignment().getHiddenSequences(), av.getAlignment()
.getHiddenColumns());
- ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
+
}
}
});
od.updateViewportFromMouse(evt.getX(), evt.getY(), av
.getAlignment().getHiddenSequences(), av.getAlignment()
.getHiddenColumns());
- ap.setScrollValues(od.getScrollCol(), od.getScrollRow());
}
}
}
oviewCanvas.resetOviewDims(od);
updateOverviewImage();
+ setBoxPosition();
}
/**
* changed
*
*/
- public void setBoxPosition()
+ private void setBoxPosition()
{
od.setBoxPosition(av.getAlignment().getHiddenSequences(), av
.getAlignment().getHiddenColumns());
repaint();
}
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ setBoxPosition();
+ }
}
import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.util.MessageManager;
import jalview.util.Platform;
+import jalview.viewmodel.ViewportListenerI;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
+import java.beans.PropertyChangeEvent;
import java.util.List;
import javax.swing.JMenuItem;
* supports a range of mouse operations to select, hide or reveal columns.
*/
public class ScalePanel extends JPanel implements MouseMotionListener,
- MouseListener
+ MouseListener, ViewportListenerI
{
protected int offy = 4;
addMouseListener(this);
addMouseMotionListener(this);
+
+ av.getRanges().addPropertyChangeListener(this);
}
/**
}
}
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ // Respond to viewport change events (e.g. alignment panel was scrolled)
+ repaint();
+ }
+
}
import jalview.datamodel.SequenceI;
import jalview.renderer.ScaleRenderer;
import jalview.renderer.ScaleRenderer.ScaleMark;
+import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import java.awt.BasicStroke;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
import java.util.List;
import javax.swing.JComponent;
* @author $author$
* @version $Revision$
*/
-public class SeqCanvas extends JComponent
+public class SeqCanvas extends JComponent implements ViewportListenerI
{
final FeatureRenderer fr;
setLayout(new BorderLayout());
PaintRefresher.Register(this, av.getSequenceSetId());
setBackground(Color.white);
+
+ av.getRanges().addPropertyChangeListener(this);
}
public SequenceRenderer getSequenceRenderer()
if (horizontal > 0) // scrollbar pulled right, image to the left
{
- er++;
transX = (er - sr - horizontal) * charWidth;
sr = er - horizontal;
}
else if (horizontal < 0)
{
- er = sr - horizontal - 1;
+ er = sr - horizontal;
}
else if (vertical > 0) // scroll down
{
av.setWrappedWidth(cWidth);
- av.getRanges().setEndRes(av.getRanges().getStartRes() + cWidth);
+ av.getRanges().setEndRes(av.getRanges().getStartRes() + cWidth - 1);
int endx;
int ypos = hgap;
repaint();
}
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if (!av.getWrapAlignment())
+ {
+ if (evt.getPropertyName().equals("startres")
+ || evt.getPropertyName().equals("endres"))
+ {
+ // Make sure we're not trying to draw a panel
+ // larger than the visible window
+ ViewportRanges vpRanges = av.getRanges();
+ int scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ if (scrollX > vpRanges.getEndRes() - vpRanges.getStartRes())
+ {
+ scrollX = vpRanges.getEndRes() - vpRanges.getStartRes();
+ }
+ else if (scrollX < vpRanges.getStartRes() - vpRanges.getEndRes())
+ {
+ scrollX = vpRanges.getStartRes() - vpRanges.getEndRes();
+ }
+ fastPaint(scrollX, 0);
+ }
+ else if (evt.getPropertyName().equals("startseq")
+ || evt.getPropertyName().equals("endseq"))
+ {
+ fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ }
+ }
}
endEditing();
if (av.getWrapAlignment())
{
- ap.scrollToWrappedVisible(seqCanvas.cursorX);
+ av.getRanges().scrollToWrappedVisible(seqCanvas.cursorX);
}
else
{
- while (seqCanvas.cursorY < av.getRanges().getStartSeq())
- {
- ap.scrollUp(true);
- }
- while (seqCanvas.cursorY > av.getRanges().getEndSeq())
- {
- ap.scrollUp(false);
- }
- if (!av.getWrapAlignment())
- {
- HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- while (seqCanvas.cursorX < hidden.adjustForHiddenColumns(av
- .getRanges().getStartRes()))
- {
- if (!ap.scrollRight(false))
- {
- break;
- }
- }
- while (seqCanvas.cursorX > hidden.adjustForHiddenColumns(av
- .getRanges().getEndRes()))
- {
- if (!ap.scrollRight(true))
- {
- break;
- }
- }
- }
+ av.getRanges().scrollToVisible(seqCanvas.cursorX, seqCanvas.cursorY,
+ av);
}
setStatusMessage(av.getAlignment().getSequenceAt(seqCanvas.cursorY),
seqCanvas.cursorX, seqCanvas.cursorY);
if (av.isFollowHighlight())
{
- /*
- * if scrollToPosition requires a scroll adjustment, this flag prevents
- * another scroll event being propagated back to the originator
- *
- * @see AlignmentPanel#adjustmentValueChanged
- */
- ap.setDontScrollComplement(true);
+ // don't allow highlight of protein/cDNA to also scroll a complementary
+ // panel,as this sets up a feedback loop (scrolling panel 1 causes moused
+ // over residue to change abruptly, causing highlighted residue in panel 2
+ // to change, causing a scroll in panel 1 etc)
+ ap.setToScrollComplementPanel(false);
if (ap.scrollToPosition(results, false))
{
seqCanvas.revalidate();
}
+ ap.setToScrollComplementPanel(true);
}
setStatusMessage(results);
seqCanvas.highlightSearchResults(results);
{
if (e.isShiftDown())
{
- ap.scrollRight(true);
+ av.getRanges().scrollRight(true);
}
else
{
- ap.scrollUp(false);
+ av.getRanges().scrollUp(false);
}
}
else
{
if (e.isShiftDown())
{
- ap.scrollRight(false);
+ av.getRanges().scrollRight(false);
}
else
{
- ap.scrollUp(true);
+ av.getRanges().scrollUp(true);
}
}
// TODO Update tooltip for new position.
if (mouseDragging && (evt.getY() < 0)
&& (av.getRanges().getStartSeq() > 0))
{
- running = ap.scrollUp(true);
+ running = av.getRanges().scrollUp(true);
}
if (mouseDragging && (evt.getY() >= getHeight())
&& (av.getAlignment().getHeight() > av.getRanges()
.getEndSeq()))
{
- running = ap.scrollUp(false);
+ running = av.getRanges().scrollUp(false);
}
if (mouseDragging && (evt.getX() < 0))
{
- running = ap.scrollRight(false);
+ running = av.getRanges().scrollRight(false);
}
else if (mouseDragging && (evt.getX() >= getWidth()))
{
- running = ap.scrollRight(true);
+ running = av.getRanges().scrollRight(true);
}
}
public abstract class OverviewDimensions
{
protected static final int MAX_WIDTH = 400;
+
protected static final int MIN_WIDTH = 120;
+
protected static final int MIN_SEQ_HEIGHT = 40;
+
protected static final int MAX_SEQ_HEIGHT = 300;
private static final int DEFAULT_GRAPH_HEIGHT = 20;
protected int width;
+
protected int sequencesHeight;
+
protected int graphHeight = DEFAULT_GRAPH_HEIGHT;
+
protected int boxX = -1;
+
protected int boxY = -1;
+
protected int boxWidth = -1;
+
protected int boxHeight = -1;
- protected int scrollCol = -1;
- protected int scrollRow = -1;
+
protected int alwidth;
+
protected int alheight;
+ /**
+ * 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)
{
g.drawRect(boxX + 1, boxY + 1, boxWidth - 2, boxHeight - 2);
}
- public int getScrollCol()
- {
- return scrollCol;
- }
-
- public int getScrollRow()
- {
- return scrollRow;
- }
-
public int getBoxX()
{
return boxX;
int xAsRes = Math.round((float) x * alwidth / width);
// get viewport width in residues
- int vpwidth = ranges.getEndRes() - ranges.getStartRes() + 1;
+ int vpwidth = ranges.getViewportWidth();
if (xAsRes + vpwidth > alwidth)
{
// 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) < alwidth)
+ if ((ranges.getEndRes() + vpwidth - 1) < alwidth)
{
xAsRes = alwidth - vpwidth;
}
else
{
- xAsRes = scrollCol;
+ xAsRes = ranges.getEndRes();
}
}
// get viewport height in sequences
// add 1 because height includes both endSeq and startSeq
- int vpheight = ranges.getEndSeq() - ranges.getStartSeq() + 1;
+ int vpheight = ranges.getViewportHeight();
if (yAsSeq + vpheight > alheight)
{
// went past the end of the alignment, adjust backwards
- if ((scrollRow + vpheight - 1) < alheight)
+ if ((ranges.getEndSeq() + vpheight - 1) < alheight)
{
yAsSeq = alheight - vpheight;
}
else
{
- yAsSeq = scrollRow;
+ yAsSeq = ranges.getEndSeq();
}
}
- // update scroll values
- scrollCol = xAsRes;
- scrollRow = yAsSeq;
+ // update viewport
+ ranges.setStartRes(xAsRes);
+ ranges.setStartSeq(yAsSeq);
}
int xAsRes = Math.round((float) x * alwidth / width);
// get viewport width in residues
- int vpwidth = ranges.getEndRes() - ranges.getStartRes() + 1;
+ int vpwidth = ranges.getViewportWidth();
// 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
// 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)
+ if ((ranges.getEndRes() + vpwidth - 1) < visAlignWidth)
{
visXAsRes = hiddenCols.findColumnPosition(hiddenCols
.subtractVisibleColumns(vpwidth - 1, alwidth - 1));
}
else
{
- visXAsRes = scrollCol;
+ visXAsRes = ranges.getEndRes();
}
}
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;
+ int vpheight = ranges.getViewportHeight();
// 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
if (visYAsSeq + vpheight - 1 > visAlignHeight)
{
// went past the end of the alignment, adjust backwards
- if ((scrollRow + vpheight - 1) < visAlignHeight)
+ if ((ranges.getEndSeq() + vpheight - 1) < visAlignHeight)
{
visYAsSeq = hiddenSeqs.findIndexWithoutHiddenSeqs(hiddenSeqs
.subtractVisibleRows(vpheight - 1, alheight - 1));
}
else
{
- visYAsSeq = scrollRow;
+ visYAsSeq = ranges.getEndSeq();
}
}
- // update scroll values
- scrollCol = visXAsRes;
- scrollRow = visYAsSeq;
+ // update viewport
+ ranges.setStartRes(xAsRes);
+ ranges.setStartSeq(yAsSeq);
}
--- /dev/null
+package jalview.viewmodel;
+
+import java.beans.PropertyChangeListener;
+
+public interface ViewportListenerI extends PropertyChangeListener
+{
+
+}
*/
package jalview.viewmodel;
+import java.beans.PropertyChangeSupport;
+
public abstract class ViewportProperties
{
+ protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(
+ this);
+
+ public void addPropertyChangeListener(ViewportListenerI listener)
+ {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(ViewportListenerI listener)
+ {
+ changeSupport.removePropertyChangeListener(listener);
+ }
}
*/
package jalview.viewmodel;
+import jalview.api.AlignViewportI;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
/**
- * 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,
+ * 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
*/
public class ViewportRanges extends ViewportProperties
}
/**
- * Set first residue visible in the viewport
+ * Set first residue visible in the viewport, and retain the current width.
+ * Fires a property change event.
*
* @param res
* residue position
*/
public void setStartRes(int res)
{
- if (res > al.getWidth() - 1)
+ int width = getViewportWidth();
+ setStartEndRes(res, res + width - 1);
+ }
+
+ /**
+ * Set start and end residues at the same time. This method only fires one
+ * event for the two changes, and should be used in preference to separate
+ * calls to setStartRes and setEndRes.
+ *
+ * @param start
+ * the start residue
+ * @param end
+ * the end residue
+ */
+ public void setStartEndRes(int start, int end)
+ {
+ int oldstartres = this.startRes;
+ if (start > al.getWidth() - 1)
+ {
+ startRes = al.getWidth() - 1;
+ }
+ else if (start < 0)
+ {
+ startRes = 0;
+ }
+ else
{
- res = al.getWidth() - 1;
+ startRes = start;
}
- else if (res < 0)
+
+ int oldendres = this.endRes;
+ if (end < 0)
{
- res = 0;
+ endRes = 0;
+ }
+ else
+ {
+ 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);
}
- this.startRes = res;
}
/**
- * Set last residue visible in the viewport
+ * Set last residue visible in the viewport. Fires a property change event.
*
* @param res
* residue position
*/
public void setEndRes(int res)
{
- if (res >= al.getWidth())
- {
- res = al.getWidth() - 1;
- }
- else if (res < 0)
+ int startres = res;
+ int width = getViewportWidth();
+ if (startres + width - 1 > al.getWidth() - 1)
{
- res = 0;
+ startres = al.getWidth() - width;
}
- this.endRes = res;
+ setStartEndRes(startres - width + 1, startres);
}
/**
- * Set the first sequence visible in the viewport
+ * Set the first sequence visible in the viewport, maintaining the height. If
+ * the viewport would extend past the last sequence, sets the viewport so it
+ * sits at the bottom of the alignment. Fires a property change event.
*
* @param seq
* sequence position
*/
public void setStartSeq(int seq)
{
- if (seq > al.getHeight() - 1)
+ int startseq = seq;
+ int height = getViewportHeight();
+ if (startseq + height - 1 > al.getHeight() - 1)
+ {
+ startseq = al.getHeight() - height;
+ }
+ setStartEndSeq(startseq, startseq + height - 1);
+ }
+
+ /**
+ * Set start and end sequences at the same time. The viewport height may
+ * change. This method only fires one event for the two changes, and should be
+ * used in preference to separate calls to setStartSeq and setEndSeq.
+ *
+ * @param start
+ * the start sequence
+ * @param end
+ * the end sequence
+ */
+ public void setStartEndSeq(int start, int end)
+ {
+ int oldstartseq = this.startSeq;
+ if (start > al.getHeight() - 1)
+ {
+ startSeq = al.getHeight() - 1;
+ }
+ else if (start < 0)
+ {
+ startSeq = 0;
+ }
+ else
+ {
+ startSeq = start;
+ }
+
+ int oldendseq = this.endSeq;
+ if (end >= al.getHeight())
+ {
+ endSeq = al.getHeight() - 1;
+ }
+ else if (end < 0)
+ {
+ endSeq = 0;
+ }
+ else
{
- seq = al.getHeight() - 1;
+ endSeq = end;
}
- else if (seq < 0)
+
+ changeSupport.firePropertyChange("startseq", oldstartseq, startSeq);
+ if (oldstartseq == startSeq)
{
- seq = 0;
+ // event won't be fired if start positions are the same
+ // fire in case the end positions changed
+ changeSupport.firePropertyChange("endseq", oldendseq, endSeq);
}
- this.startSeq = seq;
}
/**
- * Set the last sequence visible in the viewport
+ * Set the last sequence visible in the viewport. Fires a property change
+ * event.
*
* @param seq
* sequence position
*/
public void setEndSeq(int seq)
{
- if (seq >= al.getHeight())
- {
- seq = al.getHeight() - 1;
- }
- else if (seq < 0)
- {
- seq = 0;
- }
- this.endSeq = seq;
+ int height = getViewportHeight();
+ setStartEndSeq(seq - height + 1, seq);
}
/**
{
return endSeq;
}
+
+ /**
+ * Set viewport width in residues, without changing startRes. Use in
+ * preference to calculating endRes from the width, to avoid out by one
+ * errors! Fires a property change event.
+ *
+ * @param w
+ * width in residues
+ */
+ public void setViewportWidth(int w)
+ {
+ setStartEndRes(startRes, startRes + w - 1);
+ }
+
+ /**
+ * Set viewport height in residues, without changing startSeq. Use in
+ * preference to calculating endSeq from the height, to avoid out by one
+ * errors! Fires a property change event.
+ *
+ * @param h
+ * height in sequences
+ */
+ public void setViewportHeight(int h)
+ {
+ setStartEndSeq(startSeq, startSeq + h - 1);
+ }
+
+ /**
+ * Set viewport horizontal start position and width. Use in preference to
+ * calculating endRes from the width, to avoid out by one errors! Fires a
+ * property change event.
+ *
+ * @param start
+ * start residue
+ * @param w
+ * width in residues
+ */
+ public void setViewportStartAndWidth(int start, int w)
+ {
+ int vpstart = start;
+ if (vpstart < 0)
+ {
+ vpstart = 0;
+ }
+ else if (vpstart + w - 1 > al.getWidth() - 1)
+ {
+ vpstart = al.getWidth() - 1;
+ }
+ setStartEndRes(vpstart, vpstart + w - 1);
+ }
+
+ /**
+ * Set viewport vertical start position and height. Use in preference to
+ * calculating endSeq from the height, to avoid out by one errors! Fires a
+ * property change event.
+ *
+ * @param start
+ * start sequence
+ * @param h
+ * height in sequences
+ */
+ public void setViewportStartAndHeight(int start, int h)
+ {
+ int vpstart = start;
+ if (vpstart < 0)
+ {
+ vpstart = 0;
+ }
+ else if (vpstart + h - 1 > al.getHeight() - 1)
+ {
+ vpstart = al.getHeight() - h;
+ }
+ setStartEndSeq(vpstart, vpstart + h - 1);
+ }
+
+ /**
+ * Get width of viewport in residues
+ *
+ * @return width of viewport
+ */
+ public int getViewportWidth()
+ {
+ return (endRes - startRes + 1);
+ }
+
+ /**
+ * Get height of viewport in residues
+ *
+ * @return height of viewport
+ */
+ public int getViewportHeight()
+ {
+ return (endSeq - startSeq + 1);
+ }
+
+ /**
+ * Scroll the viewport range vertically. Fires a property change event.
+ *
+ * @param up
+ * true if scrolling up, false if down
+ *
+ * @return true if the scroll is valid
+ */
+ public boolean scrollUp(boolean up)
+ {
+ if (up)
+ {
+ if (startSeq < 1)
+ {
+ return false;
+ }
+
+ setStartSeq(startSeq - 1);
+ }
+ else
+ {
+ if (endSeq >= al.getHeight() - 1)
+ {
+ return false;
+ }
+
+ setStartSeq(startSeq + 1);
+ }
+ return true;
+ }
+
+ /**
+ * Scroll the viewport range horizontally. Fires a property change event.
+ *
+ * @param right
+ * true if scrolling right, false if left
+ *
+ * @return true if the scroll is valid
+ */
+ public boolean scrollRight(boolean right)
+ {
+ if (!right)
+ {
+ if (startRes < 1)
+ {
+ return false;
+ }
+
+ setStartRes(startRes - 1);
+ }
+ else
+ {
+ if (endRes > al.getWidth() - 1)
+ {
+ return false;
+ }
+
+ setStartRes(startRes + 1);
+ }
+
+ return true;
+ }
+
+ /**
+ * Scroll a wrapped alignment so that the specified residue is visible. Fires
+ * a property change event.
+ *
+ * @param res
+ * residue position to scroll to
+ */
+ public void scrollToWrappedVisible(int res)
+ {
+ // get the start residue of the wrapped row which res is in
+ // and set that as our start residue
+ int width = getViewportWidth();
+ setStartRes((res / width) * width);
+ }
+
+ /**
+ * Scroll so that (x,y) is visible. Fires a property change event.
+ *
+ * @param x
+ * x position in alignment
+ * @param y
+ * y position in alignment
+ * @param av
+ * viewport to be visible in. Here until hidden columns JAL-2388
+ * merged, then use alignment to get hidden cols
+ */
+ public void scrollToVisible(int x, int y, AlignViewportI av)
+ {
+ while (y < startSeq)
+ {
+ scrollUp(true);
+ }
+ while (y > endSeq)
+ {
+ scrollUp(false);
+ }
+
+ HiddenColumns hidden = al.getHiddenColumns();
+ while (x < hidden.adjustForHiddenColumns(startRes))
+ {
+ if (!scrollRight(false))
+ {
+ break;
+ }
+ }
+ while (x > hidden.adjustForHiddenColumns(endRes))
+ {
+ if (!scrollRight(true))
+ {
+ break;
+ }
+ }
+ }
+
+ /**
+ * Adjust sequence position for page up. Fires a property change event.
+ */
+ public void pageUp()
+ {
+ setViewportStartAndHeight(2 * startSeq - endSeq, getViewportHeight());
+ }
+
+ /**
+ * Adjust sequence position for page down. Fires a property change event.
+ */
+ public void pageDown()
+ {
+ setViewportStartAndHeight(endSeq, getViewportHeight());
+ }
}
hiddenCols.revealAllHiddenColumns(colsel);
vpranges = new ViewportRanges(al);
- vpranges.setStartRes(0);
- vpranges.setEndRes(62);
- vpranges.setStartSeq(0);
- vpranges.setEndSeq(17);
+ vpranges.setViewportStartAndHeight(0, 18);
+ vpranges.setViewportStartAndWidth(0, 63);
viewHeight = vpranges.getEndSeq() - vpranges.getStartSeq() + 1;
viewWidth = vpranges.getEndRes() - vpranges.getStartRes() + 1;
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// negative boxX value reset to 0
mouseClick(od, -5, 10);
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollRow(),
+ assertEquals(vpranges.getStartSeq(),
Math.round((float) 10 * alheight / od.getSequencesHeight()));
- assertEquals(od.getScrollCol(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
// negative boxY value reset to 0
mouseClick(od, 6, -2);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) 6 * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// overly large boxX value reset to width-boxWidth
mouseClick(od, 100, 6);
assertEquals(od.getBoxY(), 6);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()));
assertEquals(od.getBoxY(), od.getSequencesHeight() - od.getBoxHeight());
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
// here (float) od.getBoxY() * alheight / od.getSequencesHeight() = 507.5
// and round rounds to 508; however we get 507 working with row values
// hence the subtraction of 1
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()) - 1);
assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()));
assertEquals(od.getBoxX(), oldboxx + 5);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
assertEquals(od.getBoxY(), oldboxy + 2);
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()));
// click at top corner
mouseClick(od, 0, 0);
assertEquals(od.getBoxX(), 0);
- assertEquals(od.getScrollCol(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
assertEquals(od.getBoxY(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
}
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide cols at start and check updated box position is correct
int lastHiddenCol = 30;
// click to right of hidden columns, box moves to click point
testBoxIsAtClickPoint(40, 0);
- assertEquals(od.getScrollRow(), 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(),
Math.round((float) 40 * alwidth / od.getWidth()));
// click to right of hidden columns such that box runs over right hand side
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
}
/**
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide columns 63-73, no change to box position or dimensions
int firstHidden = 63;
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// move box so that it overlaps with hidden cols on one side
// box width, boxX and scrollCol as for unhidden case
// between cols 60 and 70
mouseClick(od, xpos, 0);
testBoxIsAtClickPoint(xpos, 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round(xpos * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// move box so that it completely covers hidden cols
// box width, boxX and scrollCol as for unhidden case
xpos = 33;
mouseClick(od, xpos, 0);
testBoxIsAtClickPoint(xpos, 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) xpos * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// move box so boxX is in hidden cols, box overhangs at right
// boxX and scrollCol at left of hidden area, box width unchanged
xpos = 50;
mouseClick(od, xpos, 0);
testBoxIsAtClickPoint(xpos, 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) xpos * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// move box so boxX is to right of hidden cols, but does not go beyond full
// width of alignment
// box width, boxX and scrollCol all as for non-hidden case
xpos = 75;
testBoxIsAtClickPoint(xpos, 0);
- assertEquals(od.getScrollRow(), 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(),
Math.round(xpos * alwidth / od.getWidth()));
// move box so it goes beyond full width of alignment
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
}
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide columns 140-164, no change to box position or dimensions
int firstHidden = 140;
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// click to left of hidden cols, without overlapping
// boxX, scrollCol and width as normal
int xpos = 5;
testBoxIsAtClickPoint(xpos, 0);
- assertEquals(od.getScrollRow(), 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(),
Math.round((float) xpos * alwidth / od.getWidth()));
// click to left of hidden cols, with overlap
xpos = Math.round((float) 145 * od.getWidth() / alwidth) - boxWidth;
mouseClick(od, xpos, 0);
testBoxIsAtClickPoint(xpos, 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) xpos * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// click off end of alignment
// boxX and scrollCol adjusted backwards, width normal
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
}
/**
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide rows at start and check updated box position is correct
int lastHiddenRow = 30;
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide rows in middle and check updated box position is correct
// no changes
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide rows at end and check updated box position is correct
// no changes
*/
private void moveViewportH(int startRes)
{
- vpranges.setStartRes(startRes);
- vpranges.setEndRes(startRes + viewWidth - 1);
+ vpranges.setViewportStartAndWidth(startRes, viewWidth);
od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
}
*/
private void moveViewportV(int startSeq)
{
- vpranges.setStartSeq(startSeq);
- vpranges.setEndSeq(startSeq + viewHeight - 1);
+ vpranges.setViewportStartAndHeight(startSeq, viewHeight);
od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
}
*/
private void moveViewport(int startRes, int startSeq)
{
- vpranges.setStartRes(startRes);
- vpranges.setEndRes(startRes + viewWidth - 1);
- vpranges.setStartSeq(startSeq);
- vpranges.setEndSeq(startSeq + viewHeight - 1);
+ vpranges.setViewportStartAndWidth(startRes, viewWidth);
+ vpranges.setViewportStartAndHeight(startSeq, viewHeight);
od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
}
/*
* Mouse click as position x,y in overview window
*/
- private void mouseClick(OverviewDimensionsHideHidden od, int x, int y)
+ private void mouseClick(OverviewDimensions od, int x, int y)
{
od.updateViewportFromMouse(x, y, al.getHiddenSequences(), hiddenCols);
// updates require an OverviewPanel to exist which it doesn't here
// so call setBoxPosition() as it would be called by the AlignmentPanel
// normally
-
- vpranges.setStartRes(od.getScrollCol());
- vpranges.setEndRes(od.getScrollCol() + viewWidth - 1);
- vpranges.setStartSeq(od.getScrollRow());
- vpranges.setEndSeq(od.getScrollRow() + viewHeight - 1);
od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
}
hiddenCols.revealAllHiddenColumns(colsel);
vpranges = new ViewportRanges(al);
- vpranges.setStartRes(0);
- vpranges.setEndRes(62);
- vpranges.setStartSeq(0);
- vpranges.setEndSeq(17);
+ vpranges.setViewportStartAndHeight(0, 18);
+ vpranges.setViewportStartAndWidth(0, 63);
viewHeight = vpranges.getEndSeq() - vpranges.getStartSeq() + 1;
viewWidth = vpranges.getEndRes() - vpranges.getStartRes() + 1;
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// negative boxX value reset to 0
mouseClick(od, -5, 10);
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollRow(),
+ assertEquals(vpranges.getStartSeq(),
Math.round((float) 10 * alheight / od.getSequencesHeight()));
- assertEquals(od.getScrollCol(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
// negative boxY value reset to 0
mouseClick(od, 6, -2);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) 6 * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// overly large boxX value reset to width-boxWidth
mouseClick(od, 100, 6);
assertEquals(od.getBoxY(), 6);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()));
assertEquals(od.getBoxY(), od.getSequencesHeight() - od.getBoxHeight());
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
// here (float) od.getBoxY() * alheight / od.getSequencesHeight() = 507.5
// and round rounds to 508; however we get 507 working with row values
// hence the subtraction of 1
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()) - 1);
assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()));
assertEquals(od.getBoxX(), oldboxx + 5);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
assertEquals(od.getBoxY(), oldboxy + 2);
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()));
// click at top corner
mouseClick(od, 0, 0);
assertEquals(od.getBoxX(), 0);
- assertEquals(od.getScrollCol(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
assertEquals(od.getBoxY(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
}
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide cols at start and check updated box position is correct
// changes boxX but not boxwidth
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollRow(), 0);
- assertEquals(od.getScrollCol(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
// click to right of hidden columns, box moves to click point
testBoxIsAtClickPoint(40, 0);
- assertEquals(od.getScrollRow(), 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(),
Math.round((float) 40 * alwidth / od.getWidth())
- (lastHiddenCol + 1));
assertEquals(od.getBoxY(), 5);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth())
- (lastHiddenCol + 1));
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()));
}
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide columns 63-73, no change to box position or dimensions
int firstHidden = 63;
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// move box so that it overlaps with hidden cols on one side
// box width changes, boxX and scrollCol as for unhidden case
Math.round(boxWidth + (float) (lastHidden - firstHidden + 1)
* od.getWidth() / alwidth));
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round(xpos * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// move box so that it completely covers hidden cols
// box width changes, boxX and scrollCol as for hidden case
Math.round(boxWidth + (float) (lastHidden - firstHidden + 1)
* od.getWidth() / alwidth));
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) xpos * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// move box so boxX is in hidden cols, box overhangs at right
// boxX and scrollCol at left of hidden area, box width extends across
+ Math.round((float) (lastHidden - firstHidden + 1)
* od.getWidth() / alwidth));
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(), firstHidden - 1);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), firstHidden - 1);
+ assertEquals(vpranges.getStartSeq(), 0);
// move box so boxX is to right of hidden cols, but does not go beyond full
// width of alignment
// box width, boxX and scrollCol all as for non-hidden case
xpos = 75;
testBoxIsAtClickPoint(xpos, 0);
- assertEquals(od.getScrollRow(), 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(),
Math.round(xpos * alwidth / od.getWidth())
- (lastHidden - firstHidden + 1));
assertEquals(od.getBoxY(), 5);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(
+ vpranges.getStartRes(),
Math.round(((float) od.getBoxX() * alwidth / od.getWidth())
- (lastHidden - firstHidden + 1)));
- assertEquals(od.getScrollRow(),
+ assertEquals(
+ vpranges.getStartSeq(),
Math.round((float) od.getBoxY() * alheight
/ od.getSequencesHeight()));
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide columns 140-164, no change to box position or dimensions
int firstHidden = 140;
assertEquals(od.getBoxX(), 0);
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// click to left of hidden cols, without overlapping
// boxX, scrollCol and width as normal
int xpos = 5;
testBoxIsAtClickPoint(xpos, 0);
- assertEquals(od.getScrollRow(), 0);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(),
Math.round((float) xpos * alwidth / od.getWidth()));
// click to left of hidden cols, with overlap
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// click in hidden cols
// boxX and scrollCol adjusted for hidden cols, width normal
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// click off end of alignment
// boxX and scrollCol adjusted for hidden cols, width normal
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(),
+ assertEquals(vpranges.getStartRes(),
Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
}
/**
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxHeight(), boxHeight);
assertEquals(od.getBoxWidth(), boxWidth);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide rows at start and check updated box position is correct
// changes boxY but not boxheight
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide rows in middle and check updated box position is correct
// no changes
assertEquals(od.getBoxY(), 0);
assertEquals(od.getBoxWidth(), boxWidth);
assertEquals(od.getBoxHeight(), boxHeight);
- assertEquals(od.getScrollCol(), 0);
- assertEquals(od.getScrollRow(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
// hide rows at end and check updated box position is correct
// no changes
*/
private void moveViewportH(int startRes)
{
- vpranges.setStartRes(startRes);
- vpranges.setEndRes(startRes + viewWidth - 1);
+ vpranges.setViewportStartAndWidth(startRes, viewWidth);
od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
}
*/
private void moveViewportV(int startSeq)
{
- vpranges.setStartSeq(startSeq);
- vpranges.setEndSeq(startSeq + viewHeight - 1);
+ vpranges.setViewportStartAndHeight(startSeq, viewHeight);
od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
}
*/
private void moveViewport(int startRes, int startSeq)
{
- vpranges.setStartRes(startRes);
- vpranges.setEndRes(startRes + viewWidth - 1);
- vpranges.setStartSeq(startSeq);
- vpranges.setEndSeq(startSeq + viewHeight - 1);
+ vpranges.setViewportStartAndWidth(startRes, viewWidth);
+ vpranges.setViewportStartAndHeight(startSeq, viewHeight);
od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
}
/*
* Mouse click as position x,y in overview window
*/
- private void mouseClick(OverviewDimensionsShowHidden od, int x, int y)
+ private void mouseClick(OverviewDimensions od, int x, int y)
{
od.updateViewportFromMouse(x, y, al.getHiddenSequences(), hiddenCols);
// updates require an OverviewPanel to exist which it doesn't here
// so call setBoxPosition() as it would be called by the AlignmentPanel
// normally
-
- vpranges.setStartRes(od.getScrollCol());
- vpranges.setEndRes(od.getScrollCol() + viewWidth - 1);
- vpranges.setStartSeq(od.getScrollRow());
- vpranges.setEndSeq(od.getScrollRow() + viewHeight - 1);
od.setBoxPosition(al.getHiddenSequences(), hiddenCols);
}
--- /dev/null
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.viewmodel;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.analysis.AlignmentGenerator;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+
+import java.util.Hashtable;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+@Test(singleThreaded = true)
+public class OverviewDimensionsTest
+{
+ AlignmentI al;
+ OverviewDimensions od;
+
+ // cached widths and heights
+ int boxWidth;
+ int boxHeight;
+ int viewHeight;
+ int viewWidth;
+ int alheight;
+ int alwidth;
+
+ ViewportRanges vpranges;
+
+ Hashtable<SequenceI, SequenceCollectionI> hiddenRepSequences = new Hashtable<SequenceI, SequenceCollectionI>();
+
+ ColumnSelection hiddenCols = new ColumnSelection();
+
+ @BeforeClass(alwaysRun = true)
+ public void setUpJvOptionPane()
+ {
+ // create random alignment
+ AlignmentGenerator gen = new AlignmentGenerator(false);
+ al = gen.generate(157, 525, 123, 5, 5);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp()
+ {
+ if (!hiddenRepSequences.isEmpty())
+ {
+ al.getHiddenSequences().showAll(hiddenRepSequences);
+ }
+ hiddenCols.revealAllHiddenColumns();
+
+ vpranges = new ViewportRanges(al);
+ vpranges.setViewportStartAndHeight(0, 18);
+ vpranges.setViewportStartAndWidth(0, 63);
+
+ viewHeight = vpranges.getEndSeq() - vpranges.getStartSeq() + 1;
+ viewWidth = vpranges.getEndRes() - vpranges.getStartRes() + 1;
+
+ ColumnSelection hiddenCols = new ColumnSelection();
+
+ od = new OverviewDimensions(vpranges, true);
+ // Initial box sizing - default path through code
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+
+ mouseClick(od, 0, 0);
+ moveViewport(0, 0);
+
+ // calculate before hidden columns so we get absolute values
+ alheight = vpranges.getAbsoluteAlignmentHeight();
+ alwidth = vpranges.getAbsoluteAlignmentWidth();
+
+ boxWidth = Math.round((float) (vpranges.getEndRes()
+ - vpranges.getStartRes() + 1)
+ * od.getWidth() / alwidth);
+ boxHeight = Math.round((float) (vpranges.getEndSeq()
+ - vpranges.getStartSeq() + 1)
+ * od.getSequencesHeight() / alheight);
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void cleanUp()
+ {
+ al = null;
+ }
+
+ /**
+ * Test that the OverviewDimensions constructor sets width and height
+ * correctly
+ */
+ @Test(groups = { "Functional" })
+ public void testConstructor()
+ {
+ SequenceI seqa = new Sequence("Seq1", "ABC");
+ SequenceI seqb = new Sequence("Seq2", "ABC");
+ SequenceI seqc = new Sequence("Seq3", "ABC");
+ SequenceI seqd = new Sequence("Seq4", "ABC");
+ SequenceI seqe = new Sequence("Seq5",
+ "ABCABCABCABCABCABCABCABCBACBACBACBAC");
+
+ int defaultGraphHeight = 20;
+ int maxWidth = 400;
+ int minWidth = 120;
+ int maxSeqHeight = 300;
+ int minSeqHeight = 40;
+
+ // test for alignment with width > height
+ SequenceI[] seqs1 = new SequenceI[] { seqa, seqb };
+ Alignment al1 = new Alignment(seqs1);
+ ViewportRanges props = new ViewportRanges(al1);
+
+ OverviewDimensions od = new OverviewDimensions(props, true);
+ int scaledHeight = 267;
+ assertEquals(od.getGraphHeight(), defaultGraphHeight);
+ assertEquals(od.getSequencesHeight(), scaledHeight);
+ assertEquals(od.getWidth(), maxWidth);
+ assertEquals(od.getHeight(), scaledHeight + defaultGraphHeight);
+
+ // test for alignment with width < height
+ SequenceI[] seqs2 = new SequenceI[] { seqa, seqb, seqc, seqd };
+ Alignment al2 = new Alignment(seqs2);
+ props = new ViewportRanges(al2);
+
+ od = new OverviewDimensions(props, true);
+ int scaledWidth = 300;
+ assertEquals(od.getGraphHeight(), defaultGraphHeight);
+ assertEquals(od.getSequencesHeight(), maxSeqHeight);
+ assertEquals(od.getWidth(), scaledWidth);
+ assertEquals(od.getHeight(), scaledWidth + defaultGraphHeight);
+
+ // test for alignment with width > height and sequence height scaled below
+ // min value
+ SequenceI[] seqs3 = new SequenceI[] { seqe };
+ Alignment al3 = new Alignment(seqs3);
+ props = new ViewportRanges(al3);
+
+ od = new OverviewDimensions(props, true);
+ assertEquals(od.getGraphHeight(), defaultGraphHeight);
+ assertEquals(od.getSequencesHeight(), minSeqHeight);
+ assertEquals(od.getWidth(), maxWidth);
+ assertEquals(od.getHeight(), minSeqHeight + defaultGraphHeight);
+
+ // test for alignment with width < height and width scaled below min value
+ SequenceI[] seqs4 = new SequenceI[] { seqa, seqb, seqc, seqd, seqa,
+ seqb, seqc, seqd, seqa, seqb, seqc, seqd, seqa, seqb, seqc, seqd };
+ Alignment al4 = new Alignment(seqs4);
+ props = new ViewportRanges(al4);
+
+ od = new OverviewDimensions(props, true);
+ assertEquals(od.getGraphHeight(), defaultGraphHeight);
+ assertEquals(od.getSequencesHeight(), maxSeqHeight);
+ assertEquals(od.getWidth(), minWidth);
+ assertEquals(od.getHeight(), maxSeqHeight + defaultGraphHeight);
+
+ Alignment al5 = new Alignment(seqs4);
+ props = new ViewportRanges(al5);
+
+ od = new OverviewDimensions(props, false);
+ assertEquals(od.getGraphHeight(), 0);
+ assertEquals(od.getSequencesHeight(), maxSeqHeight);
+ assertEquals(od.getWidth(), minWidth);
+ assertEquals(od.getHeight(), maxSeqHeight);
+ }
+
+ /**
+ * Test that validation after mouse adjustments to boxX and boxY sets box
+ * dimensions and scroll values correctly, when there are no hidden rows or
+ * columns.
+ */
+ @Test(groups = { "Functional" })
+ public void testSetBoxFromMouseClick()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols,
+ vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // negative boxX value reset to 0
+ mouseClick(od, -5, 10);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartSeq(),
+ Math.round((float) 10 * alheight / od.getSequencesHeight()));
+ assertEquals(vpranges.getStartRes(), 0);
+
+ // negative boxY value reset to 0
+ mouseClick(od, 6, -2);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) 6 * alwidth / od.getWidth()));
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // overly large boxX value reset to width-boxWidth
+ mouseClick(od, 100, 6);
+ assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
+ assertEquals(od.getBoxY(), 6);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+ assertEquals(
+ vpranges.getStartSeq(),
+ Math.round((float) od.getBoxY() * alheight
+ / od.getSequencesHeight()));
+
+ // overly large boxY value reset to sequenceHeight - boxHeight
+ mouseClick(od, 10, 520);
+ assertEquals(od.getBoxX(), 10);
+ assertEquals(od.getBoxY(), od.getSequencesHeight() - od.getBoxHeight());
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+
+ // here (float) od.getBoxY() * alheight / od.getSequencesHeight() = 507.5
+ // and round rounds to 508; however we get 507 working with row values
+ // hence the subtraction of 1
+ assertEquals(
+ vpranges.getStartSeq(),
+ Math.round((float) od.getBoxY() * alheight
+ / od.getSequencesHeight()) - 1);
+
+ // click past end of alignment, as above
+ mouseClick(od, 3000, 5);
+ assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+ assertEquals(
+ vpranges.getStartSeq(),
+ Math.round((float) od.getBoxY() * alheight
+ / od.getSequencesHeight()));
+
+ // move viewport so startRes non-zero and then mouseclick
+ moveViewportH(50);
+
+ // click at viewport position
+ int oldboxx = od.getBoxX();
+ int oldboxy = od.getBoxY();
+ mouseClick(od, od.getBoxX() + 5, od.getBoxY() + 2);
+ assertEquals(od.getBoxX(), oldboxx + 5);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+ assertEquals(od.getBoxY(), oldboxy + 2);
+ assertEquals(
+ vpranges.getStartSeq(),
+ Math.round((float) od.getBoxY() * alheight
+ / od.getSequencesHeight()));
+
+ // click at top corner
+ mouseClick(od, 0, 0);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ }
+
+ /**
+ * Test setting of the box position, when there are hidden cols at the start
+ * of the alignment
+ */
+ @Test(groups = { "Functional" })
+ public void testFromMouseWithHiddenColsAtStart()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols,
+ vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // hide cols at start and check updated box position is correct
+ // changes boxX but not boxwidth
+ int lastHiddenCol = 30;
+ hiddenCols.hideColumns(0, lastHiddenCol);
+
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+ assertEquals(od.getBoxX(),
+ Math.round((float) (lastHiddenCol + 1) * od.getWidth()
+ / alwidth));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // try to click in hidden cols, check box does not move
+ int xpos = 10;
+ mouseClick(od, xpos, 0);
+ assertEquals(
+ od.getBoxX(),
+ Math.round((float) (lastHiddenCol + 1) * od.getWidth()
+ / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(), 0);
+
+ // click to right of hidden columns, box moves to click point
+ testBoxIsAtClickPoint(40, 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) 40 * alwidth / od.getWidth())
+ - (lastHiddenCol + 1));
+
+ // click to right of hidden columns such that box runs over right hand side
+ // of alignment
+ // box position is adjusted away from the edge
+ // overly large boxX value reset to width-boxWidth
+ xpos = 100;
+ mouseClick(od, xpos, 5);
+ assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
+ assertEquals(od.getBoxY(), 5);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) od.getBoxX() * alwidth / od.getWidth())
+ - (lastHiddenCol + 1));
+ assertEquals(
+ vpranges.getStartSeq(),
+ Math.round((float) od.getBoxY() * alheight
+ / od.getSequencesHeight()));
+ }
+
+ /**
+ * Test setting of the box position, when there are hidden cols in the middle
+ * of the alignment
+ */
+ @Test(groups = { "Functional" })
+ public void testFromMouseWithHiddenColsInMiddle()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols,
+ vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // hide columns 63-73, no change to box position or dimensions
+ int firstHidden = 63;
+ int lastHidden = 73;
+ hiddenCols.hideColumns(firstHidden, lastHidden);
+
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // move box so that it overlaps with hidden cols on one side
+ // box width changes, boxX and scrollCol as for unhidden case
+ int xpos = 55 - boxWidth; // 55 is position in overview approx halfway
+ // between cols 60 and 70
+ mouseClick(od, xpos, 0);
+ assertEquals(od.getBoxX(), xpos);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(
+ od.getBoxWidth(),
+ Math.round(boxWidth + (float) (lastHidden - firstHidden + 1)
+ * od.getWidth() / alwidth));
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round(xpos * alwidth / od.getWidth()));
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // move box so that it completely covers hidden cols
+ // box width changes, boxX and scrollCol as for hidden case
+ xpos = 33;
+ mouseClick(od, xpos, 0);
+ assertEquals(od.getBoxX(), xpos);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(
+ od.getBoxWidth(),
+ Math.round(boxWidth + (float) (lastHidden - firstHidden + 1)
+ * od.getWidth() / alwidth));
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) xpos * alwidth / od.getWidth()));
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // move box so boxX is in hidden cols, box overhangs at right
+ // boxX and scrollCol at left of hidden area, box width extends across
+ // hidden region
+ xpos = 50;
+ mouseClick(od, xpos, 0);
+ assertEquals(od.getBoxX(),
+ Math.round((float) (firstHidden - 1) * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(
+ od.getBoxWidth(),
+ boxWidth
+ + Math.round((float) (lastHidden - firstHidden + 1)
+ * od.getWidth() / alwidth));
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(), firstHidden - 1);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // move box so boxX is to right of hidden cols, but does not go beyond full
+ // width of alignment
+ // box width, boxX and scrollCol all as for non-hidden case
+ xpos = 75;
+ testBoxIsAtClickPoint(xpos, 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(),
+ Math.round(xpos * alwidth / od.getWidth())
+ - (lastHidden - firstHidden + 1));
+
+ // move box so it goes beyond full width of alignment
+ // boxX, scrollCol adjusted back, box width normal
+ xpos = 3000;
+ mouseClick(od, xpos, 5);
+ assertEquals(od.getBoxX(), od.getWidth() - od.getBoxWidth());
+ assertEquals(od.getBoxY(), 5);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(
+ vpranges.getStartRes(),
+ Math.round(((float) od.getBoxX() * alwidth / od.getWidth())
+ - (lastHidden - firstHidden + 1)));
+ assertEquals(
+ vpranges.getStartSeq(),
+ Math.round((float) od.getBoxY() * alheight
+ / od.getSequencesHeight()));
+
+ }
+
+ /**
+ * Test setting of the box position, when there are hidden cols at the end of
+ * the alignment
+ */
+ @Test(groups = { "Functional" })
+ public void testFromMouseWithHiddenColsAtEnd()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols,
+ vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // hide columns 140-164, no change to box position or dimensions
+ int firstHidden = 140;
+ int lastHidden = 164;
+ hiddenCols.hideColumns(firstHidden, lastHidden);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // click to left of hidden cols, without overlapping
+ // boxX, scrollCol and width as normal
+ int xpos = 5;
+ testBoxIsAtClickPoint(xpos, 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) xpos * alwidth / od.getWidth()));
+
+ // click to left of hidden cols, with overlap
+ // boxX and scrollCol adjusted for hidden cols, width normal
+ xpos = Math.round((float) 145 * od.getWidth() / alwidth) - boxWidth;
+ mouseClick(od, xpos, 0);
+ assertEquals(od.getBoxX(),
+ Math.round((float) (firstHidden - 1) * od.getWidth() / alwidth)
+ - boxWidth + 1);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // click in hidden cols
+ // boxX and scrollCol adjusted for hidden cols, width normal
+ xpos = 115;
+ assertEquals(od.getBoxX(),
+ Math.round((float) (firstHidden - 1) * od.getWidth() / alwidth)
+ - boxWidth + 1);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // click off end of alignment
+ // boxX and scrollCol adjusted for hidden cols, width normal
+ xpos = 3000;
+ assertEquals(od.getBoxX(),
+ Math.round((float) (firstHidden - 1) * od.getWidth() / alwidth)
+ - boxWidth + 1);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(),
+ Math.round((float) od.getBoxX() * alwidth / od.getWidth()));
+ assertEquals(vpranges.getStartSeq(), 0);
+ }
+
+ /**
+ * Test that the box position is set correctly when set from the viewport,
+ * with no hidden rows or columns
+ */
+ @Test(groups = { "Functional" })
+ public void testSetBoxFromViewport()
+ {
+ // move viewport to start of alignment
+ moveViewport(0, 0);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to right
+ moveViewportH(70);
+ assertEquals(od.getBoxX(),
+ Math.round((float) 70 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport down
+ moveViewportV(100);
+ assertEquals(od.getBoxX(),
+ Math.round((float) 70 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(),
+ Math.round(100 * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to bottom right
+ moveViewport(98, 507);
+ assertEquals(od.getBoxX(),
+ Math.round((float) 98 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(),
+ Math.round((float) 507 * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ }
+
+ /**
+ * Test that the box position is set correctly when there are hidden columns
+ * at the start
+ */
+ @Test(groups = { "Functional" })
+ public void testSetBoxFromViewportHiddenColsAtStart()
+ {
+ int firstHidden = 0;
+ int lastHidden = 20;
+ hiddenCols.hideColumns(firstHidden, lastHidden);
+
+ // move viewport to start of alignment
+ moveViewport(0, 0);
+ assertEquals(od.getBoxX(),
+ Math.round((float) (lastHidden + 1) * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to end of alignment - need to make startRes by removing
+ // hidden cols because of how viewport/overview are implemented
+ moveViewport(98 - lastHidden - 1, 0);
+ assertEquals(od.getBoxX(),
+ Math.round((float) 98 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ }
+
+ /**
+ * Test that the box position is set correctly when there are hidden columns
+ * in the middle
+ */
+ @Test(groups = { "Functional" })
+ public void testSetBoxFromViewportHiddenColsInMiddle()
+ {
+ int firstHidden = 68;
+ int lastHidden = 78;
+ hiddenCols.hideColumns(firstHidden, lastHidden);
+
+ // move viewport before hidden columns
+ moveViewport(3, 0);
+
+ assertEquals(od.getBoxX(),
+ Math.round((float) 3 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ System.out.println(od.getBoxWidth());
+ assertEquals(od.getBoxWidth(), boxWidth);
+ System.out.println(od.getBoxWidth());
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to left of hidden columns with overlap
+ moveViewport(10, 0);
+ assertEquals(od.getBoxX(),
+ Math.round((float) 10 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(
+ od.getBoxWidth(),
+ boxWidth
+ + Math.round((float) (lastHidden - firstHidden + 1)
+ * od.getWidth() / alwidth));
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to straddle hidden columns
+ moveViewport(63, 0);
+ assertEquals(od.getBoxX(),
+ Math.round((float) 63 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(
+ od.getBoxWidth(),
+ boxWidth
+ + Math.round((lastHidden - firstHidden + 1)
+ * od.getWidth() / alwidth));
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to right of hidden columns, no overlap
+ moveViewport(80 - (lastHidden - firstHidden + 1), 0);
+ assertEquals(od.getBoxX(),
+ Math.round((float) 80 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ }
+
+ /**
+ * Test that the box position is set correctly when there are hidden columns
+ * at the end
+ */
+ @Test(groups = { "Functional" })
+ public void testSetBoxFromViewportHiddenColsAtEnd()
+ {
+ int firstHidden = 152;
+ int lastHidden = 164;
+ hiddenCols.hideColumns(firstHidden, lastHidden);
+
+ // move viewport before hidden columns
+ moveViewport(3, 0);
+ assertEquals(od.getBoxX(),
+ Math.round((float) 3 * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to hidden columns
+ // viewport can't actually extend into hidden cols,
+ // so move to the far right edge of the viewport
+ moveViewport(firstHidden - viewWidth, 0);
+ assertEquals(od.getBoxX(),
+ Math.round((float) (firstHidden - viewWidth)
+ * od.getWidth() / alwidth));
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ }
+
+ /**
+ * Test that the box position is set correctly when there are hidden rows at
+ * the start
+ */
+ @Test(groups = { "Functional" })
+ public void testSetBoxFromViewportHiddenRowsAtStart()
+ {
+ int firstHidden = 0;
+ int lastHidden = 20;
+ hideSequences(firstHidden, lastHidden);
+
+ // move viewport to start of alignment:
+ // box moves to below hidden rows, height remains same
+ moveViewport(0, 0);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(),
+ Math.round((float) (lastHidden + 1) * od.getSequencesHeight()
+ / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to end of alignment
+ moveViewport(0, 525 - viewHeight - lastHidden - 1);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(
+ od.getBoxY(),
+ Math.round((float) (525 - viewHeight) * od.getSequencesHeight()
+ / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ }
+
+ /**
+ * Test that the box position is set correctly when there are hidden rows in
+ * the middle
+ */
+ @Test(groups = { "Functional" })
+ public void testSetBoxFromViewportHiddenRowsInMiddle()
+ {
+ int firstHidden = 200;
+ int lastHidden = 210;
+ hideSequences(firstHidden, lastHidden);
+
+ // move viewport to start of alignment:
+ // box, height etc as in non-hidden case
+ moveViewport(0, 0);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to straddle hidden rows
+ moveViewport(0, 198);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), Math.round ((float)198 * od.getSequencesHeight()
+ / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(
+ od.getBoxHeight(),
+ Math.round((float) (viewHeight + lastHidden - firstHidden + 1)
+ * od.getSequencesHeight() / alheight));
+ }
+
+ /**
+ * Test that the box position is set correctly when there are hidden rows at
+ * the bottom
+ */
+ @Test(groups = { "Functional" })
+ public void testSetBoxFromViewportHiddenRowsAtEnd()
+ {
+ int firstHidden = 500;
+ int lastHidden = 524;
+ hideSequences(firstHidden, lastHidden);
+
+ // move viewport to start of alignment:
+ // box, height etc as in non-hidden case
+ moveViewport(0, 0);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // move viewport to end of alignment
+ // viewport sits above hidden rows and does not include them
+ moveViewport(0, firstHidden - viewHeight - 1);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(
+ od.getBoxY(),
+ Math.round((float) (firstHidden - viewHeight - 1)
+ * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ }
+
+ /**
+ * Test setting of the box position, when there are hidden rows at the start
+ * of the alignment
+ */
+ @Test(groups = { "Functional" })
+ public void testFromMouseWithHiddenRowsAtStart()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols,
+ vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // hide rows at start and check updated box position is correct
+ // changes boxY but not boxheight
+ int lastHiddenRow = 30;
+ hideSequences(0, lastHiddenRow);
+
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(),
+ Math.round((float) (lastHiddenRow + 1)
+ * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // click in hidden rows - same result
+ mouseClick(od, 0, 0);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(
+ od.getBoxY(),
+ Math.round((float) (lastHiddenRow + 1)
+ * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // click below hidden rows
+ mouseClick(od, 0, 150);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 150);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ }
+
+ /**
+ * Test setting of the box position, when there are hidden rows at the middle
+ * of the alignment
+ */
+ @Test(groups = { "Functional" })
+ public void testFromMouseWithHiddenRowsInMiddle()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols,
+ vpranges);
+
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // hide rows in middle and check updated box position is correct
+ // no changes
+ int firstHiddenRow = 50;
+ int lastHiddenRow = 54;
+ hideSequences(firstHiddenRow, lastHiddenRow);
+
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // click above hidden rows, so that box overlaps
+ int ypos = 35; // column value in residues
+ mouseClick(od, 0,
+ Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(),
+ Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(
+ od.getBoxHeight(),
+ boxHeight
+ + Math.round((float) (lastHiddenRow - firstHiddenRow + 1)
+ * od.getSequencesHeight() / alheight));
+
+ // click so that box straddles hidden rows
+ ypos = 44; // column value in residues
+ mouseClick(od, 0,
+ Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(),
+ Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(
+ od.getBoxHeight(),
+ boxHeight
+ + Math.round((float) (lastHiddenRow - firstHiddenRow + 1)
+ * od.getSequencesHeight() / alheight));
+ }
+
+ /**
+ * Test setting of the box position, when there are hidden rows at the end of
+ * the alignment
+ */
+ @Test(groups = { "Functional" })
+ public void testFromMouseWithHiddenRowsAtEnd()
+ {
+ od.updateViewportFromMouse(0, 0, al.getHiddenSequences(), hiddenCols,
+ vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ assertEquals(vpranges.getStartRes(), 0);
+ assertEquals(vpranges.getStartSeq(), 0);
+
+ // hide rows at end and check updated box position is correct
+ // no changes
+ int firstHidden = 500;
+ int lastHidden = 524;
+ hideSequences(firstHidden, lastHidden);
+
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(), 0);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // click above hidden rows
+ int ypos = 40; // row 40
+ mouseClick(od, 0,
+ Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(od.getBoxY(),
+ Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // click above hidden rows so box overlaps
+ // boxY moved upwards, boxHeight remains same
+ ypos = 497; // row 497
+ mouseClick(od, 0,
+ Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(
+ od.getBoxY(),
+ Math.round((float) (firstHidden - viewHeight)
+ * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ // click within hidden rows
+ ypos = 505;
+ mouseClick(od, 0,
+ Math.round((float) ypos * od.getSequencesHeight() / alheight));
+ assertEquals(od.getBoxX(), 0);
+ assertEquals(
+ od.getBoxY(),
+ Math.round((firstHidden - viewHeight) * od.getSequencesHeight()
+ / alheight));
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+ }
+
+ /*
+ * Move viewport horizontally: startRes + previous width gives new horizontal extent. Vertical extent stays the same.
+ */
+ private void moveViewportH(int startRes)
+ {
+ vpranges.setViewportStartAndWidth(startRes, viewWidth);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+ }
+
+ /*
+ * Move viewport vertically: startSeq and endSeq give new vertical extent. Horizontal extent stays the same.
+ */
+ private void moveViewportV(int startSeq)
+ {
+ vpranges.setViewportStartAndHeight(startSeq, viewHeight);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+ }
+
+ /*
+ * Move viewport horizontally and vertically.
+ */
+ private void moveViewport(int startRes, int startSeq)
+ {
+ vpranges.setViewportStartAndWidth(startRes, viewWidth);
+ vpranges.setViewportStartAndHeight(startSeq, viewHeight);
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+ }
+
+ /*
+ * Mouse click as position x,y in overview window
+ */
+ private void mouseClick(OverviewDimensions od, int x, int y)
+ {
+ od.updateViewportFromMouse(x, y, al.getHiddenSequences(), hiddenCols,
+ vpranges);
+
+ // updates require an OverviewPanel to exist which it doesn't here
+ // so call setBoxPosition() as it would be called by the AlignmentPanel
+ // normally
+ od.setBoxPosition(al.getHiddenSequences(), hiddenCols, vpranges);
+ }
+
+ /*
+ * Test that the box is positioned with the top left corner at xpos, ypos
+ * and with the original width and height
+ */
+ private void testBoxIsAtClickPoint(int xpos, int ypos)
+ {
+ mouseClick(od, xpos, ypos);
+ assertEquals(od.getBoxX(), xpos);
+ assertEquals(od.getBoxY(), ypos);
+ assertEquals(od.getBoxWidth(), boxWidth);
+ assertEquals(od.getBoxHeight(), boxHeight);
+
+ }
+
+ /*
+ * Hide sequences between start and end
+ */
+ private void hideSequences(int start, int end)
+ {
+ SequenceI[] allseqs = al.getSequencesArray();
+ SequenceGroup theseSeqs = new SequenceGroup();
+
+ for (int i = start; i <= end; i++)
+ {
+ theseSeqs.addSequence(allseqs[i], false);
+ al.getHiddenSequences().hideSequence(allseqs[i]);
+ }
+
+ hiddenRepSequences.put(allseqs[start], theseSeqs);
+ }
+}
package jalview.viewmodel;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
import jalview.analysis.AlignmentGenerator;
import jalview.datamodel.AlignmentI;
+import java.beans.PropertyChangeEvent;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
import org.testng.annotations.Test;
public class ViewportRangesTest {
AlignmentI al = gen.generate(20, 30, 1, 5, 5);
- @Test
+ @Test(groups = { "Functional" })
public void testViewportRanges()
{
ViewportRanges vr = new ViewportRanges(al);
assertEquals(vr.getEndSeq(), al.getHeight() - 1);
}
- @Test
+ @Test(groups = { "Functional" })
public void testGetAbsoluteAlignmentHeight()
{
ViewportRanges vr = new ViewportRanges(al);
assertEquals(vr.getAbsoluteAlignmentHeight(), al.getHeight() + 1);
}
- @Test
+ @Test(groups = { "Functional" })
public void testGetAbsoluteAlignmentWidth()
{
ViewportRanges vr = new ViewportRanges(al);
assertEquals(vr.getAbsoluteAlignmentWidth(), al.getWidth());
}
- @Test
+ @Test(groups = { "Functional" })
public void testSetEndRes()
{
ViewportRanges vr = new ViewportRanges(al);
vr.setEndRes(-1);
assertEquals(vr.getEndRes(), 0);
- vr.setEndRes(al.getWidth());
- assertEquals(vr.getEndRes(), al.getWidth() - 1);
-
vr.setEndRes(al.getWidth() - 1);
assertEquals(vr.getEndRes(), al.getWidth() - 1);
}
- @Test
+ @Test(groups = { "Functional" })
public void testSetEndSeq()
{
ViewportRanges vr = new ViewportRanges(al);
assertEquals(vr.getEndSeq(), al.getHeight() - 1);
}
- @Test
+ @Test(groups = { "Functional" })
public void testSetStartRes()
{
ViewportRanges vr = new ViewportRanges(al);
assertEquals(vr.getStartRes(), al.getWidth() - 1);
}
- @Test
+ @Test(groups = { "Functional" })
public void testSetStartSeq()
{
ViewportRanges vr = new ViewportRanges(al);
vr.setStartSeq(-1);
assertEquals(vr.getStartSeq(), 0);
- vr.setStartSeq(al.getHeight());
- assertEquals(vr.getStartSeq(), al.getHeight() - 1);
+ vr.setStartSeq(al.getHeight() - vr.getViewportHeight() + 1);
+ assertEquals(vr.getStartSeq(), al.getHeight() - vr.getViewportHeight());
+
+ vr.setStartSeq(al.getHeight() - vr.getViewportHeight());
+ assertEquals(vr.getStartSeq(), al.getHeight() - vr.getViewportHeight());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetStartEndRes()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setStartEndRes(-1, -1);
+ assertEquals(vr.getStartRes(), 0);
+ assertEquals(vr.getEndRes(), 0);
+
+ vr.setStartEndRes(5, 19);
+ assertEquals(vr.getStartRes(), 5);
+ assertEquals(vr.getEndRes(), 19);
+
+ vr.setStartEndRes(al.getWidth(), al.getWidth());
+ assertEquals(vr.getEndRes(), al.getWidth());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetStartEndSeq()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setStartEndSeq(-1, -1);
+ assertEquals(vr.getStartSeq(), 0);
+ assertEquals(vr.getEndSeq(), 0);
+
+ vr.setStartEndSeq(5, 19);
+ assertEquals(vr.getStartSeq(), 5);
+ assertEquals(vr.getEndSeq(), 19);
+
+ vr.setStartEndSeq(al.getHeight(), al.getHeight());
+ assertEquals(vr.getEndSeq(), al.getHeight() - 1);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetViewportHeight()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportHeight(13);
+ assertEquals(vr.getViewportHeight(), 13);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetViewportWidth()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportWidth(13);
+ assertEquals(vr.getViewportWidth(), 13);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetViewportStartAndHeight()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportStartAndHeight(2, 6);
+ assertEquals(vr.getViewportHeight(), 6);
+ assertEquals(vr.getStartSeq(), 2);
+
+ // reset -ve values of start to 0
+ vr.setViewportStartAndHeight(-1, 7);
+ assertEquals(vr.getViewportHeight(), 7);
+ assertEquals(vr.getStartSeq(), 0);
+
+ // reset out of bounds start values to within bounds
+ vr.setViewportStartAndHeight(35, 5);
+ assertEquals(vr.getViewportHeight(), 5);
+ assertEquals(vr.getStartSeq(), 24);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetViewportStartAndWidth()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportStartAndWidth(2, 6);
+ assertEquals(vr.getViewportWidth(), 6);
+ assertEquals(vr.getStartRes(), 2);
+
+ // reset -ve values of start to 0
+ vr.setViewportStartAndWidth(-1, 7);
+ assertEquals(vr.getViewportWidth(), 7);
+ assertEquals(vr.getStartRes(), 0);
+
+ // reset out of bounds start values to within bounds
+ vr.setViewportStartAndWidth(35, 5);
+ assertEquals(vr.getViewportWidth(), 5);
+ assertEquals(vr.getStartRes(), 20);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testPageUpDown()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportStartAndHeight(8, 6);
+ vr.pageDown();
+ assertEquals(vr.getStartSeq(), 13);
+
+ vr.pageUp();
+ assertEquals(vr.getStartSeq(), 8);
+
+ vr.pageUp();
+ assertEquals(vr.getStartSeq(), 3);
+
+ vr.pageUp();
+ // pageup does not go beyond 0, viewport height stays the same
+ assertEquals(vr.getStartSeq(), 0);
+ assertEquals(vr.getViewportHeight(), 6);
+
+ vr.pageDown();
+ vr.pageDown();
+ vr.pageDown();
+ vr.pageDown();
+ vr.pageDown();
+
+ // pagedown to bottom does not go beyond end, and height stays same
+ assertEquals(vr.getStartSeq(), 23);
+ assertEquals(vr.getViewportHeight(), 6);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testScrollUp()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportStartAndHeight(1, 5);
+ vr.scrollUp(true);
+ assertEquals(vr.getStartSeq(), 0);
+ // can't scroll above top
+ vr.scrollUp(true);
+ assertEquals(vr.getStartSeq(), 0);
+
+ vr.setViewportStartAndHeight(23, 5);
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 24);
+ // can't scroll beyond bottom
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 24);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testScrollRight()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportStartAndWidth(1, 5);
+ vr.scrollRight(false);
+ assertEquals(vr.getStartRes(), 0);
+ // can't scroll left past start
+ vr.scrollRight(false);
+ assertEquals(vr.getStartRes(), 0);
+
+ vr.setViewportStartAndWidth(19, 5);
+ vr.scrollRight(true);
+ assertEquals(vr.getStartRes(), 20);
+ // can't scroll right past end
+ vr.scrollRight(true);
+ assertEquals(vr.getStartRes(), 20);
+ }
+
+ @Test(groups = { "Functional" })
+ public void testScrollToWrappedVisible()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportStartAndWidth(5, 10);
+
+ vr.scrollToWrappedVisible(0);
+ assertEquals(vr.getStartRes(), 0);
+
+ vr.scrollToWrappedVisible(10);
+ assertEquals(vr.getStartRes(), 10);
+
+ vr.scrollToWrappedVisible(15);
+ assertEquals(vr.getStartRes(), 10);
+ }
+
+ // leave until JAL-2388 is merged and we can do without viewport
+ /*@Test(groups = { "Functional" })
+ public void testScrollToVisible()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ vr.setViewportStartAndWidth(12,5);
+ vr.setViewportStartAndHeight(10,6);
+ vr.scrollToVisible(13,14)
+
+ // no change
+ assertEquals(vr.getStartRes(), 12);
+ assertEquals(vr.getStartSeq(), 10);
+
+ vr.scrollToVisible(5,6);
+ assertEquals(vr.getStartRes(), 5);
+ assertEquals(vr.getStartSeq(), 6);
+
+ // test for hidden columns too
+ }*/
+
+ @Test(groups = { "Functional" })
+ public void testEventFiring()
+ {
+ ViewportRanges vr = new ViewportRanges(al);
+ MockPropChangeListener l = new MockPropChangeListener(vr);
+ List<String> emptylist = new ArrayList<String>();
+
+ vr.setViewportWidth(5);
+ vr.setViewportHeight(5);
+ l.reset();
+
+ // one event fired when startRes is called with new value
+ vr.setStartRes(4);
+ assertTrue(l.verify(1, Arrays.asList("startres")));
+ l.reset();
+
+ // no event fired for same value
+ vr.setStartRes(4);
+ assertTrue(l.verify(0, emptylist));
+ l.reset();
+
+ vr.setEndRes(10);
+ assertTrue(l.verify(1, Arrays.asList("startres")));
+ l.reset();
+
+ // no event fired for same value
+ vr.setEndRes(10);
+ assertTrue(l.verify(0, emptylist));
+ l.reset();
+
+ vr.setStartSeq(4);
+ assertTrue(l.verify(1, Arrays.asList("startseq")));
+ l.reset();
+
+ vr.setStartSeq(4);
+ assertTrue(l.verify(0, emptylist));
+ l.reset();
+
+ vr.setEndSeq(10);
+ assertTrue(l.verify(1, Arrays.asList("startseq")));
+ l.reset();
+
+ vr.setEndSeq(10);
+ assertTrue(l.verify(0, emptylist));
+ l.reset();
+
+ vr.setStartEndRes(2, 15);
+ assertTrue(l.verify(1, Arrays.asList("startres")));
+ l.reset();
+
+ vr.setStartEndRes(2, 15);
+ assertTrue(l.verify(0, emptylist));
+ l.reset();
+
+ // check new value fired by event is corrected startres
+ vr.setStartEndRes(-1, 5);
+ assertTrue(l.verify(1, Arrays.asList("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)));
+ l.reset();
+
+ vr.setStartEndSeq(2, 15);
+ assertTrue(l.verify(1, Arrays.asList("startseq")));
+ l.reset();
+
+ vr.setStartEndSeq(2, 15);
+ assertTrue(l.verify(0, emptylist));
+ l.reset();
+
+ vr.setStartEndRes(2, 2); // so seq and res values should be different, in
+ // case of transposing in code
+ l.reset();
- vr.setStartSeq(al.getHeight() - 1);
- assertEquals(vr.getStartSeq(), al.getHeight() - 1);
+ // check new value fired by event is corrected startseq
+ vr.setStartEndSeq(-1, 5);
+ assertTrue(l.verify(1, Arrays.asList("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)));
+ l.reset();
+
+ // reset for later tests
+ vr.setStartEndSeq(2, 15);
+ l.reset();
+
+ // test viewport height and width setting triggers event
+ vr.setViewportHeight(10);
+ assertTrue(l.verify(1, Arrays.asList("endseq")));
+ l.reset();
+
+ vr.setViewportWidth(18);
+ assertTrue(l.verify(1, Arrays.asList("endres")));
+ l.reset();
+
+ // already has seq start set to 2, so triggers endseq
+ vr.setViewportStartAndHeight(2, 16);
+ assertTrue(l.verify(1, Arrays.asList("endseq")));
+ l.reset();
+
+ vr.setViewportStartAndWidth(1, 14);
+ assertTrue(l.verify(1, Arrays.asList("startres")));
+ l.reset();
+
+ // test page up/down triggers event
+ vr.pageUp();
+ assertTrue(l.verify(1, Arrays.asList("startseq")));
+ l.reset();
+
+ vr.pageDown();
+ assertTrue(l.verify(1, Arrays.asList("startseq")));
+ l.reset();
+
+ // test scrolling triggers event
+ vr.scrollUp(true);
+ assertTrue(l.verify(1, Arrays.asList("startseq")));
+ l.reset();
+
+ vr.scrollUp(false);
+ assertTrue(l.verify(1, Arrays.asList("startseq")));
+ l.reset();
+
+ vr.scrollRight(true);
+ assertTrue(l.verify(1, Arrays.asList("startres")));
+ l.reset();
+
+ vr.scrollRight(false);
+ assertTrue(l.verify(1, Arrays.asList("startres")));
+ l.reset();
+
+ // TODO test scrollToVisibble once hidden columns JAL-2388 merged in
+ // to avoid somersaults with align viewport
+ /*vr.scrollToVisible(10, 10);
+ assertTrue(l.verify(1, Arrays.asList("startres")));
+ l.reset();*/
+
+ vr.scrollToWrappedVisible(5);
+ assertTrue(l.verify(1, Arrays.asList("startres")));
+ l.reset();
+ }
+}
+
+// mock listener for property change events
+class MockPropChangeListener implements ViewportListenerI
+{
+ private int firecount = 0;
+
+ private List<String> events = new ArrayList<String>();
+
+ private List<Integer> newvalues = new ArrayList<Integer>();
+
+ public MockPropChangeListener(ViewportRanges vr)
+ {
+ vr.addPropertyChangeListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ firecount++;
+ events.add(evt.getPropertyName());
+ newvalues.add((Integer) evt.getNewValue());
+ }
+
+ public boolean verify(int count, List<String> eventslist,
+ List<Integer> valueslist)
+ {
+ return (count == firecount) && events.equals(eventslist)
+ && newvalues.equals(valueslist);
+ }
+
+ public boolean verify(int count, List<String> eventslist)
+ {
+ return (count == firecount) && events.equals(eventslist);
+ }
+
+ public void reset()
+ {
+ firecount = 0;
+ events.clear();
+ newvalues.clear();
}
}