Merge branch 'develop' into bug/JAL-2431splitFrameNewView bug/JAL-2431splitFrameNewView
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 31 Mar 2017 09:59:57 +0000 (10:59 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 31 Mar 2017 09:59:57 +0000 (10:59 +0100)
1  2 
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignmentPanel.java
src/jalview/viewmodel/AlignmentViewport.java

@@@ -86,6 -86,7 +86,7 @@@ import jalview.schemes.ResiduePropertie
  import jalview.schemes.TCoffeeColourScheme;
  import jalview.util.MessageManager;
  import jalview.viewmodel.AlignmentViewport;
+ import jalview.viewmodel.ViewportRanges;
  import jalview.ws.DBRefFetcher;
  import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
  import jalview.ws.jws1.Discoverer;
@@@ -160,6 -161,8 +161,8 @@@ public class AlignFrame extends GAlignF
  
    AlignViewport viewport;
  
+   ViewportRanges vpRanges;
    public AlignViewControllerI avc;
  
    List<AlignmentPanel> alignPanels = new ArrayList<AlignmentPanel>();
        progressBar = new ProgressBar(this.statusPanel, this.statusBar);
      }
  
+     vpRanges = viewport.getRanges();
      avc = new jalview.controller.AlignViewController(this, viewport,
              alignPanel);
      if (viewport.getAlignmentConservationAnnotation() == null)
                    new String[] { (viewport.cursorMode ? "on" : "off") }));
            if (viewport.cursorMode)
            {
-             alignPanel.getSeqPanel().seqCanvas.cursorX = viewport.startRes;
-             alignPanel.getSeqPanel().seqCanvas.cursorY = viewport.startSeq;
+             alignPanel.getSeqPanel().seqCanvas.cursorX = vpRanges
+                     .getStartRes();
+             alignPanel.getSeqPanel().seqCanvas.cursorY = vpRanges
+                     .getStartSeq();
            }
            alignPanel.getSeqPanel().seqCanvas.repaint();
            break;
            }
            else
            {
-             alignPanel.setScrollValues(viewport.startRes, viewport.startSeq
-                     - viewport.endSeq + viewport.startSeq);
+             alignPanel.setScrollValues(vpRanges.getStartRes(),
+                     2 * vpRanges.getStartSeq() - vpRanges.getEndSeq());
            }
            break;
          case KeyEvent.VK_PAGE_DOWN:
            }
            else
            {
-             alignPanel.setScrollValues(viewport.startRes, viewport.startSeq
-                     + viewport.endSeq - viewport.startSeq);
+             alignPanel.setScrollValues(vpRanges.getStartRes(),
+                     vpRanges.getEndSeq());
            }
            break;
          }
        {
  
          // propagate alignment changed.
-         viewport.setEndSeq(alignment.getHeight());
+         vpRanges.setEndSeq(alignment.getHeight());
          if (annotationAdded)
          {
            // Duplicate sequence annotation in all views.
        {
          trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
                  column, viewport.getAlignment());
-         viewport.setStartRes(0);
+         vpRanges.setStartRes(0);
        }
        else
        {
      // This is to maintain viewport position on first residue
      // of first sequence
      SequenceI seq = viewport.getAlignment().getSequenceAt(0);
-     int startRes = seq.findPosition(viewport.startRes);
+     int startRes = seq.findPosition(vpRanges.getStartRes());
      // ShiftList shifts;
      // viewport.getAlignment().removeGaps(shifts=new ShiftList());
      // edit.alColumnChanges=shifts.getInverse();
      // if (viewport.hasHiddenColumns)
      // viewport.getColumnSelection().compensateForEdits(shifts);
-     viewport.setStartRes(seq.findIndex(startRes) - 1);
+     vpRanges.setStartRes(seq.findIndex(startRes) - 1);
      viewport.firePropertyChange("alignment", null, viewport.getAlignment()
              .getSequences());
  
      // This is to maintain viewport position on first residue
      // of first sequence
      SequenceI seq = viewport.getAlignment().getSequenceAt(0);
-     int startRes = seq.findPosition(viewport.startRes);
+     int startRes = seq.findPosition(vpRanges.getStartRes());
  
      addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
              viewport.getAlignment()));
  
-     viewport.setStartRes(seq.findIndex(startRes) - 1);
+     vpRanges.setStartRes(seq.findIndex(startRes) - 1);
  
      viewport.firePropertyChange("alignment", null, viewport.getAlignment()
              .getSequences());
       */
      newap.av.replaceMappings(viewport.getAlignment());
  
 +    /*
 +     * start up cDNA consensus (if applicable) now mappings are in place
 +     */
 +    if (newap.av.initComplementConsensus())
 +    {
 +      newap.refresh(true); // adjust layout of annotations
 +    }
 +
      newap.av.viewName = getNewViewName(viewTitle);
  
      addAlignmentPanel(newap, true);
