JAL-4071 first working prototype
[jalview.git] / src / jalview / viewmodel / seqfeatures / FeatureRendererModel.java
index 8f513c9..9155440 100644 (file)
@@ -25,6 +25,7 @@ import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeSupport;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
@@ -35,6 +36,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureColourI;
 import jalview.api.FeaturesDisplayedI;
 import jalview.datamodel.AlignedCodonFrame;
@@ -51,6 +53,7 @@ import jalview.datamodel.features.SequenceFeatures;
 import jalview.renderer.seqfeatures.FeatureRenderer;
 import jalview.schemes.FeatureColour;
 import jalview.util.ColorUtils;
+import jalview.util.Platform;
 
 public abstract class FeatureRendererModel
         implements jalview.api.FeatureRenderer
@@ -312,7 +315,8 @@ public abstract class FeatureRendererModel
   }
 
   @Override
-  public List<SequenceFeature> findFeaturesAtColumn(SequenceI sequence, int column)
+  public List<SequenceFeature> findFeaturesAtColumn(SequenceI sequence,
+          int column)
   {
     /*
      * include features at the position provided their feature type is 
@@ -406,8 +410,8 @@ public abstract class FeatureRendererModel
         }
         if (groupDisplayed)
         {
-          Set<String> types = asq.getFeatures().getFeatureTypesForGroups(
-                  true, group);
+          Set<String> types = asq.getFeatures()
+                  .getFeatureTypesForGroups(true, group);
           for (String type : types)
           {
             if (!allfeatures.contains(type)) // or use HashSet and no test?
@@ -486,6 +490,7 @@ public abstract class FeatureRendererModel
       }
     }
   }
+
   protected Boolean firing = Boolean.FALSE;
 
   /**
@@ -624,10 +629,11 @@ public abstract class FeatureRendererModel
    * @param type
    * @return
    */
-  protected boolean showFeatureOfType(String type)
+  public boolean showFeatureOfType(String type)
   {
-    return type == null ? false : (av.getFeaturesDisplayed() == null ? true
-            : av.getFeaturesDisplayed().isVisible(type));
+    return type == null ? false
+            : (av.getFeaturesDisplayed() == null ? true
+                    : av.getFeaturesDisplayed().isVisible(type));
   }
 
   @Override
@@ -705,15 +711,15 @@ public abstract class FeatureRendererModel
   }
 
   /**
-   * Sets the priority order for features, with the highest priority (displayed on
-   * top) at the start of the data array
+   * Sets the priority order for features, with the highest priority (displayed
+   * on top) at the start of the data array
    * 
    * @param data
    *          an array of { Type, Colour, Filter, Boolean }
    * @param visibleNew
    *          when true current featureDisplay list will be cleared
-   * @return true if any visible features have been reordered or recoloured, else
-   *         false (i.e. no need to repaint)
+   * @return true if any visible features have been reordered or recoloured,
+   *         else false (i.e. no need to repaint)
    */
   public boolean setFeaturePriority(FeatureSettingsBean[] data,
           boolean visibleNew)
@@ -796,6 +802,7 @@ public abstract class FeatureRendererModel
    * @param listener
    * @see java.beans.PropertyChangeSupport#addPropertyChangeListener(java.beans.PropertyChangeListener)
    */
