public interface ViewStyleI
{
+ void setShowComplementFeatures(boolean b);
+
+ boolean isShowComplementFeatures();
void setColourAppliesToAllGroups(boolean b);
package jalview.gui;
import jalview.api.FeatureColourI;
+import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.Mapping;
+import jalview.datamodel.SearchResultMatchI;
import jalview.datamodel.SearchResults;
import jalview.datamodel.SearchResultsI;
import jalview.datamodel.SequenceFeature;
{
Arrays.sort(renderOrder, order);
}
+
+ /**
+ * Answers a (possibly empty) list of features in this alignment at a position
+ * (or range) which is mappable from the given sequence residue position in a
+ * mapped alignment.
+ *
+ * @param sequence
+ * @param pos
+ * @return
+ */
+ public List<SequenceFeature> findComplementFeaturesAtResidue(
+ SequenceI sequence, int pos)
+ {
+ SequenceI ds = sequence.getDatasetSequence();
+ List<SequenceFeature> result = new ArrayList<>();
+ List<AlignedCodonFrame> mappings = this.av.getAlignment()
+ .getCodonFrame(sequence);
+ for (AlignedCodonFrame acf : mappings)
+ {
+ Mapping mapping = acf.getMappingForSequence(sequence);
+ if (mapping.getMap().getFromRatio() == mapping.getMap().getToRatio())
+ {
+ continue; // we are only looking for 3:1 or 1:3 mappings
+ }
+ SearchResultsI sr = new SearchResults();
+ acf.markMappedRegion(ds, pos, sr);
+ for (SearchResultMatchI match : sr.getResults())
+ {
+ for (int i = match.getStart(); i <= match.getEnd(); i++)
+ {
+ List<SequenceFeature> fs = findFeaturesAtResidue(
+ match.getSequence(), i);
+ for (SequenceFeature sf : fs)
+ {
+ if (!result.contains(sf))
+ {
+ result.addAll(fs);
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+ }
}
JSlider transparency = new JSlider();
+ JCheckBox showComplement;
+
/*
* when true, constructor is still executing - so ignore UI events
*/
transparency.setToolTipText(
MessageManager.getString("label.transparency_tip"));
+ boolean nucleotide = af.getViewport().getAlignment().isNucleotide();
+ showComplement = new JCheckBox(
+ "Show " + (nucleotide ? "protein" : "CDS") + " features");
+ showComplement.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ af.getViewport()
+ .setShowComplementFeatures(showComplement.isSelected());
+ }
+ });
+
JPanel transPanel = new JPanel(new GridLayout(1, 2));
bigPanel.add(transPanel, BorderLayout.SOUTH);
transbuttons.add(sortByScore);
transbuttons.add(sortByDens);
transbuttons.add(help);
- transPanel.add(transparency);
+
+ boolean hasComplement = af.getViewport().getCodingComplement() != null;
+ JPanel transPanelLeft = new JPanel(
+ new GridLayout(hasComplement ? 2 : 1, 1));
+ transPanelLeft.add(transparency);
+ if (hasComplement)
+ {
+ transPanelLeft.add(showComplement);
+ }
+ transPanel.add(transPanelLeft);
transPanel.add(transbuttons);
JPanel buttonPanel = new JPanel();
.findFeaturesAtColumn(sequence, column + 1);
seqARep.appendFeatures(tooltipText, pos, features,
this.ap.getSeqPanel().seqCanvas.fr);
+
+ /*
+ * add features in CDS/protein complement at the corresponding
+ * position if configured to do so
+ */
+ if (av.isShowComplementFeatures())
+ {
+ if (!Comparison.isGap(sequence.getCharAt(column)))
+ {
+ AlignViewportI complement = ap.getAlignViewport()
+ .getCodingComplement();
+ AlignFrame af = Desktop.getAlignFrameFor(complement);
+ FeatureRenderer fr2 = af.getFeatureRenderer();
+ features = fr2.findComplementFeaturesAtResidue(sequence, pos);
+ seqARep.appendFeatures(tooltipText, pos, features, fr2);
+ }
+ }
}
if (tooltipText.length() == 6) // <html>
{
viewStyle.setProteinFontAsCdna(b);
}
+ @Override
+ public void setShowComplementFeatures(boolean b)
+ {
+ viewStyle.setShowComplementFeatures(b);
+ }
+
+ @Override
+ public boolean isShowComplementFeatures()
+ {
+ return viewStyle.isShowComplementFeatures();
+ }
+
/**
* @return true if view should scroll to show the highlighted region of a
* sequence
visibleTypes);
/*
- * include features unless their feature group is not displayed, or
- * they are hidden (have no colour) based on a filter or colour threshold
+ * include features unless they are hidden (have no colour), based on
+ * feature group visibility, or a filter or colour threshold
*/
for (SequenceFeature sf : features)
{
- if (!featureGroupNotShown(sf) && getColour(sf) != null)
+ if (getColour(sf) != null)
{
result.add(sf);
}
private int fontStyle;
+ private boolean showComplementFeatures;
+
/**
* GUI state
*
{
proteinFontAsCdna = b;
}
+
+ @Override
+ public void setShowComplementFeatures(boolean b)
+ {
+ showComplementFeatures = b;
+ }
+
+ @Override
+ public boolean isShowComplementFeatures()
+ {
+ return showComplementFeatures;
+ }
}