X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2Fseqfeatures%2FFeatureRendererModel.java;h=81d1b7ed34569490789c9bc3578c0b94e33bc69f;hb=3d0101179759ef157b088ea135423cd909512d9f;hp=a4e434863ebeed9cd6ad3064ac5e62014a82d9b2;hpb=bf0d052fef43e9809b7170dbfd372b3ea116391b;p=jalview.git diff --git a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java index a4e4348..81d1b7e 100644 --- a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java +++ b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java @@ -28,8 +28,7 @@ import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.renderer.seqfeatures.FeatureRenderer; import jalview.schemes.FeatureColour; -import jalview.schemes.UserColourScheme; -import jalview.viewmodel.AlignmentViewport; +import jalview.util.ColorUtils; import java.awt.Color; import java.beans.PropertyChangeListener; @@ -37,6 +36,7 @@ import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; @@ -44,8 +44,8 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -public abstract class FeatureRendererModel implements - jalview.api.FeatureRenderer +public abstract class FeatureRendererModel + implements jalview.api.FeatureRenderer { /** @@ -64,7 +64,7 @@ public abstract class FeatureRendererModel implements protected PropertyChangeSupport changeSupport = new PropertyChangeSupport( this); - protected AlignmentViewport av; + protected AlignViewportI av; @Override public AlignViewportI getViewport() @@ -215,7 +215,8 @@ public abstract class FeatureRendererModel implements if (r[0] != 0 || mm[0] < 0.0) { r[0] = 1; - r[1] = (byte) ((int) 128.0 + 127.0 * (sequenceFeature.score / mm[1])); + r[1] = (byte) ((int) 128.0 + + 127.0 * (sequenceFeature.score / mm[1])); } else { @@ -264,7 +265,8 @@ public abstract class FeatureRendererModel implements } @Override - public List findFeaturesAtRes(SequenceI sequence, int res) + public List findFeaturesAtRes(SequenceI sequence, + int res) { ArrayList tmp = new ArrayList(); SequenceFeature[] features = sequence.getSequenceFeatures(); @@ -273,15 +275,13 @@ public abstract class FeatureRendererModel implements { for (int i = 0; i < features.length; i++) { - if (!av.areFeaturesDisplayed() - || !av.getFeaturesDisplayed().isVisible( - features[i].getType())) + if (!av.areFeaturesDisplayed() || !av.getFeaturesDisplayed() + .isVisible(features[i].getType())) { continue; } - if (features[i].featureGroup != null - && featureGroups != null + if (features[i].featureGroup != null && featureGroups != null && featureGroups.containsKey(features[i].featureGroup) && !featureGroups.get(features[i].featureGroup) .booleanValue()) @@ -289,8 +289,12 @@ public abstract class FeatureRendererModel implements continue; } - if ((features[i].getBegin() <= res) - && (features[i].getEnd() >= res)) + // check if start/end are at res, and if not a contact feature, that res + // lies between start and end + if ((features[i].getBegin() == res || features[i].getEnd() == res) + || (!features[i].isContactFeature() + && (features[i].getBegin() < res) + && (features[i].getEnd() >= res))) { tmp.add(features[i]); } @@ -341,6 +345,8 @@ public abstract class FeatureRendererModel implements { minmax = new Hashtable(); } + + Set oldGroups = new HashSet(featureGroups.keySet()); AlignmentI alignment = av.getAlignment(); for (int i = 0; i < alignment.getHeight(); i++) { @@ -355,9 +361,10 @@ public abstract class FeatureRendererModel implements int index = 0; while (index < features.length) { + String fgrp = features[index].getFeatureGroup(); + oldGroups.remove(fgrp); if (!featuresDisplayed.isRegistered(features[index].getType())) { - String fgrp = features[index].getFeatureGroup(); if (fgrp != null) { Boolean groupDisplayed = featureGroups.get(fgrp); @@ -421,6 +428,16 @@ public abstract class FeatureRendererModel implements index++; } } + + /* + * oldGroups now consists of groups that no longer + * have any feature in them - remove these + */ + for (String grp : oldGroups) + { + featureGroups.remove(grp); + } + updateRenderOrder(allfeatures); findingFeatures = false; } @@ -453,7 +470,8 @@ public abstract class FeatureRendererModel implements { if (initOrders) { - setOrder(oldRender[j], (1 - (1 + (float) j) / oldRender.length)); + setOrder(oldRender[j], + (1 - (1 + (float) j) / oldRender.length)); } if (allfeatures.contains(oldRender[j])) { @@ -539,7 +557,7 @@ public abstract class FeatureRendererModel implements FeatureColourI fc = featureColours.get(featureType); if (fc == null) { - Color col = UserColourScheme.createColourFromName(featureType); + Color col = ColorUtils.createColourFromName(featureType); fc = new FeatureColour(col); featureColours.put(featureType, fc); } @@ -547,40 +565,59 @@ public abstract class FeatureRendererModel implements } /** - * calculate the render colour for a specific feature using current feature - * settings. + * Returns the configured colour for a particular feature instance. This + * includes calculation of 'colour by label', or of a graduated score colour, + * if applicable. It does not take into account feature visibility or colour + * transparency. * * @param feature - * @return render colour for the given feature + * @return */ public Color getColour(SequenceFeature feature) { FeatureColourI fc = getFeatureStyle(feature.getType()); - return fc.getColor(feature); + return fc.isColored(feature) ? fc.getColor(feature) : null; } + /** + * Answers true unless the feature has a score value which lies outside a + * minimum or maximum threshold configured for colouring. This method does not + * check feature type or group visibility. + * + * @param sequenceFeature + * @return + */ protected boolean showFeature(SequenceFeature sequenceFeature) { FeatureColourI fc = getFeatureStyle(sequenceFeature.type); return fc.isColored(sequenceFeature); } + /** + * Answers true if the feature type is currently selected to be displayed, + * else false + * + * @param type + * @return + */ protected boolean showFeatureOfType(String type) { - return av.getFeaturesDisplayed().isVisible(type); + return type == null ? false : av.getFeaturesDisplayed().isVisible(type); } @Override public void setColour(String featureType, FeatureColourI col) { - featureColours.put(featureType, col); + featureColours.put(featureType, col); } + @Override public void setTransparency(float value) { transparency = value; } + @Override public float getTransparency() { return transparency; @@ -670,7 +707,8 @@ public abstract class FeatureRendererModel implements } else { - av.setFeaturesDisplayed(av_featuresdisplayed = new FeaturesDisplayed()); + av.setFeaturesDisplayed( + av_featuresdisplayed = new FeaturesDisplayed()); } } else @@ -782,11 +820,12 @@ public abstract class FeatureRendererModel implements { // conflict between applet and desktop - featureGroups returns the map in // the desktop featureRenderer - return (featureGroups == null) ? Arrays.asList(new String[0]) : Arrays - .asList(featureGroups.keySet().toArray(new String[0])); + return (featureGroups == null) ? Arrays.asList(new String[0]) + : Arrays.asList(featureGroups.keySet().toArray(new String[0])); } - public boolean checkGroupVisibility(String group, boolean newGroupsVisible) + public boolean checkGroupVisibility(String group, + boolean newGroupsVisible) { if (featureGroups == null) { @@ -812,7 +851,7 @@ public abstract class FeatureRendererModel implements * @return list of groups */ @Override - public List getGroups(boolean visible) + public List getGroups(boolean visible) { if (featureGroups != null) {