JAL-2349 JAL-3855 highlight residues associated with elements under mouse - Jmol...
[jalview.git] / src / jalview / gui / AnnotationPanel.java
index ba02a3f..d31e52d 100755 (executable)
@@ -56,6 +56,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.ContactListI;
+import jalview.datamodel.ContactRange;
 import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.SequenceI;
 import jalview.gui.JalviewColourChooser.ColourChooserListener;
@@ -584,25 +585,35 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
 
     if (graphStretch != -1)
     {
+
       if (aa[graphStretch].graph == AlignmentAnnotation.CUSTOMRENDERER)
       {
-        int currentX = getColumnForXPos(evt.getX());
-        ContactListI forCurrentX = av.getContactList(aa[graphStretch],
-                currentX);
-        if (forCurrentX != null)
+        if (evt.isAltDown() || evt.isAltGraphDown())
+        {
+          dragMode = DragMode.MatrixSelect;
+          firstDragX = mouseDragLastX;
+          firstDragY = mouseDragLastY;
+        }
+        else
         {
-          ContactGeometry cXcgeom = new ContactGeometry(forCurrentX,
-                  aa[graphStretch].graphHeight);
-          ContactGeometry.contactInterval cXci = cXcgeom.mapFor(yOffset,
-                  yOffset);
-          int fr, to;
-          fr = Math.min(cXci.cStart, cXci.cEnd);
-          to = Math.max(cXci.cStart, cXci.cEnd);
-          for (int c = fr; c <= to; c++)
+          int currentX = getColumnForXPos(evt.getX());
+          ContactListI forCurrentX = av.getContactList(aa[graphStretch],
+                  currentX);
+          if (forCurrentX != null)
           {
-            av.getColumnSelection().addElement(c);
+            ContactGeometry cXcgeom = new ContactGeometry(forCurrentX,
+                    aa[graphStretch].graphHeight);
+            ContactGeometry.contactInterval cXci = cXcgeom.mapFor(yOffset,
+                    yOffset);
+            int fr, to;
+            fr = Math.min(cXci.cStart, cXci.cEnd);
+            to = Math.max(cXci.cStart, cXci.cEnd);
+            for (int c = fr; c <= to; c++)
+            {
+              av.getColumnSelection().addElement(c);
+            }
+            av.getColumnSelection().addElement(currentX);
           }
-          av.getColumnSelection().addElement(currentX);
         }
       }
     }
@@ -676,6 +687,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     graphStretch = -1;
     mouseDragLastX = -1;
     mouseDragLastY = -1;
