From de32fd704f78dafa5bed5eb64f9f96fab320971f Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 18 Jan 2019 15:12:46 +0000 Subject: [PATCH] JAL-3187 basic first version for tooltips only (rendering yet to do) --- src/jalview/api/ViewStyleI.java | 3 ++ src/jalview/gui/FeatureRenderer.java | 48 ++++++++++++++++++++ src/jalview/gui/FeatureSettings.java | 26 ++++++++++- src/jalview/gui/SeqPanel.java | 17 +++++++ src/jalview/viewmodel/AlignmentViewport.java | 12 +++++ .../seqfeatures/FeatureRendererModel.java | 6 +-- src/jalview/viewmodel/styles/ViewStyle.java | 14 ++++++ 7 files changed, 122 insertions(+), 4 deletions(-) diff --git a/src/jalview/api/ViewStyleI.java b/src/jalview/api/ViewStyleI.java index 2b554ea..978ce61 100644 --- a/src/jalview/api/ViewStyleI.java +++ b/src/jalview/api/ViewStyleI.java @@ -24,6 +24,9 @@ import java.awt.Color; public interface ViewStyleI { + void setShowComplementFeatures(boolean b); + + boolean isShowComplementFeatures(); void setColourAppliesToAllGroups(boolean b); diff --git a/src/jalview/gui/FeatureRenderer.java b/src/jalview/gui/FeatureRenderer.java index 46f574e..c2a84c6 100644 --- a/src/jalview/gui/FeatureRenderer.java +++ b/src/jalview/gui/FeatureRenderer.java @@ -21,6 +21,9 @@ 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; @@ -574,4 +577,49 @@ public class FeatureRenderer { 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 findComplementFeaturesAtResidue( + SequenceI sequence, int pos) + { + SequenceI ds = sequence.getDatasetSequence(); + List result = new ArrayList<>(); + List 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 fs = findFeaturesAtResidue( + match.getSequence(), i); + for (SequenceFeature sf : fs) + { + if (!result.contains(sf)) + { + result.addAll(fs); + } + } + } + } + } + + return result; + } } diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index dbe3317..35215b4 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -150,6 +150,8 @@ public class FeatureSettings extends JPanel JSlider transparency = new JSlider(); + JCheckBox showComplement; + /* * when true, constructor is still executing - so ignore UI events */ @@ -1260,6 +1262,19 @@ public class FeatureSettings extends JPanel 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); @@ -1269,7 +1284,16 @@ public class FeatureSettings extends JPanel 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(); diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index 8b2e7bc..6feda5a 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -847,6 +847,23 @@ public class SeqPanel extends 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) // { diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index 1366ada..ec3f12e 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -2714,6 +2714,18 @@ public abstract class AlignmentViewport 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 diff --git a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java index 553f813..1f69776 100644 --- a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java +++ b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java @@ -320,12 +320,12 @@ public abstract class FeatureRendererModel 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); } diff --git a/src/jalview/viewmodel/styles/ViewStyle.java b/src/jalview/viewmodel/styles/ViewStyle.java index 16aa580..1d1ab4d 100644 --- a/src/jalview/viewmodel/styles/ViewStyle.java +++ b/src/jalview/viewmodel/styles/ViewStyle.java @@ -365,6 +365,8 @@ public class ViewStyle implements ViewStyleI private int fontStyle; + private boolean showComplementFeatures; + /** * GUI state * @@ -1111,4 +1113,16 @@ public class ViewStyle implements ViewStyleI { proteinFontAsCdna = b; } + + @Override + public void setShowComplementFeatures(boolean b) + { + showComplementFeatures = b; + } + + @Override + public boolean isShowComplementFeatures() + { + return showComplementFeatures; + } } -- 1.7.10.2