--- /dev/null
+package jalview.api;
+
+import java.awt.Color;
+
+public interface FeatureColourI
+{
+
+ /**
+ * Answers true when either isColourByLabel, isAboveThreshold or
+ * isBelowThreshold answers true
+ *
+ * @return
+ */
+ boolean isGraduatedColour();
+
+ /**
+ * Returns the feature colour (when isGraduatedColour answers false)
+ *
+ * @return
+ */
+ Color getColour();
+
+ /**
+ * Returns the minimum colour (when isGraduatedColour answers true)
+ *
+ * @return
+ */
+ Color getMinColour();
+
+ /**
+ * Returns the maximum colour (when isGraduatedColour answers true)
+ *
+ * @return
+ */
+ Color getMaxColour();
+
+ /**
+ * Answers true if the feature is coloured by label (description); only
+ * applicable when isGraduatedColour answers true
+ *
+ * @return
+ */
+ boolean isColourByLabel();
+
+ /**
+ * Answers true if the feature is coloured below a threshold value; only
+ * applicable when isGraduatedColour answers true
+ *
+ * @return
+ */
+ boolean isBelowThreshold();
+
+ /**
+ * Answers true if the feature is coloured above a threshold value; only
+ * applicable when isGraduatedColour answers true
+ *
+ * @return
+ */
+ boolean isAboveThreshold();
+
+ /**
+ * Answers true if the threshold is the min (or max) of the colour range; only
+ * applicable when isGraduatedColour answers true
+ *
+ * @return
+ */
+ boolean isThresholdMinMax();
+
+ /**
+ * Returns the threshold value (if any), else zero
+ *
+ * @return
+ */
+ float getThreshold();
+
+ /**
+ * Answers true if ?
+ *
+ * @return
+ */
+ boolean isLowToHigh();
+}
--- /dev/null
+package jalview.api;
+
+/**
+ * An interface that describes the settings configurable in the Feature Settings
+ * dialog.
+ *
+ * @author gmcarstairs
+ *
+ */
+public interface FeatureSettingsI
+{
+ // note Java 8 will allow default implementations of these methods in the
+ // interface, simplifying instantiating classes
+
+ /**
+ * Answers true if the specified feature type is displayed
+ *
+ * @param type
+ * @return
+ */
+ boolean isFeatureDisplayed(String type);
+
+ /**
+ * Answers true if the specified feature group is displayed
+ *
+ * @param group
+ * @return
+ */
+ boolean isGroupDisplayed(String group);
+
+ /**
+ * Returns the colour (or graduated colour) for the feature type, or null if
+ * not known
+ *
+ * @param type
+ * @return
+ */
+ FeatureColourI getFeatureColour(String type);
+
+ /**
+ * Returns the transparency value, from 0 (fully transparent) to 1 (fully
+ * opaque)
+ *
+ * @return
+ */
+ float getTransparency();
+
+ /**
+ * Returns -1 if feature1 'precedes' (is displayed on top of) feature 2, +1 if
+ * feature2 is on top of feature1, or 0 if we don't care
+ *
+ * @param feature1
+ * @param feature2
+ * @return
+ */
+ int compareTo(String feature1, String feature2);
+
+ /**
+ * Answers true if features should be initially sorted so that features with a
+ * shorter average length are displayed on top of those with a longer average
+ * length
+ *
+ * @return
+ */
+ boolean optimiseOrder();
+}
--- /dev/null
+package jalview.schemes;
+
+import jalview.api.FeatureColourI;
+
+import java.awt.Color;
+
+/**
+ * A convenience class with implementations of FeatureColourI methods. Override
+ * methods as required in subclasses.
+ */
+public class FeatureColourAdapter implements FeatureColourI
+{
+ @Override
+ public boolean isGraduatedColour()
+ {
+ return isColourByLabel() || isAboveThreshold() || isBelowThreshold();
+ }
+
+ @Override
+ public Color getColour()
+ {
+ return Color.BLACK;
+ }
+
+ @Override
+ public Color getMinColour()
+ {
+ return Color.WHITE;
+ }
+
+ @Override
+ public Color getMaxColour()
+ {
+ return Color.BLACK;
+ }
+
+ @Override
+ public boolean isColourByLabel()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isBelowThreshold()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isAboveThreshold()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isThresholdMinMax()
+ {
+ return false;
+ }
+
+ @Override
+ public float getThreshold()
+ {
+ return 0f;
+ }
+
+ @Override
+ public boolean isLowToHigh()
+ {
+ return true;
+ }
+
+}
--- /dev/null
+package jalview.schemes;
+
+import jalview.api.FeatureColourI;
+import jalview.api.FeatureSettingsI;
+
+import java.awt.Color;
+
+/**
+ * Pre-set configurations for feature settings
+ *
+ * @author gmcarstairs
+ *
+ */
+public enum FeatureColourScheme implements FeatureSettingsI
+{
+ /**
+ * Show sequence variants in red, on top of exons coloured by label
+ */
+ EnsemblVariants
+ {
+
+ @Override
+ public boolean isFeatureDisplayed(String type)
+ {
+ // TODO accept SO sub-types of these features
+ // if (SequenceOntologyFactory.getInstance().isA(SequenceOntologyI.EXON...
+ return (EXON.equals(type) || SEQUENCE_VARIANT.equals(type));
+ }
+
+ @Override
+ public boolean isGroupDisplayed(String group)
+ {
+ return true;
+ }
+
+ @Override
+ public FeatureColourI getFeatureColour(String type)
+ {
+ if (EXON.equals(type))
+ {
+ return new FeatureColourAdapter()
+ {
+ @Override
+ public boolean isColourByLabel()
+ {
+ return true;
+ }
+ };
+ }
+ if (SEQUENCE_VARIANT.equals(type))
+ {
+ return new FeatureColourAdapter()
+ {
+
+ @Override
+ public Color getColour()
+ {
+ return Color.RED;
+ }
+ };
+ }
+ return null;
+ }
+
+ @Override
+ public float getTransparency()
+ {
+ return 1f;
+ }
+
+ /**
+ * Order sequence_variant above exon above the rest
+ */
+ @Override
+ public int compareTo(String feature1, String feature2)
+ {
+ if (SEQUENCE_VARIANT.equals(feature1))
+ {
+ return -1;
+ }
+ if (SEQUENCE_VARIANT.equals(feature2))
+ {
+ return +1;
+ }
+ if (EXON.equals(feature1))
+ {
+ return -1;
+ }
+ if (EXON.equals(feature2))
+ {
+ return +1;
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean optimiseOrder()
+ {
+ return false;
+ };
+
+ };
+
+ // SequenceOntologyI.SEQUENCE_VARIANT
+ private static final String SEQUENCE_VARIANT = "sequence_variant";
+
+ // SequenceOntologyI.EXON
+ private static final String EXON = "exon";
+}