@@@ -35,6 -35,7 +35,7 @@@ import jalview.schemes.ResiduePropertie
  import jalview.structure.StructureSelectionManager;
  import jalview.util.MessageManager;
  import jalview.util.Platform;
+ import jalview.viewmodel.ViewportRanges;
  
  import java.awt.BorderLayout;
  import java.awt.Color;
@@@ -69,6 -70,8 +70,8 @@@ public class AlignmentPanel extends GAl
  {
    public AlignViewport av;
  
+   ViewportRanges vpRanges;
    OverviewPanel overviewPanel;
  
    private SeqPanel seqPanel;
@@@ -91,9 -94,9 +94,9 @@@
    // this value is set false when selection area being dragged
    boolean fastPaint = true;
  
-   int hextent = 0;
+   private int hextent = 0;
  
-   int vextent = 0;
+   private int vextent = 0;
  
    /*
     * Flag set while scrolling to follow complementary cDNA/protein scroll. When
    {
      alignFrame = af;
      this.av = av;
+     vpRanges = av.getRanges();
      setSeqPanel(new SeqPanel(av, this));
      setIdPanel(new IdPanel(av, this));
  
         */
        if (centre)
        {
-         int offset = (av.getEndRes() - av.getStartRes() + 1) / 2 - 1;
+         int offset = (vpRanges.getEndRes() - vpRanges.getStartRes() + 1) / 2 - 1;
          start = Math.max(start - offset, 0);
          end = end + offset - 1;
        }
        // + av.getStartSeq() + ", ends=" + av.getEndSeq());
        if (!av.getWrapAlignment())
        {
-         if ((startv = av.getStartRes()) >= start)
+         if ((startv = vpRanges.getStartRes()) >= start)
          {
            /*
             * Scroll left to make start of search results visible
            // setScrollValues(start - 1, seqIndex); // plus one residue
            setScrollValues(start, seqIndex);
          }
-         else if ((endv = av.getEndRes()) <= end)
+         else if ((endv = vpRanges.getEndRes()) <= end)
          {
            /*
             * Scroll right to make end of search results visible
            // setScrollValues(startv + 1 + end - endv, seqIndex); // plus one
            setScrollValues(startv + end - endv, seqIndex);
          }
-         else if ((starts = av.getStartSeq()) > seqIndex)
+         else if ((starts = vpRanges.getStartSeq()) > seqIndex)
          {
            /*
             * Scroll up to make start of search results visible
             */
-           setScrollValues(av.getStartRes(), seqIndex);
+           setScrollValues(vpRanges.getStartRes(), seqIndex);
          }
-         else if ((ends = av.getEndSeq()) <= seqIndex)
+         else if ((ends = vpRanges.getEndSeq()) <= seqIndex)
          {
            /*
             * Scroll down to make end of search results visible
             */
-           setScrollValues(av.getStartRes(), starts + seqIndex - ends + 1);
+           setScrollValues(vpRanges.getStartRes(), starts + seqIndex - ends
+                   + 1);
          }
          /*
           * Else results are already visible - no need to scroll
    {
      int cwidth = getSeqPanel().seqCanvas
              .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
-     if (res < av.getStartRes() || res >= (av.getStartRes() + cwidth))
+     if (res < vpRanges.getStartRes()
+             || res >= (vpRanges.getStartRes() + cwidth))
      {
        vscroll.setValue((res / cwidth));
-       av.startRes = vscroll.getValue() * cwidth;
+       vpRanges.setStartRes(vscroll.getValue() * cwidth);
      }
  
    }
      fontChanged();
      setAnnotationVisible(av.isShowAnnotation());
      boolean wrap = av.getWrapAlignment();
-     av.startSeq = 0;
+     vpRanges.setStartSeq(0);
      scalePanelHolder.setVisible(!wrap);
      hscroll.setVisible(!wrap);
      idwidthAdjuster.setVisible(!wrap);
     */
    public void setScrollValues(int x, int y)
    {
-     // System.err.println("Scroll " + this.av.viewName + " to " + x + "," + y);
      if (av == null || av.getAlignment() == null)
      {
        return;
  
      if (av.hasHiddenColumns())
      {
+       // reset the width to exclude hidden columns
        width = av.getColumnSelection().findColumnPosition(width);
      }
  
-     av.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av
-             .getCharWidth())) - 1);
      hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
      vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
  
        x = 0;
      }
  
