From 1f0742002d457b49733648b9369922bb0b78d2f0 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Wed, 13 Feb 2019 14:36:54 +0000 Subject: [PATCH] JAL-3187 'on top' optional for complementary features Conflicts: src/jalview/gui/FeatureSettings.java --- src/jalview/api/ViewStyleI.java | 4 + src/jalview/gui/FeatureSettings.java | 33 ++++- .../renderer/seqfeatures/FeatureRenderer.java | 129 ++++++++++++++------ src/jalview/viewmodel/AlignmentViewport.java | 12 ++ src/jalview/viewmodel/styles/ViewStyle.java | 14 +++ 5 files changed, 147 insertions(+), 45 deletions(-) diff --git a/src/jalview/api/ViewStyleI.java b/src/jalview/api/ViewStyleI.java index 978ce61..a348300 100644 --- a/src/jalview/api/ViewStyleI.java +++ b/src/jalview/api/ViewStyleI.java @@ -28,6 +28,10 @@ public interface ViewStyleI boolean isShowComplementFeatures(); + void setShowComplementFeaturesOnTop(boolean b); + + boolean isShowComplementFeaturesOnTop(); + void setColourAppliesToAllGroups(boolean b); boolean getColourAppliesToAllGroups(); diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index 7b8eae4..9dbeb8a 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -44,6 +44,7 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; +import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.GridLayout; @@ -153,6 +154,8 @@ public class FeatureSettings extends JPanel JCheckBox showComplement; + JCheckBox showComplementOnTop; + /* * when true, constructor is still executing - so ignore UI events */ @@ -1278,8 +1281,22 @@ public class FeatureSettings extends JPanel } }); - JPanel transPanel = new JPanel(new GridLayout(1, 2)); - bigPanel.add(transPanel, BorderLayout.SOUTH); + showComplementOnTop = new JCheckBox("on top"); + showComplementOnTop + .setSelected(af.getViewport().isShowComplementFeaturesOnTop()); + showComplementOnTop.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + af.getViewport().setShowComplementFeaturesOnTop( + showComplementOnTop.isSelected()); + refreshDisplay(); + } + }); + + JPanel lowerPanel = new JPanel(new GridLayout(1, 2)); + bigPanel.add(lowerPanel, BorderLayout.SOUTH); JPanel transbuttons = new JPanel(new GridLayout(5, 1)); transbuttons.add(optimizeOrder); @@ -1290,14 +1307,18 @@ public class FeatureSettings extends JPanel boolean hasComplement = af.getViewport().getCodingComplement() != null; JPanel transPanelLeft = new JPanel( - new GridLayout(hasComplement ? 2 : 1, 1)); + new GridLayout(hasComplement ? 3 : 2, 1)); + transPanelLeft.add(new JLabel(" Colour transparency" + ":")); transPanelLeft.add(transparency); if (hasComplement) { - transPanelLeft.add(showComplement); + JPanel cp = new JPanel(new FlowLayout(FlowLayout.LEFT)); + cp.add(showComplement); + cp.add(showComplementOnTop); + transPanelLeft.add(cp); } - transPanel.add(transPanelLeft); - transPanel.add(transbuttons); + lowerPanel.add(transPanelLeft); + lowerPanel.add(transbuttons); JPanel buttonPanel = new JPanel(); buttonPanel.add(ok); diff --git a/src/jalview/renderer/seqfeatures/FeatureRenderer.java b/src/jalview/renderer/seqfeatures/FeatureRenderer.java index 4e81e69..78f4989 100644 --- a/src/jalview/renderer/seqfeatures/FeatureRenderer.java +++ b/src/jalview/renderer/seqfeatures/FeatureRenderer.java @@ -294,6 +294,16 @@ public class FeatureRenderer extends FeatureRendererModel Color drawnColour = null; /* + * draw 'complement' features below ours if configured to do so + */ + if (av.isShowComplementFeatures() + && !av.isShowComplementFeaturesOnTop()) + { + drawnColour = drawComplementFeatures(g, seq, start, end, y1, + colourOnly, visiblePositions, drawnColour); + } + + /* * iterate over features in ordering of their rendering (last is on top) */ for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++) @@ -399,27 +409,12 @@ public class FeatureRenderer extends FeatureRendererModel } /* - * if configured to do so, find and show complement's features + * draw 'complement' features above ours if configured to do so */ - if (av.isShowComplementFeatures()) + if (av.isShowComplementFeatures() && av.isShowComplementFeaturesOnTop()) { - AlignViewportI comp = av.getCodingComplement(); - FeatureRenderer fr2 = Desktop.getAlignFrameFor(comp) - .getFeatureRenderer(); - for (int pos = visiblePositions.start; pos <= visiblePositions.end; pos++) - { - int column = seq.findIndex(pos); - List features = fr2 - .findComplementFeaturesAtResidue(seq, pos); - for (SequenceFeature sf : features) - { - FeatureColourI fc = fr2.getFeatureStyle(sf.getType()); - Color featureColour = fr2.getColor(sf, fc); - renderFeature(g, seq, column - 1, column - 1, featureColour, - start, end, y1, colourOnly); - drawnColour = featureColour; - } - } + drawnColour = drawComplementFeatures(g, seq, start, end, y1, + colourOnly, visiblePositions, drawnColour); } if (transparency != 1.0f && g != null) @@ -435,6 +430,45 @@ public class FeatureRenderer extends FeatureRendererModel } /** + * Find any features on the CDS/protein complement of the sequence region and + * draw them, with visibility and colouring as configured in the complementary + * viewport + * + * @param g + * @param seq + * @param start + * @param end + * @param y1 + * @param colourOnly + * @param visiblePositions + * @param drawnColour + * @return + */ + Color drawComplementFeatures(final Graphics g, final SequenceI seq, + int start, int end, int y1, boolean colourOnly, + Range visiblePositions, Color drawnColour) + { + AlignViewportI comp = av.getCodingComplement(); + FeatureRenderer fr2 = Desktop.getAlignFrameFor(comp) + .getFeatureRenderer(); + for (int pos = visiblePositions.start; pos <= visiblePositions.end; pos++) + { + int column = seq.findIndex(pos); + List features = fr2 + .findComplementFeaturesAtResidue(seq, pos); + for (SequenceFeature sf : features) + { + FeatureColourI fc = fr2.getFeatureStyle(sf.getType()); + Color featureColour = fr2.getColor(sf, fc); + renderFeature(g, seq, column - 1, column - 1, featureColour, + start, end, y1, colourOnly); + drawnColour = featureColour; + } + } + return drawnColour; + } + + /** * Called when alignment in associated view has new/modified features to * discover and display. * @@ -471,27 +505,12 @@ public class FeatureRenderer extends FeatureRendererModel /* * show complement features on top (if configured to show them) */ - if (av.isShowComplementFeatures()) + if (av.isShowComplementFeatures() && av.isShowComplementFeaturesOnTop()) { - AlignViewportI complement = av.getCodingComplement(); - AlignFrame af = Desktop.getAlignFrameFor(complement); - FeatureRendererModel fr2 = af.getFeatureRenderer(); - List features = fr2.findComplementFeaturesAtResidue( - seq, seq.findPosition(column - 1)); - - ReverseListIterator it = new ReverseListIterator<>( - features); - while (it.hasNext()) + Color col = findComplementFeatureColour(seq, column); + if (col != null) { - SequenceFeature sf = it.next(); - if (!fr2.featureGroupNotShown(sf)) - { - Color col = fr2.getColour(sf); - if (col != null) - { - return col; - } - } + return col; } } @@ -524,8 +543,40 @@ public class FeatureRenderer extends FeatureRendererModel } /* - * no displayed feature found at position + * show complement features underneath (if configured to show them) */ + Color col = null; + if (av.isShowComplementFeatures() + && !av.isShowComplementFeaturesOnTop()) + { + col = findComplementFeatureColour(seq, column); + } + + return col; + } + + Color findComplementFeatureColour(SequenceI seq, int column) + { + AlignViewportI complement = av.getCodingComplement(); + AlignFrame af = Desktop.getAlignFrameFor(complement); + FeatureRendererModel fr2 = af.getFeatureRenderer(); + List features = fr2.findComplementFeaturesAtResidue( + seq, seq.findPosition(column - 1)); + + ReverseListIterator it = new ReverseListIterator<>( + features); + while (it.hasNext()) + { + SequenceFeature sf = it.next(); + if (!fr2.featureGroupNotShown(sf)) + { + Color col = fr2.getColour(sf); + if (col != null) + { + return col; + } + } + } return null; } } diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java index ec3f12e..1ae879b 100644 --- a/src/jalview/viewmodel/AlignmentViewport.java +++ b/src/jalview/viewmodel/AlignmentViewport.java @@ -2726,6 +2726,18 @@ public abstract class AlignmentViewport return viewStyle.isShowComplementFeatures(); } + @Override + public void setShowComplementFeaturesOnTop(boolean b) + { + viewStyle.setShowComplementFeaturesOnTop(b); + } + + @Override + public boolean isShowComplementFeaturesOnTop() + { + return viewStyle.isShowComplementFeaturesOnTop(); + } + /** * @return true if view should scroll to show the highlighted region of a * sequence diff --git a/src/jalview/viewmodel/styles/ViewStyle.java b/src/jalview/viewmodel/styles/ViewStyle.java index d68227b..7fa1e39 100644 --- a/src/jalview/viewmodel/styles/ViewStyle.java +++ b/src/jalview/viewmodel/styles/ViewStyle.java @@ -369,6 +369,8 @@ public class ViewStyle implements ViewStyleI private boolean showComplementFeatures; + private boolean showComplementFeaturesOnTop; + /** * GUI state * @@ -1127,4 +1129,16 @@ public class ViewStyle implements ViewStyleI { return showComplementFeatures; } + + @Override + public void setShowComplementFeaturesOnTop(boolean b) + { + showComplementFeaturesOnTop = b; + } + + @Override + public boolean isShowComplementFeaturesOnTop() + { + return showComplementFeaturesOnTop; + } } -- 1.7.10.2