+    firstDragX = -1;
+    firstDragY = -1;
     mouseDragging = false;
     if (dragMode == DragMode.Resize)
     {
@@ -813,6 +826,9 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         /*
          * TODO draw a rubber band for range
          */
+        mouseDragLastX = x;
+        mouseDragLastY = y;
+        ap.paintAlignment(false, false);
       }
       else
       {
@@ -835,51 +851,85 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
      * get geometry of drag
      */
     int fromY = Math.min(firstDragY, evt.getY());
-    int deltaY = Math.abs(firstDragY - evt.getY());
     int toY = Math.max(firstDragY, evt.getY());
+    int fromX = Math.min(firstDragX, evt.getX());
+    int toX = Math.max(firstDragX, evt.getX());
+
+    int deltaY = toY - fromY;
+    int deltaX = toX - fromX;
 
     int[] rowIndex = getRowIndexAndOffset(fromY,
             av.getAlignment().getAlignmentAnnotation());
+    int[] toRowIndex = getRowIndexAndOffset(toY,
+            av.getAlignment().getAlignmentAnnotation());
+
+    if (rowIndex == null || toRowIndex == null)
+    {
+      System.out.println("Drag out of range. needs to be clipped");
+
+    }
+    if (rowIndex[0] != toRowIndex[0])
+    {
+      System.out.println("Drag went to another row. needs to be clipped");
+    }
 
     // rectangular selection on matrix style annotation
     AlignmentAnnotation cma = av.getAlignment()
             .getAlignmentAnnotation()[rowIndex[0]];
 
-    int fromXp = Math.min(firstDragX, evt.getX());
-    int toXp = Math.max(firstDragX, evt.getX());
-    int lastX = getColumnForXPos(fromXp);
-    int currentX = getColumnForXPos(toXp);
-    ContactListI forLastX = av.getContactList(cma, lastX);
-    ContactListI forCurrentX = av.getContactList(cma, currentX);
-    if (forLastX != null && forCurrentX != null)
+    int lastX = getColumnForXPos(fromX);
+    int currentX = getColumnForXPos(toX);
+    int fromXc = Math.min(lastX, currentX);
+    int toXc = Math.max(lastX, currentX);
+    ContactListI forFromX = av.getContactList(cma, fromXc);
+    ContactListI forToX = av.getContactList(cma, toXc);
+
+    if (forFromX != null && forToX != null)
     {
-      ContactGeometry lastXcgeom = new ContactGeometry(forLastX,
+      ContactGeometry lastXcgeom = new ContactGeometry(forFromX,
               cma.graphHeight);
-      ContactGeometry.contactInterval lastXci = lastXcgeom.mapFor(
-              rowIndex[1],
-              rowIndex[1] + ((fromY == firstDragY) ? -deltaY : deltaY));
-      ContactGeometry cXcgeom = new ContactGeometry(forCurrentX,
+      ContactGeometry.contactInterval lastXci = lastXcgeom
+              .mapFor(rowIndex[1], rowIndex[1] - deltaY);
+
+      ContactGeometry cXcgeom = new ContactGeometry(forToX,
               cma.graphHeight);
       ContactGeometry.contactInterval cXci = cXcgeom.mapFor(rowIndex[1],
-              rowIndex[1] + deltaY);
+              rowIndex[1] - deltaY);
+
       // mark rectangular region formed by drag
-      System.err.println("Matrix Selection from last(" + lastXci.cStart
-              + "," + lastXci.cEnd + ") to cur(" + cXci.cStart + ","
-              + cXci.cEnd + ")");
+      System.err.println("Matrix Selection from last(" + fromXc + ",["
+              + lastXci.cStart + "," + lastXci.cEnd + "]) to cur(" + toXc
+              + ",[" + cXci.cStart + "," + cXci.cEnd + "])");
       int fr, to;
       fr = Math.min(lastXci.cStart, lastXci.cEnd);
       to = Math.max(lastXci.cStart, lastXci.cEnd);
       System.err.println("Marking " + fr + " to " + to);
       for (int c = fr; c <= to; c++)
       {
-        av.getColumnSelection().addElement(c);
+        if (cma.sequenceRef != null)
+        {
+          int col = cma.sequenceRef.findIndex(c);
+          av.getColumnSelection().addElement(col);
+        }
+        else
+        {
+          av.getColumnSelection().addElement(c);
+        }
       }
       fr = Math.min(cXci.cStart, cXci.cEnd);
       to = Math.max(cXci.cStart, cXci.cEnd);
       System.err.println("Marking " + fr + " to " + to);
       for (int c = fr; c <= to; c++)
       {
-        av.getColumnSelection().addElement(c);
+        if (cma.sequenceRef != null)
+        {
+          int col = cma.sequenceRef.findIndex(c);
+          av.getColumnSelection().addElement(col);
+        }
+        else
+        {
+          av.getColumnSelection().addElement(c);
+        }
       }
       fr = Math.min(lastX, currentX);
       to = Math.max(lastX, currentX);
@@ -969,15 +1019,14 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
   static int[] getRowIndexAndOffset(int yPos, AlignmentAnnotation[] aa)
   {
     int[] res = new int[2];
+    res[0] = -1;
+    res[1] = 0;
     if (aa == null)
     {
-      res[0] = -1;
-      res[1] = 0;
       return res;
     }
     int row = -1;
     int height = 0, lheight = 0;
-
     for (int i = 0; i < aa.length; i++)
     {
       if (aa[i].visible)
@@ -1048,12 +1097,16 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       if (clist != null)
       {
         ContactGeometry cgeom = new ContactGeometry(clist, ann.graphHeight);
-        ContactGeometry.contactInterval ci = cgeom.mapFor(rowAndOffset,
-                rowAndOffset);
-        tooltip += "Contact from " + ci.cStart + " to " + ci.cEnd;
-
-        // ap.getStructureSelectionManager().mouseOverSequence(ann.sequenceRef,
-        // new int[] {column, ci.cStart,ci.cEnd}, -1, null)
+        ContactGeometry.contactInterval ci = cgeom.mapFor(rowAndOffset);
+        ContactRange cr = clist.getRangeFor(ci.cStart, ci.cEnd);
+        tooltip = "Contact from " + clist.getPosition() + ", [" + ci.cStart
+                + " - " + ci.cEnd + "]" + "<br/>Mean:" + cr.getMean();
+        int col = ann.sequenceRef.findPosition(column);
+        ap.getStructureSelectionManager()
+                .highlightPositionsOn(ann.sequenceRef, new int[][]
+                { new int[] { col, col },
+                    new int[]
+                    { ci.cStart, ci.cEnd } }, null);
       }
     }
     return tooltip;
@@ -1408,6 +1461,17 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     {
       fadedImage = oldFaded;
     }
+    if (dragMode == DragMode.MatrixSelect)
+    {
+      g.setColor(Color.yellow);
+      g.drawRect(Math.min(firstDragX, mouseDragLastX),
+              Math.min(firstDragY, mouseDragLastY),
+              Math.max(firstDragX, mouseDragLastX)
+                      - Math.min(firstDragX, mouseDragLastX),
+              Math.max(firstDragY, mouseDragLastY)
+                      - Math.min(firstDragY, mouseDragLastY));
+
+    }
   }
 
   @Override