+     // update endRes after x has (possibly) been adjusted
+     vpRanges.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av
+             .getCharWidth())) - 1);
      /*
       * each scroll adjustment triggers adjustmentValueChanged, which resets the
       * 'do not scroll complement' flag; ensure it is the same for both
    @Override
    public void adjustmentValueChanged(AdjustmentEvent evt)
    {
-     int oldX = av.getStartRes();
-     int oldY = av.getStartSeq();
+     int oldX = vpRanges.getStartRes();
+     int oldY = vpRanges.getStartSeq();
  
      if (evt.getSource() == hscroll)
      {
        int x = hscroll.getValue();
-       av.setStartRes(x);
-       av.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av
+       vpRanges.setStartRes(x);
+       vpRanges.setEndRes((x + (getSeqPanel().seqCanvas.getWidth() / av
                .getCharWidth())) - 1);
      }
  
          {
            int rowSize = getSeqPanel().seqCanvas
                    .getWrappedCanvasWidth(getSeqPanel().seqCanvas.getWidth());
-           av.setStartRes(offy * rowSize);
-           av.setEndRes((offy + 1) * rowSize);
+           vpRanges.setStartRes(offy * rowSize);
+           vpRanges.setEndRes((offy + 1) * rowSize);
          }
          else
          {
              @Override
              public void run()
              {
-               setScrollValues(av.getStartRes(), av.getStartSeq());
+               setScrollValues(vpRanges.getStartRes(),
+                       vpRanges.getStartSeq());
              }
            });
          }
        }
        else
        {
-         av.setStartSeq(offy);
-         av.setEndSeq(offy
-                 + (getSeqPanel().seqCanvas.getHeight() / av.getCharHeight()));
+         vpRanges.setStartSeq(offy);
+         vpRanges.setEndSeq(offy
+                 + (getSeqPanel().seqCanvas.getHeight() / av.getCharHeight())
+                 - 1);
        }
      }
  
        overviewPanel.setBoxPosition();
      }
  
-     int scrollX = av.startRes - oldX;
-     int scrollY = av.startSeq - oldY;
+     int scrollX = vpRanges.getStartRes() - oldX;
+     int scrollY = vpRanges.getStartSeq() - oldY;
  
      if (av.getWrapAlignment() || !fastPaint)
      {
      {
        // Make sure we're not trying to draw a panel
        // larger than the visible window
-       if (scrollX > av.endRes - av.startRes)
+       if (scrollX > vpRanges.getEndRes() - vpRanges.getStartRes())
        {
-         scrollX = av.endRes - av.startRes;
+         scrollX = vpRanges.getEndRes() - vpRanges.getStartRes();
        }
-       else if (scrollX < av.startRes - av.endRes)
+       else if (scrollX < vpRanges.getStartRes() - vpRanges.getEndRes())
        {
-         scrollX = av.startRes - av.endRes;
+         scrollX = vpRanges.getStartRes() - vpRanges.getEndRes();
        }
  
        if (scrollX != 0 || scrollY != 0)
      }
      else
      {
-       setScrollValues(av.getStartRes(), av.getStartSeq());
+       setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
      }
    }
  
    {
      return this.dontScrollComplement;
    }
 +
 +  /**
 +   * Redraw sensibly.
 +   * 
 +   * @adjustHeight if true, try to recalculate panel height for visible
 +   *               annotations
 +   */
 +  protected void refresh(boolean adjustHeight)
 +  {
 +    validateAnnotationDimensions(adjustHeight);
 +    addNotify();
 +    if (adjustHeight)
 +    {
 +      // sort, repaint, update overview
 +      paintAlignment(true);
 +    }
 +    else
 +    {
 +      // lightweight repaint
 +      repaint();
 +    }
 +  }
  }
   */
  package jalview.viewmodel;
  
+ import java.awt.Color;
+ import java.beans.PropertyChangeSupport;
+ import java.util.ArrayDeque;
+ import java.util.ArrayList;
+ import java.util.BitSet;
+ import java.util.Deque;
+ import java.util.HashMap;
+ import java.util.Hashtable;
+ import java.util.List;
+ import java.util.Map;
  import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
  import jalview.analysis.Conservation;
  import jalview.api.AlignCalcManagerI;
@@@ -57,17 -68,6 +68,6 @@@ import jalview.workers.ComplementConsen
  import jalview.workers.ConsensusThread;
  import jalview.workers.StrucConsensusThread;
  
