5a494705feb8ea74bee1f1dfbe25723091790269
[jalview.git] / src / jalview / ext / archaeopteryx / JalviewAptxBinding.java
1 package jalview.ext.archaeopteryx;
2
3 import jalview.datamodel.ColumnSelection;
4 import jalview.datamodel.HiddenColumns;
5 import jalview.datamodel.SequenceGroup;
6 import jalview.datamodel.SequenceI;
7 import jalview.gui.PaintRefresher;
8 import jalview.structure.SelectionSource;
9 import jalview.structure.StructureSelectionManager;
10 import jalview.viewmodel.AlignmentViewport;
11
12 import java.awt.event.ActionEvent;
13 import java.awt.event.InputEvent;
14 import java.awt.event.MouseEvent;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18
19 import org.forester.archaeopteryx.MainFrame;
20 import org.forester.phylogeny.PhylogenyMethods;
21 import org.forester.phylogeny.PhylogenyNode;
22
23 /**
24  * Class for binding the Archaeopteryx tree viewer to the Jalview alignment that
25  * it originates from, meaning that selecting sequences in the tree viewer also
26  * selects them in the alignment view and vice versa.
27  * 
28  * @author kjvanderheide
29  *
30  */
31 public final class JalviewAptxBinding
32         implements ExternalTreeViewerBindingI<PhylogenyNode>
33 {
34   private org.forester.archaeopteryx.TreePanel treeView;
35
36   private AlignmentViewport parentAvport;
37
38   private final StructureSelectionManager ssm;
39
40   private Map<SequenceI, PhylogenyNode> sequencesBoundToNodes;
41
42   private Map<PhylogenyNode, SequenceI> nodesBoundToSequences;
43
44   /**
45    * 
46    * @param archaeopteryx
47    * 
48    * @param jalviewAlignmentViewport
49    *          alignment viewport from which the tree was calculated.
50    * 
51    * @param alignMappedToNodes
52    *          map with sequences used to calculate the tree and matching tree
53    *          nodes as key, value pair respectively.
54    * 
55    * @param nodesMappedToAlign
56    *          map with tree nodes and matching sequences used to calculate the
57    *          tree as key, value pair respectively.
58    */
59   public JalviewAptxBinding(final MainFrame archaeopteryx,
60           final AlignmentViewport jalviewAlignmentViewport,
61           final Map<SequenceI, PhylogenyNode> alignMappedToNodes,
62           final Map<PhylogenyNode, SequenceI> nodesMappedToAlign)
63   {
64     // deal with/prohibit null values here as that will cause problems
65     parentAvport = jalviewAlignmentViewport;
66     sequencesBoundToNodes = alignMappedToNodes;
67     nodesBoundToSequences = nodesMappedToAlign;
68     treeView = archaeopteryx.getMainPanel().getCurrentTreePanel();
69     ssm = parentAvport.getStructureSelectionManager();
70     ssm.addSelectionListener(this);
71     treeView.addMouseListener(this);
72     PaintRefresher.Register(treeView, parentAvport.getSequenceSetId());
73
74   }
75
76   @Override
77   public void actionPerformed(ActionEvent e)
78   {
79   }
80
81   @Override
82   public void mouseClicked(MouseEvent e)
83   {
84   }
85
86   @Override
87   public void mousePressed(final MouseEvent e)
88   {
89     showNodeSelectionOnAlign(e);
90   }
91
92   @Override
93   public void mouseReleased(MouseEvent e)
94   {
95   }
96
97   @Override
98   public void mouseEntered(MouseEvent e)
99   {
100   }
101
102   @Override
103   public void mouseExited(MouseEvent e)
104   {
105   }
106
107
108   @Override
109   public void selection(final SequenceGroup seqsel,
110           final ColumnSelection colsel, final HiddenColumns hidden,
111           final SelectionSource source)
112   {
113     if (source == parentAvport) // check if source is alignment from where the
114     // tree originates
115     {
116       treeView.setFoundNodes0(
117               new HashSet<Long>(seqsel.getSequences().size()));
118
119       for (SequenceI selectedSequence : seqsel.getSequences())
120       {
121         PhylogenyNode matchingNode = sequencesBoundToNodes.get(selectedSequence);
122         if (matchingNode != null)
123         {
124           treeView.getFoundNodes0().add(matchingNode.getId());
125         }
126
127       }
128       PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
129
130     }
131
132
133   }
134
135   /**
136    * If a node is selected in the tree panel this method highlights the
137    * corresponding sequence in the Jalview alignment view. If an internal node
138    * is selected all child sequences get highlighted as well.
139    */
140   @Override
141   public void showNodeSelectionOnAlign(final MouseEvent e)
142   {
143     final PhylogenyNode node = treeView.findNode(e.getX(), e.getY());
144     if (node != null)
145     {
146       if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) // clear previous
147       // selection if shift
148       // IS NOT pressed
149       {
150         parentAvport.setSelectionGroup(null);
151       }
152
153       if (node.isInternal())
154       {
155         showMatchingChildSequences(node);
156
157       }
158       else
159       {
160         showMatchingSequence(node);
161
162       }
163
164     }
165   }
166
167
168
169
170   @Override
171   public void showMatchingSequence(final PhylogenyNode nodeToMatch)
172   {
173     SequenceI matchingSequence = nodesBoundToSequences.get(nodeToMatch);
174     if (matchingSequence != null)
175     {
176       treeSelectionChanged(matchingSequence);
177       parentAvport.sendSelection();
178       PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
179     }
180   }
181
182   @Override
183   public void showMatchingChildSequences(final PhylogenyNode parentNode)
184   {
185     final List<PhylogenyNode> childNodes = PhylogenyMethods
186             .getAllDescendants(parentNode);
187
188     for (PhylogenyNode childNode : childNodes)
189     {
190       SequenceI matchingSequence = nodesBoundToSequences.get(childNode);
191       if (matchingSequence != null)
192       {
193         treeSelectionChanged(matchingSequence);
194       }
195     }
196
197     parentAvport.sendSelection();
198     PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
199   }
200
201   /**
202    * Refactored from TreeCanvas.
203    * 
204    * @param sequence
205    *          of the node selected in the tree viewer.
206    */
207   @Override
208   public void treeSelectionChanged(final SequenceI sequence)
209   {
210     SequenceGroup selected = parentAvport.getSelectionGroup();
211
212     if (selected == null)
213     {
214       selected = new SequenceGroup();
215       parentAvport.setSelectionGroup(selected);
216     }
217
218     selected.setEndRes(parentAvport.getAlignment().getWidth() - 1);
219     selected.addOrRemove(sequence, true);
220
221   }
222
223   public AlignmentViewport getParentAvport()
224   {
225     return parentAvport;
226   }
227
228   public void setParentAvport(final AlignmentViewport parentAvport)
229   {
230     this.parentAvport = parentAvport;
231   }
232
233 }
234
235
236