+  @Override
   public void addPropertyChangeListener(PropertyChangeListener listener)
   {
     changeSupport.addPropertyChangeListener(listener);
@@ -805,6 +812,7 @@ public abstract class FeatureRendererModel
    * @param listener
    * @see java.beans.PropertyChangeSupport#removePropertyChangeListener(java.beans.PropertyChangeListener)
    */
+  @Override
   public void removePropertyChangeListener(PropertyChangeListener listener)
   {
     changeSupport.removePropertyChangeListener(listener);
@@ -997,8 +1005,7 @@ public abstract class FeatureRendererModel
    */
   public boolean featureGroupNotShown(final SequenceFeature sequenceFeature)
   {
-    return featureGroups != null
-            && sequenceFeature.featureGroup != null
+    return featureGroups != null && sequenceFeature.featureGroup != null
             && sequenceFeature.featureGroup.length() != 0
             && featureGroups.containsKey(sequenceFeature.featureGroup)
             && !featureGroups.get(sequenceFeature.featureGroup)
@@ -1026,9 +1033,9 @@ public abstract class FeatureRendererModel
     List<String> visibleFeatures = getDisplayedFeatureTypes();
     String[] visibleTypes = visibleFeatures
             .toArray(new String[visibleFeatures.size()]);
-    List<SequenceFeature> features = sequence.getFeatures().findFeatures(
-            fromResNo, toResNo, visibleTypes);
-  
+    List<SequenceFeature> features = sequence.getFeatures()
+            .findFeatures(fromResNo, toResNo, visibleTypes);
+
     for (SequenceFeature sf : features)
     {
       if (!featureGroupNotShown(sf) && getColour(sf) != null)
@@ -1051,6 +1058,14 @@ public abstract class FeatureRendererModel
   public void filterFeaturesForDisplay(List<SequenceFeature> features)
   {
     /*
+     * fudge: JalviewJS's IntervalStore lacks the sort method called :-(
+     */
+    if (Platform.isJS())
+    {
+      return;
+    }
+
+    /*
      * don't remove 'redundant' features if 
      * - transparency is applied (feature count affects depth of feature colour)
      * - filters are applied (not all features may be displayable)
@@ -1080,8 +1095,7 @@ public abstract class FeatureRendererModel
        * (checking type and isContactFeature as a fail-safe here, although
        * currently they are guaranteed to match in this context)
        */
-      if (lastFeature != null
-              && sf.getBegin() == lastFeature.getBegin()
+      if (lastFeature != null && sf.getBegin() == lastFeature.getBegin()
               && sf.getEnd() == lastFeature.getEnd()
               && sf.isContactFeature() == lastFeature.isContactFeature()
               && sf.getType().equals(lastFeature.getType()))
@@ -1111,7 +1125,8 @@ public abstract class FeatureRendererModel
   }
 
   @Override
-  public void setFeatureFilter(String featureType, FeatureMatcherSetI filter)
+  public void setFeatureFilter(String featureType,
+          FeatureMatcherSetI filter)
   {
     if (filter == null || filter.isEmpty())
     {
@@ -1126,7 +1141,7 @@ public abstract class FeatureRendererModel
   /**
    * Answers the colour for the feature, or null if the feature is excluded by
    * feature group visibility, by filters, or by colour threshold settings. This
-   * method does not take feature visibility into account.
+   * method does not take feature type visibility into account.
    * 
    * @param sf
    * @param fc
@@ -1149,7 +1164,7 @@ public abstract class FeatureRendererModel
     {
       return null;
     }
-  
+
     return fc.getColor(sf);
   }
 
@@ -1167,6 +1182,33 @@ public abstract class FeatureRendererModel
     return filter == null ? true : filter.matches(sf);
   }
 
+  /**
+   * Answers true unless the specified group is set to hidden. Defaults to true
+   * if group visibility is not set.
+   * 
+   * @param group
+   * @return
+   */
+  public boolean isGroupVisible(String group)
+  {
+    if (!featureGroups.containsKey(group))
+    {
+      return true;
+    }
+    return featureGroups.get(group);
+  }
+
+  /**
+   * Orders features in render precedence (last in order is last to render, so
+   * displayed on top of other features)
+   * 
+   * @param order
+   */
+  public void orderFeatures(Comparator<String> order)
+  {
+    Arrays.sort(renderOrder, order);
+  }
+
   @Override
   public MappedFeatures findComplementFeaturesAtResidue(
           final SequenceI sequence, final int pos)
@@ -1213,8 +1255,8 @@ public abstract class FeatureRendererModel
         int fromRes = match.getStart();
         int toRes = match.getEnd();
         mapFrom = match.getSequence();
-        List<SequenceFeature> fs = findFeaturesAtResidue(
-                mapFrom, fromRes, toRes);
+        List<SequenceFeature> fs = findFeaturesAtResidue(mapFrom, fromRes,
+                toRes);
         for (SequenceFeature sf : fs)
         {
           if (!found.contains(sf))
@@ -1259,8 +1301,9 @@ public abstract class FeatureRendererModel
         }
       }
     }
-    
-    return new MappedFeatures(mapping.getMapping(), mapFrom, pos, residue, result);
+
+    return new MappedFeatures(mapping.getMapping(), mapFrom, pos, residue,
+            result);
   }
 
   @Override
@@ -1291,4 +1334,9 @@ public abstract class FeatureRendererModel
     return true;
   }
 
+  @Override
+  public AlignmentViewPanel getAlignPanel()
+  {
+    return null;
+  }
 }