JAL-2405 set context on selection group for tailored colour options
[jalview.git] / src / jalview / viewmodel / AlignmentViewport.java
index 57258ef..e5c7b4c 100644 (file)
@@ -36,15 +36,15 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenSequences;
-import jalview.datamodel.ProfileI;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
-import jalview.schemes.Blosum62ColourScheme;
+import jalview.renderer.ResidueShader;
+import jalview.renderer.ResidueShaderI;
 import jalview.schemes.ColourSchemeI;
-import jalview.schemes.PIDColourScheme;
 import jalview.structure.CommandListener;
 import jalview.structure.StructureSelectionManager;
 import jalview.structure.VamsasSource;
@@ -597,7 +597,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   protected boolean ignoreGapsInConsensusCalculation = false;
 
-  protected ColourSchemeI globalColourScheme = null;
+  protected ResidueShaderI residueShading;
 
   @Override
   public void setGlobalColourScheme(ColourSchemeI cs)
@@ -605,74 +605,51 @@ public abstract class AlignmentViewport implements AlignViewportI,
     // TODO: logic refactored from AlignFrame changeColour -
     // TODO: autorecalc stuff should be changed to rely on the worker system
     // check to see if we should implement a changeColour(cs) method rather than
-    // put th logic in here
+    // put the logic in here
     // - means that caller decides if they want to just modify state and defer
     // calculation till later or to do all calculations in thread.
     // via changecolour
-    globalColourScheme = cs;
-    boolean recalc = false;
+
+    /*
+     * only instantiate alignment colouring once, thereafter update it;
+     * this means that any conservation or PID threshold settings
+     * persist when the alignment colour scheme is changed
+     */
+    if (residueShading == null)
+    {
+      residueShading = new ResidueShader(viewStyle);
+    }
+    residueShading.setColourScheme(cs);
+
+    // TODO: do threshold and increment belong in ViewStyle or ResidueShader?
+    // ...problem: groups need these, but do not currently have a ViewStyle
+
     if (cs != null)
     {
-      recalc = getConservationSelected();
-      if (getAbovePIDThreshold() || cs instanceof PIDColourScheme
-              || cs instanceof Blosum62ColourScheme)
+      if (getConservationSelected())
       {
-        recalc = true;
-        cs.setThreshold(viewStyle.getThreshold(),
-                ignoreGapsInConsensusCalculation);
+        residueShading.setConservation(hconservation);
       }
-      else
-      {
-        cs.setThreshold(0, ignoreGapsInConsensusCalculation);
-      }
-      if (recalc)
-      {
-        cs.setConsensus(hconsensus);
-        cs.setConservation(hconservation);
-      }
-      cs.setConservationApplied(getConservationSelected());
-      cs.alignmentChanged(alignment, hiddenRepSequences);
+      residueShading.alignmentChanged(alignment, hiddenRepSequences);
     }
+
+    /*
+     * if 'apply colour to all groups' is selected... do so
+     * (but don't transfer any colour threshold settings to groups)
+     */
     if (getColourAppliesToAllGroups())
     {
       for (SequenceGroup sg : getAlignment().getGroups())
       {
-        if (cs == null)
-        {
-          sg.cs = null;
-          continue;
-        }
-        sg.cs = cs.applyTo(sg, getHiddenRepSequences());
-        sg.setConsPercGaps(ConsPercGaps);
-        if (getAbovePIDThreshold() || cs instanceof PIDColourScheme
-                || cs instanceof Blosum62ColourScheme)
-        {
-          sg.cs.setThreshold(viewStyle.getThreshold(),
-                  isIgnoreGapsConsensus());
-          recalc = true;
-        }
-        else
+        /*
+         * retain any colour thresholds per group while
+         * changing choice of colour scheme (JAL-2386)
+         */
+        sg.setColourScheme(cs);
+        if (cs != null)
         {
-          sg.cs.setThreshold(0, isIgnoreGapsConsensus());
-        }
-
-        if (getConservationSelected())
-        {
-          sg.cs.setConservationApplied(true);
-          recalc = true;
-        }
-        else
-        {
-          sg.cs.setConservation(null);
-          // sg.cs.setThreshold(0, getIgnoreGapsConsensus());
-        }
-        if (recalc)
-        {
-          sg.recalcConservation();
-        }
-        else
-        {
-          sg.cs.alignmentChanged(sg, hiddenRepSequences);
+          sg.getGroupColourScheme()
+                  .alignmentChanged(sg, hiddenRepSequences);
         }
       }
     }
