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.gui.events.AlignmentPositionListener; 024import org.biojava.nbio.structure.gui.util.AlignedPosition; 025 026import java.awt.event.MouseEvent; 027import java.awt.event.MouseListener; 028import java.awt.event.MouseMotionListener; 029import java.util.ArrayList; 030import java.util.List; 031 032/** 033 * Mouse Motion Listener for the {@link MultipleAligPanel}, 034 * which provides methods to obtain positions of the mouse 035 * and connect them to the sequence alignment positions using 036 * the information in {@link MultipleAlignmentCoordManager}. 037 * 038 * @author Aleix Lafita 039 * 040 */ 041public class MultipleAligPanelMouseMotionListener 042implements MouseMotionListener, MouseListener { 043 044 private MultipleAligPanel parent; 045 private List<AlignmentPositionListener> aligPosListeners; 046 private int prevPos; 047 048 private boolean isDragging ; 049 private AlignedPosition selectionStart; 050 private AlignedPosition selectionEnd; 051 private boolean selectionLocked; 052 053 public MultipleAligPanelMouseMotionListener(MultipleAligPanel parent){ 054 this.parent = parent; 055 aligPosListeners = new ArrayList<AlignmentPositionListener>(); 056 prevPos = -1; 057 isDragging = false; 058 selectionStart = null; 059 selectionEnd = null; 060 selectionLocked = false; 061 } 062 063 public void addAligPosListener(AlignmentPositionListener li){ 064 aligPosListeners.add(li); 065 } 066 067 @Override 068 public void mouseDragged(MouseEvent e) { 069 070 AlignedPosition pos = getCurrentAlignedPosition(e); 071 072 if (pos == null) return; 073 if (prevPos == pos.getPos1() && isDragging) return; 074 075 if (!isDragging) { 076 isDragging = true; 077 setSelectionLock(true); 078 } 079 080 if (selectionStart == null) selectionStart = pos; 081 if (selectionEnd == null) selectionEnd = pos; 082 083 if (pos.getPos1() <= selectionStart.getPos1()) selectionStart = pos; 084 else selectionEnd = pos; 085 086 if (!keyPressed(e)) { 087 triggerRangeSelected(selectionStart, selectionEnd); 088 } else triggerRangeSelected(selectionStart, selectionEnd); 089 090 prevPos = pos.getPos1(); 091 } 092 093 private boolean keyPressed(MouseEvent e) { 094 if (e.isShiftDown() || e.isControlDown() || e.isAltDown()) 095 return true; 096 return false; 097 } 098 099 private void triggerRangeSelected( 100 AlignedPosition start, AlignedPosition end) { 101 for (AlignmentPositionListener li : aligPosListeners){ 102 li.rangeSelected(start, end); 103 } 104 } 105 106 public void triggerSelectionLocked(boolean b) { 107 selectionLocked = b; 108 for (AlignmentPositionListener li : aligPosListeners){ 109 if (b) li.selectionLocked(); 110 else li.selectionUnlocked(); 111 } 112 } 113 114 @Override 115 public void mouseMoved(MouseEvent e) { 116 if ( selectionLocked) return; 117 AlignedPosition pos = getCurrentAlignedPosition(e); 118 if ( pos == null) return; 119 120 triggerMouseOverPosition(pos); 121 } 122 123 private void triggerMouseOverPosition(AlignedPosition pos) { 124 for (AlignmentPositionListener li : aligPosListeners) 125 li.mouseOverPosition(pos); 126 } 127 128 private AlignedPosition getCurrentAlignedPosition(MouseEvent e) { 129 130 MultipleAlignmentCoordManager coordManager = parent.getCoordManager(); 131 int aligSeq = coordManager.getAligSeq(e.getPoint()); 132 133 //We are not over a position in the sequences 134 if (aligSeq == -1) return null; 135 136 //Get sequence positions 137 int seqPos = coordManager.getSeqPos(aligSeq, e.getPoint()); 138 if (seqPos < 0) return null; 139 if (seqPos >= parent.length) return null; 140 141 AlignedPosition pos = new AlignedPosition(); 142 pos.setPos1(seqPos); 143 144 if (parent.getMapSeqToStruct().get(seqPos)!=-1) 145 pos.setEquivalent(AlignedPosition.EQUIVALENT); 146 147 return pos; 148 } 149 150 public void destroy() { 151 aligPosListeners.clear(); 152 parent = null; 153 } 154 155 @Override 156 public void mouseClicked(MouseEvent e) {} 157 158 private void triggerToggleSelection(AlignedPosition pos) { 159 for (AlignmentPositionListener li : aligPosListeners) 160 li.toggleSelection(pos); 161 } 162 163 @Override 164 public void mouseEntered(MouseEvent e) {} 165 166 @Override 167 public void mouseExited(MouseEvent e) {} 168 169 @Override 170 public void mousePressed(MouseEvent e) { 171 172 selectionStart = null; 173 selectionEnd = null; 174 175 if (!keyPressed(e)) { 176 177 setSelectionLock(false); 178 triggerSelectionLocked(false); 179 180 AlignedPosition pos = getCurrentAlignedPosition(e); 181 if (pos != null) prevPos = pos.getPos1(); 182 } 183 } 184 185 private void setSelectionLock(boolean flag){ 186 selectionLocked = flag; 187 triggerSelectionLocked(flag); 188 } 189 190 @Override 191 public void mouseReleased(MouseEvent e) { 192 193 isDragging = false; 194 195 if (keyPressed(e)) { 196 boolean keepOn = false; 197 if (!selectionLocked) keepOn = true; 198 setSelectionLock(true); 199 200 // add to selection 201 AlignedPosition pos = getCurrentAlignedPosition(e); 202 if (pos == null) return; 203 204 if (keepOn) triggerMouseOverPosition(pos); 205 else triggerToggleSelection(pos); 206 prevPos = pos.getPos1(); 207 } 208 } 209}