Formatting
[jalview.git] / src / jalview / gui / ScalePanel.java
index 73a9e6e..ebf25bf 100755 (executable)
@@ -1,6 +1,6 @@
 /*\r
  * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+ * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
  *\r
  * This program is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU General Public License\r
@@ -24,63 +24,133 @@ import javax.swing.*;
 \r
 import jalview.datamodel.*;\r
 \r
+/**\r
+ * DOCUMENT ME!\r
+ *\r
+ * @author $author$\r
+ * @version $Revision$\r
+ */\r
 public class ScalePanel\r
-    extends JPanel\r
+    extends JPanel implements MouseMotionListener, MouseListener\r
 {\r
   protected int offy = 4;\r
+\r
+  /** DOCUMENT ME!! */\r
   public int width;\r
   protected AlignViewport av;\r
   AlignmentPanel ap;\r
   boolean stretchingGroup = false;\r
+  int min; //used by mouseDragged to see if user\r
+  int max; //used by mouseDragged to see if user\r
+  boolean mouseDragging = false;\r
 \r
-  int min, max; //used by mouseDragged to see if user\r
   // wants to delete columns\r
-\r
   public ScalePanel(AlignViewport av, AlignmentPanel ap)\r
   {\r
     this.av = av;\r
     this.ap = ap;\r
 \r
-    addMouseListener(new MouseAdapter()\r
+    addMouseListener(this);\r
+    addMouseMotionListener(this);\r
+  }\r
+\r
+  /**\r
+   * DOCUMENT ME!\r
+   *\r
+   * @param evt DOCUMENT ME!\r
+   */\r
+  public void mousePressed(MouseEvent evt)\r
+  {\r
+    int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
+    final int res;\r
+\r
+    if (av.hasHiddenColumns)\r
+    {\r
+      res = av.getColumnSelection().adjustForHiddenColumns(x);\r
+    }\r
+    else\r
+    {\r
+      res = x;\r
+    }\r
+\r
+    min = res;\r
+    max = res;\r
+\r
+    if (SwingUtilities.isRightMouseButton(evt))\r
     {\r
-      public void mousePressed(MouseEvent evt)\r
+      JPopupMenu pop = new JPopupMenu();\r
+      if (reveal != null)\r
       {\r
-        doMousePressed(evt);\r
+        JMenuItem item = new JMenuItem("Reveal");\r
+        item.addActionListener(new ActionListener()\r
+        {\r
+          public void actionPerformed(ActionEvent e)\r
+          {\r
+            av.showColumn(reveal[0]);\r
+            reveal = null;\r
+            ap.repaint();\r
+            if (ap.overviewPanel != null)\r
+            {\r
+              ap.overviewPanel.updateOverviewImage();\r
+            }\r
+          }\r
+        });\r
+        pop.add(item);\r
+\r
+        if (av.getColumnSelection().getHiddenColumns().size() > 1)\r
+        {\r
+          item = new JMenuItem("Reveal All");\r
+          item.addActionListener(new ActionListener()\r
+          {\r
+            public void actionPerformed(ActionEvent e)\r
+            {\r
+              av.showAllHiddenColumns();\r
+              reveal = null;\r
+              ap.repaint();\r
+              if (ap.overviewPanel != null)\r
+              {\r
+                ap.overviewPanel.updateOverviewImage();\r
+              }\r
+            }\r
+          });\r
+          pop.add(item);\r
+        }\r
+        pop.show(this, evt.getX(), evt.getY());\r
       }\r
-\r
-      public void mouseReleased(MouseEvent evt)\r
+      else if (av.getColumnSelection().contains(res))\r
       {\r
-        doMouseReleased(evt);\r
+        JMenuItem item = new JMenuItem("Hide Columns");\r
+        item.addActionListener(new ActionListener()\r
+        {\r
+          public void actionPerformed(ActionEvent e)\r
+          {\r
+            av.hideColumns(res, res);\r
+            if (av.getSelectionGroup() != null\r
+                && av.getSelectionGroup().getSize() == av.alignment.getHeight())\r
+            {\r
+              av.setSelectionGroup(null);\r
+            }\r
+\r
+            ap.repaint();\r
+            if (ap.overviewPanel != null)\r
+            {\r
+              ap.overviewPanel.updateOverviewImage();\r
+            }\r
+          }\r
+        });\r
+        pop.add(item);\r
+        pop.show(this, evt.getX(), evt.getY());\r
       }\r
-    });\r
-    addMouseMotionListener(new MouseMotionAdapter()\r
+    }\r
+    else // LEFT MOUSE TO SELECT\r
     {\r
-      public void mouseDragged(MouseEvent evt)\r
+      if (!evt.isControlDown() && !evt.isShiftDown())\r
       {\r
-        doMouseDragged(evt);\r
+        av.getColumnSelection().clear();\r
       }\r
-    });\r
-  }\r
-\r
-  public void doMousePressed(MouseEvent evt)\r
-  {\r
-    int x = evt.getX();\r
-    int res = (x / av.getCharWidth()) + av.getStartRes();\r
-    SequenceGroup sg = null;\r
-\r
-    min=res;\r
-    max=res;\r
 \r
-    if (av.getColumnSelection().contains(res))\r
-    {\r
-      av.getColumnSelection().removeElement(res);\r
-      ap.annotationPanel.removeEditableColumn(res);\r
-    }\r
-    else\r
-    {\r
       av.getColumnSelection().addElement(res);\r
-      sg = new SequenceGroup();\r
-\r
+      SequenceGroup sg = new SequenceGroup();\r
       for (int i = 0; i < av.alignment.getSequences().size(); i++)\r
       {\r
         sg.addSequence(av.alignment.getSequenceAt(i), false);\r
@@ -88,92 +158,200 @@ public class ScalePanel
 \r
       sg.setStartRes(res);\r
       sg.setEndRes(res);\r
+      av.setSelectionGroup(sg);\r
+\r
+      if (evt.isShiftDown())\r
+      {\r
+        int min = Math.min(av.getColumnSelection().getMin(), res);\r
+        int max = Math.max(av.getColumnSelection().getMax(), res);\r
+        for (int i = min; i < max; i++)\r
+        {\r
+          av.getColumnSelection().addElement(i);\r
+        }\r
+        sg.setStartRes(min);\r
+        sg.setEndRes(max);\r
+      }\r
 \r
     }\r
 \r
-    av.setSelectionGroup(sg);\r
     ap.repaint();\r
   }\r
 \r
-  public void doMouseReleased(MouseEvent evt)\r
+  /**\r
+   * DOCUMENT ME!\r
+   *\r
+   * @param evt DOCUMENT ME!\r
+   */\r
+  public void mouseReleased(MouseEvent evt)\r
   {\r
-    int x = evt.getX();\r
-    int res = (x / av.getCharWidth()) + av.getStartRes();\r
+    mouseDragging = false;\r
 \r
-    if(av.getColumnSelection()!=null)\r
+    int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
+\r
+    if (res > av.alignment.getWidth())\r
     {\r
-      for(int i=0; i<av.getColumnSelection().size(); i++)\r
-      {\r
-        ap.annotationPanel.addEditableColumn(\r
-            av.getColumnSelection().columnAt(i));\r
-      }\r
+      res = av.alignment.getWidth() - 1;\r
+    }\r
+\r
+    if (av.hasHiddenColumns)\r
+    {\r
+      res = av.getColumnSelection().adjustForHiddenColumns(res);\r
     }\r
 \r
     if (!stretchingGroup)\r
     {\r
       ap.repaint();\r
+\r
       return;\r
     }\r
 \r
     SequenceGroup sg = av.getSelectionGroup();\r
 \r
-    if (res > sg.getStartRes())\r
-    {\r
-      sg.setEndRes(res);\r
-    }\r
-    else if (res < sg.getStartRes())\r
+    if (sg != null)\r
     {\r
-      sg.setStartRes(res);\r
+      if (res > sg.getStartRes())\r
+      {\r
+        sg.setEndRes(res);\r
+      }\r
+      else if (res < sg.getStartRes())\r
+      {\r
+        sg.setStartRes(res);\r
+      }\r
     }\r
-\r
     stretchingGroup = false;\r
     ap.repaint();\r
   }\r
 \r
-  public void doMouseDragged(MouseEvent evt)\r
+  /**\r
+   * DOCUMENT ME!\r
+   *\r
+   * @param evt DOCUMENT ME!\r
+   */\r
+  public void mouseDragged(MouseEvent evt)\r
   {\r
-    int x = evt.getX();\r
-    int res = (x / av.getCharWidth()) + av.getStartRes();\r
+    mouseDragging = true;\r
+\r
+    int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
+    if (res < 0)\r
+    {\r
+      res = 0;\r
+    }\r
 \r
-    if(res < min)\r
+    if (av.hasHiddenColumns)\r
+    {\r
+      res = av.getColumnSelection().adjustForHiddenColumns(res);\r
+    }\r
+\r
+    if (res > av.alignment.getWidth())\r
+    {\r
+      res = av.alignment.getWidth() - 1;\r
+    }\r
+\r
+    if (res < min)\r
+    {\r
       min = res;\r
-    if(res>max)\r
+    }\r
+\r
+    if (res > max)\r
+    {\r
       max = res;\r
+    }\r
 \r
     SequenceGroup sg = av.getSelectionGroup();\r
 \r
     if (sg != null)\r
     {\r
       stretchingGroup = true;\r
+\r
       if (!av.getColumnSelection().contains(res))\r
       {\r
         av.getColumnSelection().addElement(res);\r
       }\r
 \r
-\r
       if (res > sg.getStartRes())\r
       {\r
         sg.setEndRes(res);\r
       }\r
-      else if (res < sg.getStartRes())\r
+      if (res < sg.getStartRes())\r
       {\r
         sg.setStartRes(res);\r
       }\r
 \r
-      for(int i=min; i<=max; i++)\r
+      for (int i = min; i <= max; i++)\r
       {\r
-        if (i < sg.getStartRes() || i > sg.getEndRes())\r
-         {\r
-           av.getColumnSelection().removeElement(i);\r
-           ap.annotationPanel.removeEditableColumn(res);\r
-         }\r
+        if ( (i < sg.getStartRes()) || (i > sg.getEndRes()))\r
+        {\r
+          av.getColumnSelection().removeElement(i);\r
+        }\r
         else\r
+        {\r
           av.getColumnSelection().addElement(i);\r
+        }\r
       }\r
+\r
       ap.repaint();\r
     }\r
   }\r
 \r
+  public void mouseEntered(MouseEvent evt)\r
+  {\r
+    if (mouseDragging)\r
+    {\r
+      ap.seqPanel.scrollCanvas(null);\r
+    }\r
+  }\r
+\r
+  public void mouseExited(MouseEvent evt)\r
+  {\r
+    if (mouseDragging)\r
+    {\r
+      ap.seqPanel.scrollCanvas(evt);\r
+    }\r
+  }\r
+\r
+  public void mouseClicked(MouseEvent evt)\r
+  {}\r
+\r
+  public void mouseMoved(MouseEvent evt)\r
+  {\r
+    if (!av.hasHiddenColumns)\r
+    {\r
+      return;\r
+    }\r
+\r
+    int res = (evt.getX() / av.getCharWidth()) + av.getStartRes();\r
+\r
+    res = av.getColumnSelection().adjustForHiddenColumns(res);\r
+\r
+    reveal = null;\r
+    for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)\r
+    {\r
+      int[] region = (int[]) av.getColumnSelection().getHiddenColumns().\r
+          elementAt(i);\r
+      if (res + 1 == region[0] || res - 1 == region[1])\r
+      {\r
+        reveal = region;\r
+        ToolTipManager.sharedInstance().registerComponent(this);\r
+        this.setToolTipText("Reveal Hidden Columns with Right Mouse Button");\r
+        break;\r
+      }\r
+      else\r
+      {\r
+        this.setToolTipText(null);\r
+      }\r
+\r
+    }\r
+\r
+    repaint();\r
+  }\r
+\r
+  int[] reveal;\r
+\r
+  /**\r
+   * DOCUMENT ME!\r
+   *\r
+   * @param g DOCUMENT ME!\r
+   */\r
   public void paintComponent(Graphics g)\r
   {\r
     drawScale(g, av.getStartRes(), av.getEndRes(), getWidth(), getHeight());\r
@@ -185,8 +363,12 @@ public class ScalePanel
   {\r
     Graphics2D gg = (Graphics2D) g;\r
     gg.setFont(av.getFont());\r
-    gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                        RenderingHints.VALUE_ANTIALIAS_ON);\r
+\r
+    if (av.antiAlias)\r
+    {\r
+      gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
+                          RenderingHints.VALUE_ANTIALIAS_ON);\r
+    }\r
 \r
     //Fill in the background\r
     gg.setColor(Color.white);\r
