JAL-3187 return a colour for linked features with transparency
[jalview.git] / src / jalview / renderer / seqfeatures / FeatureRenderer.java
index e81e519..4e81e69 100644 (file)
@@ -25,7 +25,10 @@ import jalview.api.FeatureColourI;
 import jalview.datamodel.Range;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
 import jalview.util.Comparison;
+import jalview.util.ReverseListIterator;
 import jalview.viewmodel.seqfeatures.FeatureRendererModel;
 
 import java.awt.AlphaComposite;
@@ -216,7 +219,8 @@ public class FeatureRenderer extends FeatureRendererModel
       return null;
     }
 
-    if (Comparison.isGap(seq.getCharAt(column)))
+    // column is 'base 1' but getCharAt is an array index (ie from 0)
+    if (Comparison.isGap(seq.getCharAt(column - 1)))
     {
       /*
        * returning null allows the colour scheme to provide gap colour
@@ -272,7 +276,8 @@ public class FeatureRenderer extends FeatureRendererModel
      * if columns are all gapped, or sequence has no features, nothing to do
      */
     Range visiblePositions = seq.findPositions(start+1, end+1);
-    if (visiblePositions == null || !seq.getFeatures().hasFeatures())
+    if (visiblePositions == null || (!seq.getFeatures().hasFeatures()
+            && !av.isShowComplementFeatures()))
     {
       return null;
     }
@@ -303,14 +308,19 @@ public class FeatureRenderer extends FeatureRendererModel
       List<SequenceFeature> overlaps = seq.getFeatures().findFeatures(
               visiblePositions.getBegin(), visiblePositions.getEnd(), type);
 
-      filterFeaturesForDisplay(overlaps, fc);
+      if (fc.isSimpleColour())
+      {
+        filterFeaturesForDisplay(overlaps);
+      }
 
       for (SequenceFeature sf : overlaps)
       {
-        Color featureColour = fc.getColor(sf);
+        Color featureColour = getColor(sf, fc);
         if (featureColour == null)
         {
-          // score feature outwith threshold for colouring
+          /*
+           * feature excluded by filters, or colour threshold
+           */
           continue;
         }
 
@@ -388,6 +398,30 @@ public class FeatureRenderer extends FeatureRendererModel
       }
     }
 
+    /*
+     * if configured to do so, find and show complement's features
+     */
+    if (av.isShowComplementFeatures())
+    {
+      AlignViewportI comp = av.getCodingComplement();
+      FeatureRenderer fr2 = Desktop.getAlignFrameFor(comp)
+              .getFeatureRenderer();
+      for (int pos = visiblePositions.start; pos <= visiblePositions.end; pos++)
+      {
+        int column = seq.findIndex(pos);
+        List<SequenceFeature> features = fr2
+                .findComplementFeaturesAtResidue(seq, pos);
+        for (SequenceFeature sf : features)
+        {
+          FeatureColourI fc = fr2.getFeatureStyle(sf.getType());
+          Color featureColour = fr2.getColor(sf, fc);
+          renderFeature(g, seq, column - 1, column - 1, featureColour,
+                  start, end, y1, colourOnly);
+          drawnColour = featureColour;
+        }
+      }
+    }
+
     if (transparency != 1.0f && g != null)
     {
       /*
@@ -401,27 +435,6 @@ public class FeatureRenderer extends FeatureRendererModel
   }
 
   /**
-<<<<<<< HEAD
-=======
-   * Answers true if the feature belongs to a feature group which is not
-   * currently displayed, else false
-   * 
-   * @param sequenceFeature
-   * @return
-   */
-  @Override
-  protected boolean featureGroupNotShown(
-          final SequenceFeature sequenceFeature)
-  {
-    return featureGroups != null && sequenceFeature.featureGroup != null
-            && sequenceFeature.featureGroup.length() != 0
-            && featureGroups.containsKey(sequenceFeature.featureGroup)
-            && !featureGroups.get(sequenceFeature.featureGroup)
-                    .booleanValue();
-  }
-
-  /**
->>>>>>> refs/heads/develop
    * Called when alignment in associated view has new/modified features to
    * discover and display.
    * 
@@ -456,6 +469,33 @@ public class FeatureRenderer extends FeatureRendererModel
     updateFeatures();
 
     /*
+     * show complement features on top (if configured to show them)
+     */
+    if (av.isShowComplementFeatures())
+    {
+      AlignViewportI complement = av.getCodingComplement();
+      AlignFrame af = Desktop.getAlignFrameFor(complement);
+      FeatureRendererModel fr2 = af.getFeatureRenderer();
+      List<SequenceFeature> features = fr2.findComplementFeaturesAtResidue(
+              seq, seq.findPosition(column - 1));
+
+      ReverseListIterator<SequenceFeature> it = new ReverseListIterator<>(
+              features);
+      while (it.hasNext())
+      {
+        SequenceFeature sf = it.next();
+        if (!fr2.featureGroupNotShown(sf))
+        {
+          Color col = fr2.getColour(sf);
+          if (col != null)
+          {
+            return col;
+          }
+        }
+      }
+    }
+
+    /*
      * inspect features in reverse renderOrder (the last in the array is 
      * displayed on top) until we find one that is rendered at the position
      */