{
seqCanvas.calculateWrappedGeometry(seqCanvas.getWidth(),
seqCanvas.getHeight());
- // int gapHeight = charHeight;
- // if (av.getScaleAboveWrapped())
- // {
- // gapHeight += charHeight;
- // }
- //
- // final int alignmentHeightPixels = gapHeight
- // + alignmentHeight * charHeight;
- // int cHeight = alignmentHeightPixels;
- // if (av.isShowAnnotation())
- // {
- // cHeight += (seqCanvas.getAnnotationHeight() +
- // SeqCanvas.SEQS_ANNOTATION_GAP);
- // }
/*
- * yPos modulo repeating width height
+ * yPos modulo height of repeating width
*/
int yOffsetPx = y % seqCanvas.wrappedRepeatHeightPx;
int res = 0;
int x = evt.getX();
- int startRes = av.getRanges().getStartRes();
+ final int startRes = av.getRanges().getStartRes();
+ final int charWidth = av.getCharWidth();
+
if (av.getWrapAlignment())
{
int hgap = av.getCharHeight();
int y = evt.getY();
y = Math.max(0, y - hgap);
- x = Math.max(0, x - seqCanvas.getLabelWidthWest());
+ x -= seqCanvas.getLabelWidthWest();
+ if (x < 0)
+ {
+ // mouse is over left scale
+ return -1;
+ }
int cwidth = seqCanvas.getWrappedCanvasWidth(this.getWidth());
if (cwidth < 1)
{
return 0;
}
+ if (x >= cwidth * charWidth)
+ {
+ // mouse is over right scale
+ return -1;
+ }
wrappedBlock = y / cHeight;
wrappedBlock += startRes / cwidth;
// allow for wrapped view scrolled right (possible from Overview)
int startOffset = startRes % cwidth;
res = wrappedBlock * cwidth + startOffset
- + Math.min(cwidth - 1, x / av.getCharWidth());
+ + Math.min(cwidth - 1, x / charWidth);
}
else
{
* rather than right-hand gutter
*/
x = Math.min(x, seqCanvas.getX() + seqCanvas.getWidth());
- res = (x / av.getCharWidth()) + startRes;
+ res = (x / charWidth) + startRes;
res = Math.min(res, av.getRanges().getEndRes());
}
public void mouseReleased(MouseEvent evt)
{
MousePos pos = findMousePosition(evt);
- if (pos.annotationIndex != -1)
+ if (pos.isOverAnnotation() || pos.seqIndex == -1 || pos.column == -1)
{
- // mouse is over annotation row in wrapped mode
return;
}
{
lastMousePress = evt.getPoint();
MousePos pos = findMousePosition(evt);
- if (pos.annotationIndex != -1)
+ if (pos.isOverAnnotation() || pos.seqIndex == -1 || pos.column == -1)
{
- // mouse is over an annotation row in wrapped mode
return;
}
int seq = pos.seqIndex;
int res = pos.column;
- if (seq < 0 || res < 0)
- {
- return;
- }
-
if ((seq < av.getAlignment().getHeight())
&& (res < av.getAlignment().getSequenceAt(seq).getLength()))
{
lastMousePosition = null;
setToolTipText(null);
lastTooltip = null;
- ap.alignFrame.statusBar.setText("");
+ ap.alignFrame.setStatus("");
return;
}
final int column = pos.column;
final int rowIndex = pos.annotationIndex;
- if (!av.getWrapAlignment() || !av.isShowAnnotation() || rowIndex < 0)
+ if (column < 0 || !av.getWrapAlignment() || !av.isShowAnnotation()
+ || rowIndex < 0)
{
return;
}
String msg = AnnotationPanel.getStatusMessage(av.getAlignment(), column,
anns[rowIndex]);
- ap.alignFrame.statusBar.setText(msg);
+ ap.alignFrame.setStatus(msg);
}
private Point lastp = null;
text.append(" (").append(Integer.toString(residuePos)).append(")");
}
- ap.alignFrame.statusBar.setText(text.toString());
+ ap.alignFrame.setStatus(text.toString());
}
/**
public void mouseDragged(MouseEvent evt)
{
MousePos pos = findMousePosition(evt);
- if (pos.isOverAnnotation())
+ if (pos.isOverAnnotation() || pos.column == -1)
{
- // mouse is over annotation row in wrapped mode
return;
}
if (!editingSeqs)
{
- doMouseDraggedDefineMode(evt);
+ dragStretchGroup(evt);
return;
}
}
message.append(Math.abs(startres - lastres) + " gaps.");
- ap.alignFrame.statusBar.setText(message.toString());
+ ap.alignFrame.setStatus(message.toString());
// Are we editing within a selection group?
if (groupEditing || (sg != null
@Override
public void mouseExited(MouseEvent e)
{
+ ap.alignFrame.setStatus(" ");
if (av.getWrapAlignment())
{
return;
{
SequenceGroup sg = null;
MousePos pos = findMousePosition(evt);
- if (pos.isOverAnnotation())
+ if (pos.isOverAnnotation() || pos.seqIndex == -1 || pos.column == -1)
{
- // mouse is over annotation label in wrapped mode
return;
}
* find features at the position (if not gapped), or straddling
* the position (if at a gap)
*/
- SequenceI sequence = av.getAlignment().getSequenceAt(pos.seqIndex);// findSeq(evt));
+ SequenceI sequence = av.getAlignment().getSequenceAt(pos.seqIndex);
List<SequenceFeature> features = seqCanvas.getFeatureRenderer()
.findFeaturesAtColumn(sequence, column + 1);
*/
protected void doMousePressedDefineMode(MouseEvent evt, MousePos pos)
{
- if (pos.isOverAnnotation())
+ if (pos.isOverAnnotation() || pos.seqIndex == -1 || pos.column == -1)
{
- // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
- // MessageManager.getString(
- // "label.cannot_edit_annotations_in_wrapped_view"),
- // MessageManager.getString("label.wrapped_view_no_edit"),
- // JvOptionPane.WARNING_MESSAGE);
return;
}
startWrapBlock = wrappedBlock;
- if (seq < 0 || res < 0)
- {
- return;
- }
-
SequenceI sequence = av.getAlignment().getSequenceAt(seq);
if ((sequence == null) || (res > sequence.getLength()))
* true if this event is happening after a mouse drag (rather than a
* mouse down)
*/
- public void doMouseReleasedDefineMode(MouseEvent evt, boolean afterDrag)
+ protected void doMouseReleasedDefineMode(MouseEvent evt,
+ boolean afterDrag)
{
if (stretchGroup == null)
{
}
/**
- * DOCUMENT ME!
+ * Resizes the borders of a selection group depending on the direction of
+ * mouse drag
*
* @param evt
- * DOCUMENT ME!
*/
- public void doMouseDraggedDefineMode(MouseEvent evt)
+ protected void dragStretchGroup(MouseEvent evt)
{
+ if (stretchGroup == null)
+ {
+ return;
+ }
+
MousePos pos = findMousePosition(evt);
- if (pos.isOverAnnotation())
+ if (pos.isOverAnnotation() || pos.column == -1 || pos.seqIndex == -1)
{
- // mouse is over annotation in wrapped mode
return;
}
return;
}
- if (stretchGroup == null)
- {
- return;
- }
-
if (res >= av.getAlignment().getWidth())
{
res = av.getAlignment().getWidth() - 1;
import java.awt.Event;
import java.awt.event.MouseEvent;
+import javax.swing.JLabel;
+
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import junit.extensions.PA;
+
public class SeqPanelTest
{
AlignFrame af;
assertEquals(
alignFrame.alignPanel.getSeqPanel().setStatusMessage(
visAl.getSequenceAt(1), 1, 1), 2);
- assertEquals(alignFrame.statusBar.getText(),
+ assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
"Sequence 2 ID: Seq2 Residue: ALA (2)");
assertEquals(
alignFrame.alignPanel.getSeqPanel().setStatusMessage(
visAl.getSequenceAt(1), 4, 1), 3);
- assertEquals(alignFrame.statusBar.getText(),
+ assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
"Sequence 2 ID: Seq2 Residue: GLU (3)");
// no status message at a gap, returns next residue position to the right
assertEquals(
alignFrame.alignPanel.getSeqPanel().setStatusMessage(
visAl.getSequenceAt(1), 2, 1), 3);
- assertEquals(alignFrame.statusBar.getText(), "Sequence 2 ID: Seq2");
+ assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
+ "Sequence 2 ID: Seq2");
assertEquals(
alignFrame.alignPanel.getSeqPanel().setStatusMessage(
visAl.getSequenceAt(1), 3, 1), 3);
- assertEquals(alignFrame.statusBar.getText(), "Sequence 2 ID: Seq2");
+ assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
+ "Sequence 2 ID: Seq2");
}
@Test(groups = "Functional")
assertEquals(
alignFrame.alignPanel.getSeqPanel().setStatusMessage(
visAl.getSequenceAt(1), 1, 1), 2);
- assertEquals(alignFrame.statusBar.getText(),
+ assertEquals(((JLabel) PA.getValue(alignFrame, "statusBar")).getText(),
"Sequence 2 ID: Seq2 Residue: B (2)");
}
av.setScaleLeftWrapped(false);
av.setScaleRightWrapped(false);
alignFrame.alignPanel.paintAlignment(false, false);
+ waitForSwing(); // for Swing thread
final int charHeight = av.getCharHeight();
final int charWidth = av.getCharWidth();
av.setScaleLeftWrapped(false);
av.setScaleRightWrapped(false);
alignFrame.alignPanel.paintAlignment(false, false);
-
+ waitForSwing();
+
final int charHeight = av.getCharHeight();
final int charWidth = av.getCharWidth();
final int alignmentHeight = av.getAlignment().getHeight();
assertEquals(pos.seqIndex, 0);
assertEquals(pos.annotationIndex, -1);
}
+
@Test(groups = "Functional")
public void testFindMousePosition_wrapped_noAnnotations()
{
av.setScaleLeftWrapped(false);
av.setScaleRightWrapped(false);
alignFrame.alignPanel.paintAlignment(false, false);
-
+ waitForSwing();
+
final int charHeight = av.getCharHeight();
final int charWidth = av.getCharWidth();
final int alignmentHeight = av.getAlignment().getHeight();
assertEquals(pos.seqIndex, 0);
assertEquals(pos.annotationIndex, -1);
}
+
+ @Test(groups = "Functional")
+ public void testFindColumn_unwrapped()
+ {
+ Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "false");
+ AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
+ int x = 0;
+ final int charWidth = alignFrame.getViewport().getCharWidth();
+ assertTrue(charWidth > 0); // sanity check
+ assertEquals(alignFrame.getViewport().getRanges().getStartRes(), 0);
+
+ /*
+ * mouse at top left of unwrapped panel
+ */
+ MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
+ 0, 0, 0, false, 0);
+ assertEquals(testee.findColumn(evt), 0);
+
+ /*
+ * not quite one charWidth across
+ */
+ x = charWidth-1;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
+ 0, 0, 0, false, 0);
+ assertEquals(testee.findColumn(evt), 0);
+
+ /*
+ * one charWidth across
+ */
+ x = charWidth;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
+ false, 0);
+ assertEquals(testee.findColumn(evt), 1);
+
+ /*
+ * two charWidths across
+ */
+ x = 2 * charWidth;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
+ false, 0);
+ assertEquals(testee.findColumn(evt), 2);
+
+ /*
+ * limited to last column of seqcanvas
+ */
+ x = 20000;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
+ false, 0);
+ SeqCanvas seqCanvas = alignFrame.alignPanel.getSeqPanel().seqCanvas;
+ int w = seqCanvas.getWidth();
+ // limited to number of whole columns, base 0
+ int expected = w / charWidth - 1;
+ assertEquals(testee.findColumn(evt), expected);
+
+ /*
+ * hide columns 5-10 (base 1)
+ */
+ alignFrame.getViewport().hideColumns(4, 9);
+ x = 5 * charWidth + 2;
+ // x is in 6th visible column, absolute column 12, or 11 base 0
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
+ false, 0);
+ assertEquals(testee.findColumn(evt), 11);
+ }
+
+ @Test(groups = "Functional")
+ public void testFindColumn_wrapped()
+ {
+ Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", "true");
+ AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport av = alignFrame.getViewport();
+ av.setScaleAboveWrapped(false);
+ av.setScaleLeftWrapped(false);
+ av.setScaleRightWrapped(false);
+ alignFrame.alignPanel.paintAlignment(false, false);
+ // need to wait for repaint to finish!
+ waitForSwing();
+ SeqPanel testee = alignFrame.alignPanel.getSeqPanel();
+ int x = 0;
+ final int charWidth = av.getCharWidth();
+ assertTrue(charWidth > 0); // sanity check
+ assertEquals(av.getRanges().getStartRes(), 0);
+
+ /*
+ * mouse at top left of wrapped panel, no West (left) scale
+ */
+ MouseEvent evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
+ 0, 0, 0, false, 0);
+ assertEquals(testee.findColumn(evt), 0);
+
+ /*
+ * not quite one charWidth across
+ */
+ x = charWidth-1;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0,
+ 0, 0, 0, false, 0);
+ assertEquals(testee.findColumn(evt), 0);
+
+ /*
+ * one charWidth across
+ */
+ x = charWidth;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
+ false, 0);
+ assertEquals(testee.findColumn(evt), 1);
+
+ /*
+ * x over scale left (before drawn columns) results in -1
+ */
+ av.setScaleLeftWrapped(true);
+ alignFrame.alignPanel.paintAlignment(false, false);
+ waitForSwing();
+ SeqCanvas seqCanvas = testee.seqCanvas;
+ int labelWidth = (int) PA.getValue(seqCanvas, "labelWidthWest");
+ assertTrue(labelWidth > 0);
+ x = labelWidth - 1;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
+ false, 0);
+ assertEquals(testee.findColumn(evt), -1);
+
+ x = labelWidth;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
+ false, 0);
+ assertEquals(testee.findColumn(evt), 0);
+
+ /*
+ * x over right edge of last residue (including scale left)
+ */
+ int residuesWide = av.getRanges().getViewportWidth();
+ assertTrue(residuesWide > 0);
+ x = labelWidth + charWidth * residuesWide - 1;
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
+ false, 0);
+ assertEquals(testee.findColumn(evt), residuesWide - 1);
+
+ /*
+ * x over scale right (beyond drawn columns) results in -1
+ */
+ av.setScaleRightWrapped(true);
+ alignFrame.alignPanel.paintAlignment(false, false);
+ waitForSwing();
+ labelWidth = (int) PA.getValue(seqCanvas, "labelWidthEast");
+ assertTrue(labelWidth > 0);
+ int residuesWide2 = av.getRanges().getViewportWidth();
+ assertTrue(residuesWide2 > 0);
+ assertTrue(residuesWide2 < residuesWide); // available width reduced
+ x += 1; // just over left edge of scale right
+ evt = new MouseEvent(testee, Event.MOUSE_MOVE, 0L, 0, x, 0, 0, 0, 0,
+ false, 0);
+ assertEquals(testee.findColumn(evt), -1);
+
+ // todo add startRes offset, hidden columns
+
+ }
@BeforeClass(alwaysRun = true)
public static void setUpBeforeClass() throws Exception
{
Cache.loadProperties("test/jalview/io/testProps.jvprops");
Jalview.main(new String[] { "-nonews" });
}
+
+ /**
+ * waits a few ms for Swing to do something
+ */
+ synchronized void waitForSwing()
+ {
+ try
+ {
+ super.wait(10);
+ } catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
}