import jalview.util.MessageManager;
import jalview.util.Platform;
import jalview.viewmodel.AlignmentViewport;
+import jalview.viewmodel.ViewportRanges;
import java.awt.BorderLayout;
import java.awt.Color;
if (av.hasHiddenColumns())
{
res = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(res);
+ .visibleToAbsoluteColumn(res);
}
return res;
int original = seqCanvas.cursorX - dx;
int maxWidth = av.getAlignment().getWidth();
- // TODO: once JAL-2759 is ready, change this loop to something more
- // efficient
- while (!hidden.isVisible(seqCanvas.cursorX)
- && seqCanvas.cursorX < maxWidth && seqCanvas.cursorX > 0
- && dx != 0)
+ if (!hidden.isVisible(seqCanvas.cursorX))
{
- seqCanvas.cursorX += dx;
+ int visx = hidden.absoluteToVisibleColumn(seqCanvas.cursorX - dx);
+ int[] region = hidden.getRegionWithEdgeAtRes(visx);
+
+ if (region != null) // just in case
+ {
+ if (dx == 1)
+ {
+ // moving right
+ seqCanvas.cursorX = region[1] + 1;
+ }
+ else if (dx == -1)
+ {
+ // moving left
+ seqCanvas.cursorX = region[0] - 1;
+ }
+ }
+ seqCanvas.cursorX = (seqCanvas.cursorX < 0) ? 0 : seqCanvas.cursorX;
}
if (seqCanvas.cursorX >= maxWidth
{
// scrollToWrappedVisible expects x-value to have hidden cols subtracted
int x = av.getAlignment().getHiddenColumns()
- .findColumnPosition(seqCanvas.cursorX);
+ .absoluteToVisibleColumn(seqCanvas.cursorX);
av.getRanges().scrollToWrappedVisible(x);
}
else
return;
}
- if (!editingSeqs)
+ if (editingSeqs)
+ {
+ endEditing();
+ }
+ else
{
doMouseReleasedDefineMode(evt, didDrag);
- return;
}
-
- endEditing();
}
/**
}
mouseDragging = true;
- if ((scrollThread != null) && (scrollThread.isRunning()))
+ if (scrollThread != null)
{
- scrollThread.setEvent(evt);
+ scrollThread.setMousePosition(evt.getPoint());
}
}
{
fixedColumns = true;
int y1 = av.getAlignment().getHiddenColumns()
- .getHiddenBoundaryLeft(startres);
+ .getNextHiddenBoundary(true, startres);
int y2 = av.getAlignment().getHiddenColumns()
- .getHiddenBoundaryRight(startres);
+ .getNextHiddenBoundary(false, startres);
if ((insertGap && startres > y1 && lastres < y1)
|| (!insertGap && startres < y2 && lastres > y2))
if (sg.getSize() == av.getAlignment().getHeight())
{
if ((av.hasHiddenColumns() && startres < av.getAlignment()
- .getHiddenColumns().getHiddenBoundaryRight(startres)))
+ .getHiddenColumns()
+ .getNextHiddenBoundary(false, startres)))
{
endEditing();
return;
}
/**
- * DOCUMENT ME!
+ * On reentering the panel, stops any scrolling that was started on dragging
+ * out of the panel
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mouseEntered(MouseEvent e)
{
oldSeq = 0;
}
-
- if ((scrollThread != null) && (scrollThread.isRunning()))
- {
- scrollThread.stopScrolling();
- scrollThread = null;
- }
+ stopScrolling();
}
/**
- * DOCUMENT ME!
+ * On leaving the panel, if the mouse is being dragged, starts a thread to
+ * scroll it until the mouse is released (in unwrapped mode only)
*
* @param e
- * DOCUMENT ME!
*/
@Override
public void mouseExited(MouseEvent e)
{
- if (av.getWrapAlignment())
- {
- return;
- }
-
- if (mouseDragging && scrollThread == null)
+ if (!av.getWrapAlignment() && mouseDragging && scrollThread == null)
{
scrollThread = new ScrollThread();
}
public void mouseWheelMoved(MouseWheelEvent e)
{
e.consume();
- if (e.getWheelRotation() > 0)
+ double wheelRotation = e.getPreciseWheelRotation();
+ if (wheelRotation > 0)
{
if (e.isShiftDown())
{
av.getRanges().scrollUp(false);
}
}
- else
+ else if (wheelRotation < 0)
{
if (e.isShiftDown())
{
return;
}
- if (res >= av.getAlignment().getWidth())
- {
- res = av.getAlignment().getWidth() - 1;
- }
+ res = Math.min(res, av.getAlignment().getWidth()-1);
if (stretchGroup.getEndRes() == res)
{
mouseDragging = true;
- if ((scrollThread != null) && (scrollThread.isRunning()))
+ if (scrollThread != null)
{
- scrollThread.setEvent(evt);
+ scrollThread.setMousePosition(evt.getPoint());
}
}
- void scrollCanvas(MouseEvent evt)
+ /**
+ * Stops the scroll thread if it is running
+ */
+ void stopScrolling()
{
- if (evt == null)
+ if (scrollThread != null)
{
- if ((scrollThread != null) && (scrollThread.isRunning()))
- {
- scrollThread.stopScrolling();
- scrollThread = null;
- }
- mouseDragging = false;
+ scrollThread.stopScrolling();
+ scrollThread = null;
}
- else
- {
- if (scrollThread == null)
- {
- scrollThread = new ScrollThread();
- }
+ mouseDragging = false;
+ }
- mouseDragging = true;
- scrollThread.setEvent(evt);
+ /**
+ * Starts a thread to scroll the alignment, towards a given mouse position
+ * outside the panel bounds
+ *
+ * @param mousePos
+ */
+ void startScrolling(Point mousePos)
+ {
+ if (scrollThread == null)
+ {
+ scrollThread = new ScrollThread();
}
+ mouseDragging = true;
+ scrollThread.setMousePosition(mousePos);
}
- // this class allows scrolling off the bottom of the visible alignment
+ /**
+ * Performs scrolling of the visible alignment left, right, up or down
+ */
class ScrollThread extends Thread
{
- MouseEvent evt;
+ private Point mousePos;
private volatile boolean threadRunning = true;
+ /**
+ * Constructor
+ */
public ScrollThread()
{
+ setName("SeqPanel$ScrollThread");
start();
}
- public void setEvent(MouseEvent e)
+ /**
+ * Sets the position of the mouse that determines the direction of the
+ * scroll to perform
+ *
+ * @param p
+ */
+ public void setMousePosition(Point p)
{
- evt = e;
+ mousePos = p;
}
+ /**
+ * Sets a flag that will cause the thread to exit
+ */
public void stopScrolling()
{
threadRunning = false;
}
- public boolean isRunning()
- {
- return threadRunning;
- }
-
+ /**
+ * Scrolls the alignment left or right, and/or up or down, depending on the
+ * last notified mouse position, until the limit of the alignment is
+ * reached, or a flag is set to stop the scroll
+ */
@Override
public void run()
{
- while (threadRunning)
+ while (threadRunning && mouseDragging)
{
- if (evt != null)
+ if (mousePos != null)
{
- if (mouseDragging && (evt.getY() < 0)
- && (av.getRanges().getStartSeq() > 0))
+ boolean scrolled = false;
+ ViewportRanges ranges = SeqPanel.this.av.getRanges();
+
+ /*
+ * scroll up or down
+ */
+ if (mousePos.y < 0)
{
- av.getRanges().scrollUp(true);
+ // mouse is above this panel - try scroll up
+ scrolled = ranges.scrollUp(true);
}
-
- if (mouseDragging && (evt.getY() >= getHeight()) && (av
- .getAlignment().getHeight() > av.getRanges().getEndSeq()))
+ else if (mousePos.y >= getHeight())
{
- av.getRanges().scrollUp(false);
+ // mouse is below this panel - try scroll down
+ scrolled = ranges.scrollUp(false);
}
- if (mouseDragging && (evt.getX() < 0))
+ /*
+ * scroll left or right
+ */
+ if (mousePos.x < 0)
+ {
+ scrolled |= ranges.scrollRight(false);
+ }
+ else if (mousePos.x >= getWidth())
{
- av.getRanges().scrollRight(false);
+ scrolled |= ranges.scrollRight(true);
}
- else if (mouseDragging && (evt.getX() >= getWidth()))
+ if (!scrolled)
{
- av.getRanges().scrollRight(true);
+ /*
+ * we have reached the limit of the visible alignment - quit
+ */
+ threadRunning = false;
+ SeqPanel.this.ap.repaint();
}
}
return true;
}
+
+ /**
+ *
+ * @return null or last search results handled by this panel
+ */
+ public SearchResultsI getLastSearchResults()
+ {
+ return lastSearchResults;
+ }
}