JAL-2934 scroll more for faster mousewheel / trackpad movement
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 1 Apr 2019 14:06:10 +0000 (15:06 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 1 Apr 2019 14:06:10 +0000 (15:06 +0100)
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/IdPanel.java
src/jalview/gui/SeqPanel.java

index 92b9a50..77a76fd 100644 (file)
@@ -62,6 +62,7 @@ import java.io.FileWriter;
 import java.io.PrintWriter;
 import java.util.List;
 
+import javax.swing.BoundedRangeModel;
 import javax.swing.SwingUtilities;
 
 /**
@@ -680,6 +681,22 @@ public class AlignmentPanel extends GAlignmentPanel implements
   }
 
   /**
+   * Answers true if the panel has no horizontal scrollbar, or the scrollbar is
+   * at its rightmost position, else false.
+   * 
+   * @return
+   */
+  boolean isScrolledFullyRight()
+  {
+    if (hscroll == null)
+    {
+      return true;
+    }
+    BoundedRangeModel model = hscroll.getModel();
+    return (model.getExtent() + model.getValue() >= model.getMaximum());
+  }
+
+  /**
    * Respond to adjustment event when horizontal or vertical scrollbar is
    * changed
    * 
index 16db94c..5b5a884 100755 (executable)
@@ -176,21 +176,27 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     renderer = new AnnotationRenderer();
   }
 
+  /**
+   * Responds to a mouse wheel movement by scrolling the annotations up or down.
+   * Annotation labels are scrolled via method adjustmentValueChanged when the
+   * vertical scrollbar is adjusted.
+   * <p>
+   * If shift is pressed, then scrolling is left or right instead, and is
+   * delegated to AlignmentPanel, so that both sequences and annotations are
+   * scrolled together.
+   * <p>
+   * This object is a MouseWheelListener to AnnotationLabels, so mouse wheel
+   * events over the labels are delegated to this method.
+   * <p>
+   * Note that this method may also be fired by scrolling with a gesture on a
+   * trackpad.
+   */
   @Override
   public void mouseWheelMoved(MouseWheelEvent e)
   {
     if (e.isShiftDown())
     {
-      e.consume();
-      double wheelRotation = e.getPreciseWheelRotation();
-      if (wheelRotation > 0)
-      {
-        av.getRanges().scrollRight(true);
-      }
-      else if (wheelRotation < 0)
-      {
-        av.getRanges().scrollRight(false);
-      }
+      ap.getSeqPanel().mouseWheelMoved(e);
     }
     else
     {
index d11d7a1..298d265 100755 (executable)
@@ -36,8 +36,6 @@ import java.awt.BorderLayout;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
 import java.util.List;
 
 import javax.swing.JPanel;
@@ -48,12 +46,9 @@ import javax.swing.ToolTipManager;
 /**
  * This panel hosts alignment sequence ids and responds to mouse clicks on them,
  * as well as highlighting ids matched by a search from the Find menu.
- * 
- * @author $author$
- * @version $Revision$
  */
 public class IdPanel extends JPanel
-        implements MouseListener, MouseMotionListener, MouseWheelListener
+        implements MouseListener, MouseMotionListener
 {
   private IdCanvas idCanvas;
 
@@ -91,7 +86,7 @@ public class IdPanel extends JPanel
     add(getIdCanvas(), BorderLayout.CENTER);
     addMouseListener(this);
     addMouseMotionListener(this);
-    addMouseWheelListener(this);
+    addMouseWheelListener(alignPanel.getSeqPanel());
     ToolTipManager.sharedInstance().registerComponent(this);
   }
 
@@ -173,38 +168,6 @@ public class IdPanel extends JPanel
   }
 
   /**
-   * Response to the mouse wheel by scrolling the alignment panel.
-   */
-  @Override
-  public void mouseWheelMoved(MouseWheelEvent e)
-  {
-    e.consume();
-    double wheelRotation = e.getPreciseWheelRotation();
-    if (wheelRotation > 0)
-    {
-      if (e.isShiftDown())
-      {
-        av.getRanges().scrollRight(true);
-      }
-      else
-      {
-        av.getRanges().scrollUp(false);
-      }
-    }
-    else if (wheelRotation < 0)
-    {
-      if (e.isShiftDown())
-      {
-        av.getRanges().scrollRight(false);
-      }
-      else
-      {
-        av.getRanges().scrollUp(true);
-      }
-    }
-  }
-
-  /**
    * Handle a mouse click event. Currently only responds to a double-click. The
    * action is to try to open a browser window at a URL that searches for the
    * selected sequence id. The search URL is configured in Preferences |
index 1176df5..9cc9d29 100644 (file)
@@ -1996,32 +1996,85 @@ public class SeqPanel extends JPanel
     }
   }
 
+  /**
+   * Responds to a mouse wheel movement by scrolling the alignment
+   * <ul>
+   * <li>left or right, if the shift key is down, else up or down</li>
+   * <li>right (or down) if the reported mouse movement is positive</li>
+   * <li>left (or up) if the reported mouse movement is negative</li>
+   * </ul>
+   * Note that this method may also be fired by scrolling with a gesture on a
+   * trackpad.
+   */
   @Override
   public void mouseWheelMoved(MouseWheelEvent e)
   {
     e.consume();
     double wheelRotation = e.getPreciseWheelRotation();
+
+    /*
+     * scroll more for large (fast) mouse movements
+     */
+    int size = 1 + (int) Math.abs(wheelRotation);
+
     if (wheelRotation > 0)
     {
       if (e.isShiftDown())
       {
-        av.getRanges().scrollRight(true);
-
+        /*
+         * scroll right
+         * stop trying to scroll right when limit is reached (saves
+         * expensive calls to Alignment.getWidth())
+         */
+        while (size-- > 0 && !ap.isScrolledFullyRight())
+        {
+          if (!av.getRanges().scrollRight(true))
+          {
+            break;
+          }
+        }
       }
       else
       {
-        av.getRanges().scrollUp(false);
+        /*
+         * scroll down
+         */
+        while (size-- > 0)
+        {
+          if (!av.getRanges().scrollUp(false))
+          {
+            break;
+          }
+        }
       }
     }
     else if (wheelRotation < 0)
     {
       if (e.isShiftDown())
       {
-        av.getRanges().scrollRight(false);
+        /*
+         * scroll left
+         */
+        while (size-- > 0)
+        {
+          if (!av.getRanges().scrollRight(false))
+          {
+            break;
+          }
+        }
       }
       else
       {
-        av.getRanges().scrollUp(true);
+        /*
+         * scroll up
+         */
+        while (size-- > 0)
+        {
+          if (!av.getRanges().scrollUp(true))
+          {
+            break;
+          }
+        }
       }
     }