@@ -200,6 +382,10 @@ public class ScalePanel
     for (int i = 0; i < cs.size(); i++)\r
     {\r
       int sel = cs.columnAt(i);\r
+      if (av.hasHiddenColumns)\r
+      {\r
+        sel = av.getColumnSelection().findColumnPosition(sel);\r
+      }\r
 \r
       if ( (sel >= startx) && (sel <= endx))\r
       {\r
@@ -221,16 +407,28 @@ public class ScalePanel
       scalestartx += 5;\r
     }\r
 \r
+    String string;\r
+    int maxX = 0;\r
+\r
     for (int i = scalestartx; i < endx; i += 5)\r
     {\r
       if ( (i % 10) == 0)\r
       {\r
-        gg.drawString(String.valueOf(i),\r
-                      (i - startx - 1) * av.charWidth, y);\r
+        string = String.valueOf(av.getColumnSelection().adjustForHiddenColumns(\r
+            i));\r
+        if ( (i - startx - 1) * av.charWidth > maxX)\r
+        {\r
+          gg.drawString(string,\r
+                        (i - startx - 1) * av.charWidth, y);\r
+          maxX = (i - startx + 1) * av.charWidth + fm.stringWidth(string);\r
+        }\r
+\r
         gg.drawLine( (int) ( ( (i - startx - 1) * av.charWidth) +\r
                             (av.charWidth / 2)), y + 2,\r
                     (int) ( ( (i - startx - 1) * av.charWidth) +\r
-                           (av.charWidth / 2)), y + (fm.getDescent() * 2));\r
+                           (av.charWidth / 2)),\r
+                    y + (fm.getDescent() * 2));\r
+\r
       }\r
       else\r
       {\r
@@ -240,5 +438,43 @@ public class ScalePanel
                            (av.charWidth / 2)), y + (fm.getDescent() * 2));\r
       }\r
     }\r
+\r
+    if (av.hasHiddenColumns)\r
+    {\r
+      gg.setColor(Color.blue);\r
+      int res;\r
+      if (av.getShowHiddenMarkers())\r
+      {\r
+        for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size();\r
+             i++)\r
+        {\r
+\r
+          res = av.getColumnSelection().findHiddenRegionPosition(i) -\r
+              startx;\r
+\r
+          if (res < 0 || res > endx - scalestartx)\r
+          {\r
+            continue;\r
+          }\r
+\r
+          gg.fillPolygon(new int[]\r
+                         {res * av.charWidth - av.charHeight / 4,\r
+                         res * av.charWidth + av.charHeight / 4,\r
+                         res * av.charWidth},\r
+                         new int[]\r
+                         {\r
+                         y - av.charHeight / 2, y - av.charHeight / 2,\r
+                         y + 8\r
+          }, 3);\r
+\r
+        }\r
+      }\r
+\r
+      if (reveal != null && reveal[0] > startx && reveal[0] < endx)\r
+      {\r
+        gg.drawString("Reveal Columns", reveal[0] * av.charWidth, 0);\r
+      }\r
+    }\r
+\r
   }\r
 }\r