Merge branch 'bug/JAL-3099alignmentVisibleWidth' into merge/JAL-3099
[jalview.git] / src / jalview / appletgui / RotatableCanvas.java
index 179a91d..34f8ea5 100755 (executable)
@@ -41,7 +41,7 @@ import java.awt.event.KeyListener;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
-import java.util.Vector;
+import java.util.List;
 
 public class RotatableCanvas extends Panel implements MouseListener,
         MouseMotionListener, KeyListener, RotatableCanvasI
@@ -82,7 +82,7 @@ public class RotatableCanvas extends Panel implements MouseListener,
 
   int npoint;
 
-  Vector<SequencePoint> points;
+  List<SequencePoint> points;
 
   Point[] orig;
 
@@ -123,7 +123,7 @@ public class RotatableCanvas extends Panel implements MouseListener,
   }
 
   @Override
-  public void setPoints(Vector<SequencePoint> points, int npoint)
+  public void setPoints(List<SequencePoint> points, int npoint)
   {
     this.points = points;
     this.npoint = npoint;
@@ -134,7 +134,7 @@ public class RotatableCanvas extends Panel implements MouseListener,
 
     for (int i = 0; i < npoint; i++)
     {
-      SequencePoint sp = points.elementAt(i);
+      SequencePoint sp = points.get(i);
       orig[i] = sp.coord;
     }
 
@@ -344,29 +344,13 @@ public class RotatableCanvas extends Panel implements MouseListener,
 
   public void drawScene(Graphics g)
   {
-    // boolean darker = false;
-
-    int halfwidth = getSize().width / 2;
-    int halfheight = getSize().height / 2;
-
     for (int i = 0; i < npoint; i++)
     {
-      SequencePoint sp = points.elementAt(i);
-      int x = (int) ((sp.coord.x - centre.x) * scale) + halfwidth;
-      int y = (int) ((sp.coord.y - centre.y) * scale)
-              + halfheight;
-      float z = sp.coord.y - centre.z;
-
+      SequencePoint sp = points.get(i);
       SequenceI sequence = sp.getSequence();
-      if (av.getSequenceColour(sequence) == Color.black)
-      {
-        g.setColor(Color.white);
-      }
-      else
-      {
-        g.setColor(av.getSequenceColour(sequence));
-      }
-
+      Color sequenceColour = av.getSequenceColour(sequence);
+      g.setColor(
+              sequenceColour == Color.black ? Color.white : sequenceColour);
       if (av.getSelectionGroup() != null)
       {
         if (av.getSelectionGroup().getSequences(null)
@@ -375,12 +359,18 @@ public class RotatableCanvas extends Panel implements MouseListener,
           g.setColor(Color.gray);
         }
       }
-      if (z < 0)
+
+      if (sp.coord.z < centre.z)
       {
         g.setColor(g.getColor().darker());
       }
 
+      int halfwidth = getSize().width / 2;
+      int halfheight = getSize().height / 2;
+      int x = (int) ((sp.coord.x - centre.x) * scale) + halfwidth;
+      int y = (int) ((sp.coord.y - centre.y) * scale) + halfheight;
       g.fillRect(x - 3, y - 3, 6, 6);
+
       if (showLabels)
       {
         g.setColor(Color.red);
@@ -402,15 +392,37 @@ public class RotatableCanvas extends Panel implements MouseListener,
   @Override
   public void keyPressed(KeyEvent evt)
   {
-    if (evt.getKeyCode() == KeyEvent.VK_UP)
+    boolean shiftDown = evt.isShiftDown();
+    int keyCode = evt.getKeyCode();
+    if (keyCode == KeyEvent.VK_UP)
     {
-      scalefactor = (float) (scalefactor * 1.1);
-      scale = findScale();
+      if (shiftDown)
+      {
+        rotate(0f, -1f);
+      }
+      else
+      {
+        zoom(1.1f);
+      }
+    }
+    else if (keyCode == KeyEvent.VK_DOWN)
+    {
+      if (shiftDown)
+      {
+        rotate(0f, 1f);
+      }
+      else
+      {
+        zoom(0.9f);
+      }
     }
-    else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
+    else if (shiftDown && keyCode == KeyEvent.VK_LEFT)
     {
-      scalefactor = (float) (scalefactor * 0.9);
-      scale = findScale();
+      rotate(1f, 0f);
+    }
+    else if (shiftDown && keyCode == KeyEvent.VK_RIGHT)
+    {
+      rotate(-1f, 0f);
     }
     else if (evt.getKeyChar() == 's')
     {
@@ -509,31 +521,16 @@ public class RotatableCanvas extends Panel implements MouseListener,
     int xPos = evt.getX();
     int yPos = evt.getY();
 
-    RotatableMatrix rotmat = new RotatableMatrix();
-
-    rotmat.rotate(yPos - mouseY, Axis.X);
-    rotmat.rotate(xPos - mouseX, Axis.Y);
-
-    for (int i = 0; i < npoint; i++)
+    if (xPos == mouseX && yPos == mouseY)
     {
-      SequencePoint sp = points.elementAt(i);
-      sp.translateBack(centre);
-
-      // Now apply the rotation matrix
-      sp.coord = rotmat.vectorMultiply(sp.coord);
-
-      // Now translate back again
-      sp.translate(centre);
+      return;
     }
 
-    for (int i = 0; i < 3; i++)
-    {
-      axisEndPoints[i] = rotmat.vectorMultiply(axisEndPoints[i]);
-    }
-    mouseX = xPos;
-    mouseY = yPos;
+    int xDelta = xPos - mouseX;
+    int yDelta = yPos - mouseY;
 
-    paint(this.getGraphics());
+    rotate(xDelta, yDelta);
+    repaint();
   }
 
   public void rectSelect(int x1, int y1, int x2, int y2)
@@ -541,7 +538,7 @@ public class RotatableCanvas extends Panel implements MouseListener,
     // boolean changedSel = false;
     for (int i = 0; i < npoint; i++)
     {
-      SequencePoint sp = points.elementAt(i);
+      SequencePoint sp = points.get(i);
       int tmp1 = (int) ((sp.coord.x - centre.x) * scale
               + getSize().width / 2.0);
       int tmp2 = (int) ((sp.coord.y - centre.y) * scale
@@ -581,7 +578,7 @@ public class RotatableCanvas extends Panel implements MouseListener,
     for (int i = 0; i < npoint; i++)
     {
 
-      SequencePoint sp = points.elementAt(i);
+      SequencePoint sp = points.get(i);
       int px = (int) ((sp.coord.x - centre.x) * scale)
               + halfwidth;
       int py = (int) ((sp.coord.y - centre.y) * scale)
@@ -596,7 +593,7 @@ public class RotatableCanvas extends Panel implements MouseListener,
 
     if (found != -1)
     {
-      return points.elementAt(found).getSequence();
+      return points.get(found).getSequence();
     }
     else
     {
@@ -613,4 +610,70 @@ public class RotatableCanvas extends Panel implements MouseListener,
     resetAxes();
   }
 
+  @Override
+  public void zoom(float factor)
+  {
+    if (factor > 0f)
+    {
+      scalefactor *= factor;
+    }
+    scale = findScale();
+  }
+
+  @Override
+  public void rotate(float x, float y)
+  {
+    if (x == 0f && y == 0f)
+    {
+      return;
+    }
+  
+    /*
+     * get the identity transformation...
+     */
+    RotatableMatrix rotmat = new RotatableMatrix();
+  
+    /*
+     * rotate around the X axis for change in Y
+     * (mouse movement up/down); note we are equating a
+     * number of pixels with degrees of rotation here!
+     */
+    if (y != 0)
+    {
+      rotmat.rotate(y, Axis.X);
+    }
+  
+    /*
+     * rotate around the Y axis for change in X
+     * (mouse movement left/right)
+     */
+    if (x != 0)
+    {
+      rotmat.rotate(x, Axis.Y);
+    }
+  
+    /*
+     * apply the composite transformation to sequence points
+     */
+    for (int i = 0; i < npoint; i++)
+    {
+      SequencePoint sp = points.get(i);
+      sp.translate(-centre.x, -centre.y, -centre.z);
+
+      // Now apply the rotation matrix
+      sp.coord = rotmat.vectorMultiply(sp.coord);
+
+      // Now translate back again
+      sp.translate(centre.x, centre.y, centre.z);
+    }
+  
+    /*
+     * rotate the x/y/z axis positions
+     */
+    for (int i = 0; i < DIMS; i++)
+    {
+      axisEndPoints[i] = rotmat.vectorMultiply(axisEndPoints[i]);
+    }
+  }
+
 }