001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.nbio.structure.align.gui.aligpanel;
022
023import org.biojava.nbio.structure.align.model.AFPChain;
024import org.biojava.nbio.structure.gui.events.AlignmentPositionListener;
025import org.biojava.nbio.structure.gui.util.AlignedPosition;
026
027import java.awt.event.MouseEvent;
028import java.awt.event.MouseListener;
029import java.awt.event.MouseMotionListener;
030import java.util.ArrayList;
031import java.util.List;
032
033public class AligPanelMouseMotionListener implements MouseMotionListener, MouseListener {
034
035        AligPanel parent;
036
037        List<AlignmentPositionListener> aligPosListeners;
038        int prevPos;
039
040        boolean isDragging ;
041        AlignedPosition selectionStart ;
042        AlignedPosition selectionEnd;
043        boolean selectionLocked;
044
045        public AligPanelMouseMotionListener(AligPanel parent){
046                this.parent = parent;
047                aligPosListeners = new ArrayList<AlignmentPositionListener>();
048                prevPos = -1;
049                isDragging = false;
050                selectionStart = null;
051                selectionEnd = null;
052                selectionLocked = false;
053        }
054
055        public void addAligPosListener(AlignmentPositionListener li){
056                aligPosListeners.add(li);
057        }
058
059        @Override
060        public void mouseDragged(MouseEvent e) {
061
062
063                AlignedPosition pos = getCurrentAlignedPosition(e);
064
065                if ( pos == null)
066                        return;
067
068
069                int p = pos.getPos1();
070
071                if ( prevPos == p && isDragging) {
072
073                        return;
074                }
075
076
077                if ( ! isDragging) {
078                        isDragging = true;
079
080                        setSelectionLock(true);
081
082                }
083
084
085                if ( selectionStart == null)
086                        selectionStart = pos;
087                if ( selectionEnd == null)
088                        selectionEnd = pos;
089
090                if ( p <= selectionStart.getPos1()) {
091                        //selectionEnd = selectionStart;
092                        selectionStart = pos;
093
094                } else {
095                        selectionEnd = pos;
096                }
097
098                //System.out.println("sel start : " + selectionStart + " - " + selectionEnd);
099
100                if ( ! keyPressed(e)) {
101                        triggerRangeSelected(selectionStart, selectionEnd);
102                } else {
103                        triggerRangeSelected(selectionStart, selectionEnd);
104                        //triggerToggleRange(selectionStart, selectionEnd);
105                }
106                prevPos = p;
107        }
108
109
110        private boolean keyPressed(MouseEvent e) {
111                if ( e.isShiftDown() || e.isControlDown() || e.isAltDown())
112                        return true;
113                return false;
114        }
115
116        private void triggerRangeSelected(AlignedPosition start,
117                        AlignedPosition end) {
118                for (AlignmentPositionListener li : aligPosListeners){
119                        li.rangeSelected(start, end);
120                }
121        }
122        public void triggerSelectionLocked(boolean b) {
123                selectionLocked = b;
124                for (AlignmentPositionListener li : aligPosListeners){
125                        if ( b)
126                                li.selectionLocked();
127                        else
128                                li.selectionUnlocked();
129                }
130
131        }
132        @Override
133        public void mouseMoved(MouseEvent e) {
134                if ( selectionLocked)
135                        return;
136                AlignedPosition pos = getCurrentAlignedPosition(e);
137                if ( pos == null)
138                        return;
139
140                triggerMouseOverPosition(pos);
141
142
143
144
145        }
146
147        private void triggerMouseOverPosition(AlignedPosition pos) {
148                for (AlignmentPositionListener li : aligPosListeners){
149                        li.mouseOverPosition(pos);
150                }
151
152
153        }
154
155        private AlignedPosition getCurrentAlignedPosition(MouseEvent e){
156                AFPChainCoordManager coordManager = parent.getCoordManager();
157
158                int aligSeq = coordManager.getAligSeq(e.getPoint());
159
160                // we are over a position in the sequences
161                if ( aligSeq == -1) {
162                        return null;
163                }
164
165                //get sequence positions
166                int seqPos = coordManager.getSeqPos(aligSeq, e.getPoint());
167
168                //if ( prevPos == seqPos)
169                //      return null;
170
171
172                //prevPos = seqPos;
173
174                if ( seqPos < 0)
175                        return null;
176
177
178
179                AFPChain afpChain = parent.getAFPChain();
180                char[] aligs1  = afpChain.getAlnseq1();
181                char[] aligs2  = afpChain.getAlnseq2();
182
183                if ( seqPos >= afpChain.getAlnLength()) {
184                        //System.err.println("seqpos " + seqPos +" >= " + afpChain.getAlnLength());
185                        return null;
186                }
187
188                //System.out.println("alignment " + aligSeq + " " + seqPos + " : ");
189                AlignedPosition pos = new AlignedPosition();
190                pos.setPos1(seqPos);
191                pos.setPos2(seqPos);
192
193                if ( aligs1[seqPos] != '-' && aligs2[seqPos] != '-'){
194                        pos.setEquivalent(AlignedPosition.EQUIVALENT);
195                }
196
197                return pos;
198        }
199
200        public void destroy() {
201                aligPosListeners.clear();
202                parent = null;
203
204        }
205
206        @Override
207        public void mouseClicked(MouseEvent e) {
208
209        }
210
211        private void triggerToggleSelection(AlignedPosition pos) {
212                for (AlignmentPositionListener li : aligPosListeners){
213                        li.toggleSelection(pos);
214                }
215
216        }
217
218
219//      private void triggerToggleRange(AlignedPosition start,
220//                      AlignedPosition end) {
221//              for (AlignmentPositionListener li : aligPosListeners){
222//                      for ( int i = start.getPos1() ; i < end.getPos1() ; i++){
223//                              AlignedPosition pos = new AlignedPosition();
224//                              pos.setPos1(i);
225//                              pos.setPos2(i);
226//                              li.toggleSelection(pos);
227//                      }
228//              }
229//
230//      }
231
232        @Override
233        public void mouseEntered(MouseEvent e) {
234                // TODO Auto-generated method stub
235
236        }
237
238        @Override
239        public void mouseExited(MouseEvent e) {
240
241
242        }
243
244        @Override
245        public void mousePressed(MouseEvent e) {
246
247                selectionStart = null;
248                selectionEnd = null;
249
250                if ( ! keyPressed(e) ) {
251                        //System.out.println("mouse pressed " + e.isShiftDown() + " selection locked: " + selectionLocked);
252
253                        setSelectionLock(false);
254                        //System.out.println("selection unlocked by mousePressed");
255                        triggerSelectionLocked(false);
256
257                        AlignedPosition pos = getCurrentAlignedPosition(e);
258                        if ( pos != null) {
259                                prevPos = pos.getPos1();
260                        }
261
262
263                }
264
265
266        }
267
268
269        private void setSelectionLock(boolean flag){
270                selectionLocked = flag;
271                triggerSelectionLocked(flag);
272        }
273
274        @Override
275        public void mouseReleased(MouseEvent e) {
276
277                isDragging = false;
278                //System.out.println("mouse released... " + e.isShiftDown() + " selection locked:" + selectionLocked);
279                if ( keyPressed(e)) {
280                        boolean keepOn = false;
281                        if ( ! selectionLocked)
282                                keepOn = true;
283                        setSelectionLock(true);
284
285
286                        // add to selection
287                        AlignedPosition pos = getCurrentAlignedPosition(e);
288                        if ( pos == null)
289                                return;
290
291                        if ( keepOn)
292                                triggerMouseOverPosition(pos);
293                        else
294                                triggerToggleSelection(pos);
295                        prevPos = pos.getPos1() ;
296
297                }
298
299
300
301
302        }
303
304}