@@ -681,7 +658,14 @@ public abstract class AlignmentViewport implements AlignViewportI,
   @Override
   public ColourSchemeI getGlobalColourScheme()
   {
-    return globalColourScheme;
+    return residueShading == null ? null : residueShading
+            .getColourScheme();
+  }
+
+  @Override
+  public ResidueShaderI getResidueShading()
+  {
+    return residueShading;
   }
 
   protected AlignmentAnnotation consensus;
@@ -701,7 +685,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   /**
    * results of alignment consensus analysis for visible portion of view
    */
-  protected ProfileI[] hconsensus = null;
+  protected ProfilesI hconsensus = null;
 
   /**
    * results of cDNA complement consensus visible portion of view
@@ -735,7 +719,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public void setSequenceConsensusHash(ProfileI[] hconsensus)
+  public void setSequenceConsensusHash(ProfilesI hconsensus)
   {
     this.hconsensus = hconsensus;
   }
@@ -747,7 +731,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public ProfileI[] getSequenceConsensusHash()
+  public ProfilesI getSequenceConsensusHash()
   {
     return hconsensus;
   }
@@ -941,7 +925,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
     hconsensus = null;
     hcomplementConsensus = null;
     // colour scheme may hold reference to consensus
-    globalColourScheme = null;
+    residueShading = null;
     // TODO remove listeners from changeSupport?
     changeSupport = null;
     setAlignment(null);
@@ -1099,6 +1083,10 @@ public abstract class AlignmentViewport implements AlignViewportI,
   public void setSelectionGroup(SequenceGroup sg)
   {
     selectionGroup = sg;
+    if (sg != null)
+    {
+      sg.setContext(alignment);
+    }
   }
 
   public void setHiddenColumns(ColumnSelection colsel)
@@ -1211,9 +1199,9 @@ public abstract class AlignmentViewport implements AlignViewportI,
     if (ap != null)
     {
       updateConsensus(ap);
-      if (globalColourScheme != null)
+      if (residueShading != null)
       {
-        globalColourScheme.setThreshold(globalColourScheme.getThreshold(),
+        residueShading.setThreshold(residueShading.getThreshold(),
                 ignoreGapsInConsensusCalculation);
       }
     }
@@ -1849,7 +1837,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
       selectionGroup.setEndRes(alWidth - 1);
     }
 
-    resetAllColourSchemes();
+    updateAllColourSchemes();
     calculator.restartWorkers();
     // alignment.adjustSequenceAnnotations();
   }
@@ -1857,17 +1845,17 @@ public abstract class AlignmentViewport implements AlignViewportI,
   /**
    * reset scope and do calculations for all applied colourschemes on alignment
    */
-  void resetAllColourSchemes()
+  void updateAllColourSchemes()
   {
-    ColourSchemeI cs = globalColourScheme;
-    if (cs != null)
+    ResidueShaderI rs = residueShading;
+    if (rs != null)
     {
-      cs.alignmentChanged(alignment, hiddenRepSequences);
+      rs.alignmentChanged(alignment, hiddenRepSequences);
 
-      cs.setConsensus(hconsensus);
-      if (cs.conservationApplied())
+      rs.setConsensus(hconsensus);
+      if (rs.conservationApplied())
       {
-        cs.setConservation(Conservation.calculateConservation("All",
+        rs.setConservation(Conservation.calculateConservation("All",
                 alignment.getSequences(), 0, alignment.getWidth(), false,
                 getConsPercGaps(), false));
       }
@@ -2718,7 +2706,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    *          the SearchResults to add to
    * @return the offset (below top of visible region) of the matched sequence
    */
-  protected int findComplementScrollTarget(SearchResults sr)
+  protected int findComplementScrollTarget(SearchResultsI sr)
   {
     final AlignViewportI complement = getCodingComplement();
     if (complement == null || !complement.isFollowHighlight())
@@ -2825,6 +2813,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    */
   private boolean selectionIsDefinedGroup = false;
 
+
   @Override
   public boolean isSelectionDefinedGroup()
   {
@@ -2848,4 +2837,27 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return selectionGroup.getContext() == alignment
             || selectionIsDefinedGroup;
   }
+
+  /**
+   * null, or currently highlighted results on this view
+   */
+  private SearchResultsI searchResults = null;
+
+  @Override
+  public boolean hasSearchResults()
+  {
+    return searchResults != null;
+  }
+
+  @Override
+  public void setSearchResults(SearchResultsI results)
+  {
+    searchResults = results;
+  }
+
+  @Override
+  public SearchResultsI getSearchResults()
+  {
+    return searchResults;
+  }
 }