- import java.awt.Color;
- import java.beans.PropertyChangeSupport;
- import java.util.ArrayDeque;
- import java.util.ArrayList;
- import java.util.BitSet;
- import java.util.Deque;
- import java.util.HashMap;
- import java.util.Hashtable;
- import java.util.List;
- import java.util.Map;
  /**
   * base class holding visualization and analysis attributes and common logic for
   * an active alignment view displayed in the GUI
@@@ -78,6 -78,8 +78,8 @@@
  public abstract class AlignmentViewport implements AlignViewportI,
          CommandListener, VamsasSource
  {
+   protected ViewportRanges ranges;
    protected ViewStyleI viewStyle = new ViewStyle();
  
    /**
  
    protected AlignmentAnnotation complementConsensus;
  
+   protected AlignmentAnnotation gapcounts;
    protected AlignmentAnnotation strucConsensus;
  
    protected AlignmentAnnotation conservation;
    }
  
    @Override
+   public AlignmentAnnotation getAlignmentGapAnnotation()
+   {
+     return gapcounts;
+   }
+   @Override
    public AlignmentAnnotation getComplementConsensusAnnotation()
    {
      return complementConsensus;
    public void updateConsensus(final AlignmentViewPanel ap)
    {
      // see note in mantis : issue number 8585
-     if (consensus == null || !autoCalculateConsensus)
+     if ((consensus == null || gapcounts == null) || !autoCalculateConsensus)
      {
        return;
      }
     */
    private boolean followHighlight = true;
  
-   // TODO private with getters and setters?
-   public int startRes;
-   public int endRes;
-   public int startSeq;
-   public int endSeq;
    /**
     * Property change listener for changes in alignment
     * 
        consensus = new AlignmentAnnotation("Consensus", "PID",
                new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
        initConsensus(consensus);
+       gapcounts = new AlignmentAnnotation("Occupancy",
+               "Number of aligned positions",
+               new Annotation[1], 0f, alignment.getHeight(),
+               AlignmentAnnotation.BAR_GRAPH);
+       initGapCounts(gapcounts);
  
        initComplementConsensus();
      }
    }
  
    /**
 -   * If this is a protein alignment and there are mappings to cDNA, add the cDNA
 -   * consensus annotation.
 +   * If this is a protein alignment and there are mappings to cDNA, adds the
 +   * cDNA consensus annotation and returns true, else returns false.
     */
 -  public void initComplementConsensus()
 +  public boolean initComplementConsensus()
    {
      if (!alignment.isNucleotide())
      {
                    "PID for cDNA", new Annotation[1], 0f, 100f,
                    AlignmentAnnotation.BAR_GRAPH);
            initConsensus(complementConsensus);
 +          return true;
          }
        }
      }
 +    return false;
    }
  
    private void initConsensus(AlignmentAnnotation aa)
      }
    }
  
+   // these should be extracted from the view model - style and settings for
+   // derived annotation
+   private void initGapCounts(AlignmentAnnotation counts)
+   {
+     counts.hasText = false;
+     counts.autoCalculated = true;
+     counts.graph = AlignmentAnnotation.BAR_GRAPH;
+     if (showConsensus)
+     {
+       alignment.addAnnotation(counts);
+     }
+   }
    private void initConservation()
    {
      if (showConservation)
      this.followHighlight = b;
    }
  
-   public int getStartRes()
-   {
-     return startRes;
-   }
    @Override
-   public int getEndRes()
-   {
-     return endRes;
-   }
-   public int getStartSeq()
-   {
-     return startSeq;
-   }
-   public void setStartRes(int res)
-   {
-     this.startRes = res;
-   }
-   public void setStartSeq(int seq)
-   {
-     this.startSeq = seq;
-   }
-   public void setEndRes(int res)
+   public ViewportRanges getRanges()
    {
-     if (res > alignment.getWidth() - 1)
-     {
-       // log.System.out.println(" Corrected res from " + res + " to maximum " +
-       // (alignment.getWidth()-1));
-       res = alignment.getWidth() - 1;
-     }
-     if (res < 0)
-     {
-       res = 0;
-     }
-     this.endRes = res;
-   }
-   public void setEndSeq(int seq)
-   {
-     if (seq > alignment.getHeight())
-     {
-       seq = alignment.getHeight();
-     }
-     if (seq < 0)
-     {
-       seq = 0;
-     }
-     this.endSeq = seq;
-   }
-   public int getEndSeq()
-   {
-     return endSeq;
+     return ranges;
    }
  
    /**
       * locate 'middle' column (true middle if an odd number visible, left of
       * middle if an even number visible)
       */
-     int middleColumn = getStartRes() + (getEndRes() - getStartRes()) / 2;
+     int middleColumn = ranges.getStartRes()
+             + (ranges.getEndRes() - ranges.getStartRes()) / 2;
      final HiddenSequences hiddenSequences = getAlignment()
              .getHiddenSequences();
  
       */
      int lastSeq = alignment.getHeight() - 1;
      List<AlignedCodonFrame> seqMappings = null;
-     for (int seqNo = getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
+     for (int seqNo = ranges.getStartSeq(); seqNo < lastSeq; seqNo++, seqOffset++)
      {
        sequence = getAlignment().getSequenceAt(seqNo);
        if (hiddenSequences != null && hiddenSequences.isHidden(sequence))
     */
    private boolean selectionIsDefinedGroup = false;
  
    @Override
    public boolean isSelectionDefinedGroup()
    {