JAL-2805 interface comments, progress on associating leaves
[jalview.git] / src / jalview / ext / archaeopteryx / AptxBinding.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 AptxBinding
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 AptxBinding(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   @Override
137   public void showNodeSelectionOnAlign(final MouseEvent e)
138   {
139     final PhylogenyNode node = treeView.findNode(e.getX(), e.getY());
140     if (node != null)
141     {
142       if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) // clear previous
143                                                            // selection if shift
144                                                            // IS NOT pressed
145       {
146         parentAvport.setSelectionGroup(null);
147       }
148
149       if (node.isInternal())
150       {
151         showMatchingChildSequences(node);
152       }
153
154       else
155       {
156         showMatchingSequence(node);
157       }
158
159     }
160   }
161
162
163
164
165   @Override
166   public void showMatchingSequence(final PhylogenyNode nodeToMatch)
167   {
168     SequenceI matchingSequence = nodesBoundToSequences.get(nodeToMatch);
169     if (matchingSequence != null)
170     {
171       treeSelectionChanged(matchingSequence);
172       parentAvport.sendSelection();
173       PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
174     }
175   }
176
177   @Override
178   public void showMatchingChildSequences(final PhylogenyNode parentNode)
179   {
180     final List<PhylogenyNode> childNodes = PhylogenyMethods
181             .getAllDescendants(parentNode);
182
183     for (PhylogenyNode childNode : childNodes)
184     {
185       SequenceI matchingSequence = nodesBoundToSequences.get(childNode);
186       if (matchingSequence != null)
187       {
188         treeSelectionChanged(matchingSequence);
189       }
190     }
191
192     parentAvport.sendSelection();
193     PaintRefresher.Refresh(treeView, parentAvport.getSequenceSetId());
194   }
195
196   /**
197    * Refactored from TreeCanvas.
198    * 
199    * @param sequence
200    *          of the node selected in the tree viewer.
201    */
202   @Override
203   public void treeSelectionChanged(final SequenceI sequence)
204   {
205     SequenceGroup selected = parentAvport.getSelectionGroup();
206
207     if (selected == null)
208     {
209       selected = new SequenceGroup();
210       parentAvport.setSelectionGroup(selected);
211     }
212
213     selected.setEndRes(parentAvport.getAlignment().getWidth() - 1);
214     selected.addOrRemove(sequence, true);
215
216   }
217
218   public AlignmentViewport getParentAvport()
219   {
220     return parentAvport;
221   }
222
223   public void setParentAvport(final AlignmentViewport parentAvport)
224   {
225     this.parentAvport = parentAvport;
226   }
227
228 }
229
230
231