Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / src / jalview / gui / IdwidthAdjuster.java
index 4fc8d95..99a39d4 100755 (executable)
@@ -1,25 +1,36 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
- * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
  * Jalview is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
  *  
  * Jalview is distributed in the hope that it will be useful, but 
  * WITHOUT ANY WARRANTY; without even the implied warranty 
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
  * PURPOSE.  See the GNU General Public License for more details.
  * 
- * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
 package jalview.gui;
 
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Graphics;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+
+import javax.swing.JPanel;
+
+import jalview.api.AlignViewportI;
+import jalview.bin.Cache;
 
 /**
  * DOCUMENT ME!
@@ -27,15 +38,13 @@ import javax.swing.*;
  * @author $author$
  * @version $Revision$
  */
-public class IdwidthAdjuster extends JPanel implements MouseListener,
-        MouseMotionListener
+public class IdwidthAdjuster extends JPanel
+        implements MouseListener, MouseMotionListener
 {
-  boolean active = false;
+  public static final int MIN_ID_WIDTH = 20;
 
   int oldX = 0;
 
-  Image image;
-
   AlignmentPanel ap;
 
   /**
@@ -47,125 +56,176 @@ public class IdwidthAdjuster extends JPanel implements MouseListener,
   public IdwidthAdjuster(AlignmentPanel ap)
   {
     this.ap = ap;
-
-    java.net.URL url = getClass().getResource("/images/idwidth.gif");
-
-    if (url != null)
-    {
-      image = java.awt.Toolkit.getDefaultToolkit().createImage(url);
-    }
-
+    setBackground(Color.white);
     addMouseListener(this);
     addMouseMotionListener(this);
   }
 
   /**
-   * DOCUMENT ME!
+   * Action on mouse pressed is to save the start position for any drag
    * 
    * @param evt
-   *          DOCUMENT ME!
    */
+  @Override
   public void mousePressed(MouseEvent evt)
   {
     oldX = evt.getX();
   }
 
   /**
-   * DOCUMENT ME!
+   * On release of mouse drag to resize the width, if there is a complementary
+   * alignment in a split frame, sets the complement to the same id width and
+   * repaints the split frame. Note this is done whether or not the protein
+   * characters are scaled to codon width.
    * 
    * @param evt
-   *          DOCUMENT ME!
    */
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
-    active = false;
     repaint();
+
+    /*
+     * If in a SplitFrame, set the other's id width to match
+     */
+    final AlignViewportI viewport = ap.getAlignViewport();
+    if (viewport.getCodingComplement() != null)
+    {
+      viewport.getCodingComplement().setIdWidth(viewport.getIdWidth());
+      SplitFrame sf = (SplitFrame) ap.alignFrame.getSplitViewContainer();
+      sf.repaint();
+    }
   }
 
   /**
-   * DOCUMENT ME!
+   * When this region is entered, repaints to show a left-right move cursor
    * 
    * @param evt
-   *          DOCUMENT ME!
    */
+  @Override
   public void mouseEntered(MouseEvent evt)
   {
-    active = true;
     repaint();
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param evt
-   *          DOCUMENT ME!
-   */
+  @Override
   public void mouseExited(MouseEvent evt)
   {
-    active = false;
-    repaint();
   }
 
   /**
-   * DOCUMENT ME!
+   * Adjusts the id panel width for a mouse drag left or right (subject to a
+   * minimum of 20 pixels) and repaints the alignment
    * 
    * @param evt
-   *          DOCUMENT ME!
    */
+  @Override
   public void mouseDragged(MouseEvent evt)
   {
-    active = true;
+    int mouseX = evt.getX();
+    final AlignViewportI viewport = ap.getAlignViewport();
+    int curwidth = viewport.getIdWidth();
+    int dif = mouseX - oldX;
+
+    final int newWidth = curwidth + dif;
 
-    Dimension d = ap.idPanel.idCanvas.getPreferredSize();
-    int dif = evt.getX() - oldX;
+    /*
+     * don't drag below minimum width
+     */
+    if (newWidth < MIN_ID_WIDTH)
+    {
+      return;
+    }
 
-    if (((d.width + dif) > 20) || (dif > 0))
+    /*
+     * don't allow residue width to be < 1 in wrapped format
+     */
+    if (viewport.getWrapAlignment())
     {
-      ap.idPanel.idCanvas.setPreferredSize(new Dimension(d.width + dif,
-              d.height));
-      ap.paintAlignment(true);
+      SeqCanvas sc = ap.getSeqPanel().seqCanvas;
+      if (sc != null && sc.getWrappedCanvasWidth(sc.getWidth() - dif) < 1)
+      {
+        return;
+      }
     }
 
     oldX = evt.getX();
+
+    /*
+     * don't drag right if mouse is to the left of the region
+     */
+    if (dif > 0 && mouseX < 0)
+    {
+      return;
+    }
+
+    // TODO JAL-4260 - work out how to trigger recomputation of wrapped pages !
+    int curCol = viewport.getRanges().getStartRes()
+            + viewport.getRanges().getViewportWidth();
+
+    viewport.setIdWidth(newWidth);
+
+    ap.validateAnnotationDimensions(false);
+    if (viewport.getWrapAlignment())
+    {
+      viewport.getRanges().scrollToWrappedVisible(
+              curCol - viewport.getRanges().getViewportWidth());
+    }
+    ap.paintAlignment(true, false);
+
+    ap.getIdPanel().getIdCanvas().setManuallyAdjusted(true);
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param evt
-   *          DOCUMENT ME!
-   */
+  public void setWidth(int newWidth)
+  {
+    if (newWidth < MIN_ID_WIDTH
+            || ap.getIdPanel().getIdCanvas().isManuallyAdjusted())
+    {
+      return;
+    }
+    final AlignViewportI viewport = ap.getAlignViewport();
+    viewport.setIdWidth(newWidth);
+    ap.paintAlignment(true, false);
+  }
+
+  public boolean manuallyAdjusted()
+  {
+    return ap.getIdPanel().getIdCanvas().isManuallyAdjusted();
+  }
+
+  @Override
   public void mouseMoved(MouseEvent evt)
   {
   }
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param evt
-   *          DOCUMENT ME!
-   */
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
   }
 
   /**
-   * DOCUMENT ME!
+   * Paints this region, showing a left-right move cursor if currently 'active'
    * 
    * @param g
-   *          DOCUMENT ME!
    */
+  @Override
   public void paintComponent(Graphics g)
   {
+    int width = getWidth();
+    int height = getHeight();
     g.setColor(Color.white);
-    g.fillRect(0, 0, getWidth(), getHeight());
+    g.fillRect(0, 0, width, height);
 
-    if (active)
+    if (!Cache.getDefault(AnnotationLabels.RESIZE_MARGINS_MARK_PREF, false))
+    // && !ap.getAlignViewport().getWrapAlignment()) // now allowing adjustment
+    // in wrap mode
     {
-      if (image != null)
-      {
-        g.drawImage(image, getWidth() - 20, 2, this);
-      }
+      int spacer = Math.max(2, AnnotationLabels.HEIGHT_ADJUSTER_HEIGHT / 4);
+      g.setColor(Color.LIGHT_GRAY);
+      g.drawLine(width - 3 * spacer, 0, width - 3 * spacer, height / 2);
+      g.drawLine(width - spacer, 0, width - spacer, height / 2);
     }
+
+    setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
   }
 }