From fd05a125d7fcad86e086893e27e1026feeaae812 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Wed, 25 Jul 2018 11:43:21 +0100 Subject: [PATCH] JAL-3072 SeqPanel.stopScrolling on mouse up in scale or annotation panel --- src/jalview/gui/IdPanel.java | 58 +++++++++------ src/jalview/gui/ScalePanel.java | 9 ++- src/jalview/gui/SeqPanel.java | 153 +++++++++++++++++++++++---------------- 3 files changed, 132 insertions(+), 88 deletions(-) diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java index a183144..3f43008 100755 --- a/src/jalview/gui/IdPanel.java +++ b/src/jalview/gui/IdPanel.java @@ -28,6 +28,7 @@ import jalview.io.SequenceAnnotationReport; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.viewmodel.AlignmentViewport; +import jalview.viewmodel.ViewportRanges; import java.awt.BorderLayout; import java.awt.event.MouseEvent; @@ -224,7 +225,7 @@ public class IdPanel extends JPanel { if (scrollThread != null) { - scrollThread.running = false; + scrollThread.stopScrolling(); } } @@ -408,7 +409,7 @@ public class IdPanel extends JPanel { if (scrollThread != null) { - scrollThread.running = false; + scrollThread.stopScrolling(); } mouseDragging = false; @@ -457,24 +458,42 @@ public class IdPanel extends JPanel this.idCanvas = idCanvas; } - // this class allows scrolling off the bottom of the visible alignment + /** + * Performs scrolling of the visible alignment up or down, adding newly + * visible sequences to the current selection + */ class ScrollThread extends Thread { - boolean running = false; + private boolean running = false; - boolean up = true; + private boolean up; + /** + * Constructor for a thread that scrolls either up or down + * + * @param up + */ public ScrollThread(boolean up) { this.up = up; + setName("IdPanel$ScrollThread$" + String.valueOf(up)); start(); } + /** + * Sets a flag to stop the scrolling + */ public void stopScrolling() { running = false; } + /** + * Scrolls the alignment either up or down, one row at a time, adding newly + * visible sequences to the current selection. Speed is limited to a maximum + * of ten rows per second. The thread exits when the end of the alignment is + * reached or a flag is set to stop it. + */ @Override public void run() { @@ -482,29 +501,20 @@ public class IdPanel extends JPanel while (running) { - if (av.getRanges().scrollUp(up)) + ViewportRanges ranges = IdPanel.this.av.getRanges(); + if (ranges.scrollUp(up)) { - // scroll was ok, so add new sequence to selection - int seq = av.getRanges().getStartSeq(); - - if (!up) - { - seq = av.getRanges().getEndSeq(); - } - - if (seq < lastid) - { - selectSeqs(lastid - 1, seq); - } - else if (seq > lastid) - { - selectSeqs(lastid + 1, seq); - } - - lastid = seq; + int toSeq = up ? ranges.getStartSeq() : ranges.getEndSeq(); + int fromSeq = toSeq < lastid ? lastid - 1 : lastid + 1; + IdPanel.this.selectSeqs(fromSeq, toSeq); + + lastid = toSeq; } else { + /* + * scroll did nothing - reached limit of visible alignment + */ running = false; } diff --git a/src/jalview/gui/ScalePanel.java b/src/jalview/gui/ScalePanel.java index e6bba02..581fb7d 100755 --- a/src/jalview/gui/ScalePanel.java +++ b/src/jalview/gui/ScalePanel.java @@ -275,6 +275,7 @@ public class ScalePanel extends JPanel public void mouseReleased(MouseEvent evt) { mouseDragging = false; + ap.getSeqPanel().stopScrolling(); int res = (evt.getX() / av.getCharWidth()) + av.getRanges().getStartRes(); @@ -356,16 +357,20 @@ public class ScalePanel extends JPanel { if (mouseDragging) { - ap.getSeqPanel().scrollCanvas(null); + ap.getSeqPanel().stopScrolling(); } } + /** + * Action on leaving the panel bounds with mouse drag in progress is to start + * scrolling the alignment in the direction of the mouse + */ @Override public void mouseExited(MouseEvent evt) { if (mouseDragging) { - ap.getSeqPanel().scrollCanvas(evt); + ap.getSeqPanel().startScrolling(evt.getPoint()); } } diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 8b2e7bc..134b337 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -48,6 +48,7 @@ import jalview.util.MappingUtils; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.viewmodel.AlignmentViewport; +import jalview.viewmodel.ViewportRanges; import java.awt.BorderLayout; import java.awt.Color; @@ -628,13 +629,14 @@ public class SeqPanel extends JPanel return; } - if (!editingSeqs) + if (editingSeqs) + { + endEditing(); + } + else { doMouseReleasedDefineMode(evt, didDrag); - return; } - - endEditing(); } /** @@ -1161,9 +1163,9 @@ public class SeqPanel extends JPanel } mouseDragging = true; - if ((scrollThread != null) && (scrollThread.isRunning())) + if (scrollThread != null) { - scrollThread.setEvent(evt); + scrollThread.setMousePosition(evt.getPoint()); } } @@ -1575,10 +1577,10 @@ public class SeqPanel extends JPanel } /** - * 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) @@ -1587,29 +1589,19 @@ public class SeqPanel extends JPanel { 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(); } @@ -2008,89 +2000,126 @@ public class SeqPanel extends JPanel 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) { - av.getRanges().scrollRight(false); + scrolled |= ranges.scrollRight(false); } - else if (mouseDragging && (evt.getX() >= getWidth())) + else if (mousePos.x >= getWidth()) { - av.getRanges().scrollRight(true); + scrolled |= ranges.scrollRight(true); + } + if (!scrolled) + { + /* + * we have reached the limit of the visible alignment - quit + */ + threadRunning = false; + SeqPanel.this.ap.repaint(); } } -- 1.7.10.2