package jalview.appletgui; import java.awt.*; import java.awt.event.*; import jalview.datamodel.*; import java.util.*; import jalview.schemes.*; public class SeqPanel extends Panel { public SeqCanvas seqCanvas; public AlignmentPanel ap; protected int startres; protected int lastres; protected int endres; protected int startseq; protected int padseq; protected AlignViewport av; // if character is inserted or deleted, we will need to recalculate the conservation int seqEditOccurred = -1; ScrollThread scrollThread = null; boolean mouseDragging = false; public SeqPanel(AlignViewport avp, AlignmentPanel p) { this.av = avp; seqCanvas = new SeqCanvas(avp); setLayout(new BorderLayout()); add(seqCanvas); ap = p; seqCanvas.addMouseMotionListener( new MouseMotionAdapter() { public void mouseMoved(MouseEvent evt) { if(av.getWrapAlignment()) return; doMouseMoved(evt); } public void mouseDragged(MouseEvent evt) { if(av.getWrapAlignment()) return; if(evt.isShiftDown() || evt.isAltDown() || evt.isControlDown()) doMouseDragged(evt); else doMouseDraggedDefineMode(evt); } }); seqCanvas.addMouseListener( new MouseAdapter() { public void mouseReleased(MouseEvent evt) { if(av.getWrapAlignment()) return; if(evt.isShiftDown() || evt.isAltDown() || evt.isControlDown()) doMouseReleased(evt); else doMouseReleasedDefineMode(evt); } public void mousePressed(MouseEvent evt) { if(av.getWrapAlignment()) return; if(evt.isShiftDown() || evt.isAltDown() || evt.isControlDown()) doMousePressed(evt); else doMousePressedDefineMode(evt); } public void mouseExited(MouseEvent evt) { if (av.getWrapAlignment() || evt.isShiftDown() || evt.isAltDown() || evt.isControlDown()) return; doMouseExitedDefineMode(evt); } public void mouseEntered(MouseEvent evt) { if (av.getWrapAlignment() || evt.isShiftDown() || evt.isAltDown() || evt.isControlDown()) return; doMouseEnteredDefineMode(evt); } }); seqCanvas.repaint(); } public void doMouseReleased(MouseEvent evt) { int x = evt.getX(); int res = x/av.getCharWidth() + av.getStartRes(); endres = res; startseq = -1; startres = -1; lastres = -1; if(seqEditOccurred>-1) updateConservation(seqEditOccurred); seqEditOccurred = -1; ap.repaint(); } public void doMousePressed(MouseEvent evt) { ap.alignFrame.addHistoryItem("sequence edit"); int seq; int res; int x = evt.getX(); int y = evt.getY(); res = x/av.getCharWidth() + av.getStartRes(); seq = y/av.getCharHeight() + av.getStartSeq(); if (seq < av.getAlignment().getHeight() && res < av.getAlignment().getSequenceAt(seq).getLength()) { //char resstr = align.getSequenceAt(seq).getSequence().charAt(res); // Find the residue's position in the sequence (res is the position // in the alignment startseq = seq; if (startseq == (av.getAlignment().getHeight() - 1)) padseq = 1; else padseq = 1; startres = res; lastres = res; } else { startseq = -1; startres = -1; lastres = -1; } return; } public void doMouseMoved(MouseEvent evt) { int res=0, seq=0; int x = evt.getX(); int y = evt.getY(); if(av.wrapAlignment) { y -= 2*av.charHeight; int chunkHeight = (av.getAlignment().getHeight()+2)*av.charHeight; res = (int)((y/chunkHeight)*(getSize().width/av.charWidth)) + x/av.getCharWidth() + av.getStartRes(); y %= chunkHeight; seq = y / av.getCharHeight() + av.getStartSeq(); } else { res = x / av.getCharWidth() + av.getStartRes(); seq = y / av.getCharHeight() + av.getStartSeq(); } if(seq>=av.getAlignment().getHeight()) return; SequenceI sequence = av.getAlignment().getSequenceAt(seq); if(res>sequence.getLength()) return; Object obj = ResidueProperties.aa2Triplet.get( sequence.getCharAt(res)+"" ) ; String aa = ""; if(obj!=null) aa = obj.toString(); StringBuffer text = new StringBuffer("Sequence " +(seq+1)+" ID: "+sequence.getName()); if(aa!="") text.append(" Residue: "+aa+" ("+ av.getAlignment().getSequenceAt(seq).findPosition(res)+")"); ap.alignFrame.statusBar.setText(text.toString()); // use aa to see if the mouse pointer is on a if( av.showSequenceFeatures) { Vector features = sequence.getSequenceFeatures(); Enumeration e = features.elements(); StringBuffer sbuffer = new StringBuffer(); while (e.hasMoreElements()) { SequenceFeature sf = (SequenceFeature) e.nextElement(); if (sf.getStart() <= sequence.findPosition(res) && sf.getEnd() >= sequence.findPosition(res)) { if(sbuffer.length()>0) sbuffer.append("; "); sbuffer.append(sf.getType() + " " + sf.getDescription()); if(sf.getStatus().length()>0) sbuffer.append(" ("+sf.getStatus()+")"); } } } } public void doMouseDragged(MouseEvent evt) { // If we're dragging we're editing if(lastres==-1) return; int x = evt.getX(); int res = x/av.getCharWidth() + av.getStartRes(); if (res < 0) res = 0; if (res != lastres) { // Group editing if (evt.isAltDown() || evt.isControlDown()) { SequenceGroup sg = av.getSelectionGroup(); if(sg==null) av.getAlignment().findGroup(startseq); if (sg != null) { boolean deleteAllowed = false; if (res < av.getAlignment().getWidth() && res < lastres) { /// Are we able to delete? boolean allGaps = true; for (int i = 0; i < sg.getSize(); i++) { SequenceI s = sg.getSequenceAt(i); for (int j = lastres-1; j >= res && allGaps; j--) { if (!jalview.util.Comparison.isGap(s.getSequence().charAt(j))) { res = j + 1; allGaps = false; } } if(!deleteAllowed && allGaps) deleteAllowed = true; } } // drag to right if (res < av.getAlignment().getWidth() && res > lastres) sg.setEndRes(sg.getEndRes() + 1); // drag to left else if (deleteAllowed && res < av.getAlignment().getWidth() && res < lastres) sg.setEndRes(sg.getEndRes() - 1); for (int i = 0; i < sg.getSize(); i++) { SequenceI s = sg.getSequenceAt(i); int k = av.alignment.findIndex(s); // drag to right if (res < av.getAlignment().getWidth() && res > lastres) for (int j = lastres; j < res; j++) insertChar(j, k); // drag to left else if (deleteAllowed && res < av.getAlignment().getWidth() && res < lastres) { for (int j = res; j < lastres; j++) { deleteChar(j, k); startres = res; } } } } } else /////Editing a single sequence/////////// { if (res < av.getAlignment().getWidth() && res > lastres) { // dragging to the right for (int j = lastres; j < res; j++) insertChar(j, startseq); } else if (res < av.getAlignment().getWidth() && res < lastres) { // dragging to the left for (int j = res; j < lastres; j++) { deleteChar(j, startseq); startres = res; } } } } lastres = res; seqCanvas.repaint(); } public void drawChars(int seqstart, int seqend, int start) { seqCanvas.drawPanel(seqCanvas.gg, start,av.getEndRes(),seqstart,seqend,av.getStartRes(),av.getStartSeq(),0); seqCanvas.repaint(); } public void insertChar(int j, int seq) { av.alignment.getSequenceAt(seq).insertCharAt(j, av.getGapCharacter()); seqEditOccurred=seq; } public void deleteChar(int j, int seq) { if ( jalview.util.Comparison.isGap( av.alignment.getSequenceAt(seq).getSequence().charAt(j))) av.alignment.getSequenceAt(seq).deleteCharAt(j); av.alignment.getWidth(); seqCanvas.repaint(); seqEditOccurred=seq; } void updateConservation(int i) { av.updateConservation(); av.updateConsensus(); } ////////////////////////////////////////// /////Everything below this is for defining the boundary of the rubberband ////////////////////////////////////////// int oldSeq = -1; public void doMousePressedDefineMode(MouseEvent evt) { int res = evt.getX()/av.getCharWidth() + av.getStartRes(); int seq = evt.getY()/av.getCharHeight() + av.getStartSeq(); oldSeq = seq; SequenceI sequence = (Sequence) av.getAlignment().getSequenceAt(seq); if(sequence==null || res>sequence.getLength()) return; stretchGroup = av.getSelectionGroup(); if(stretchGroup == null) { stretchGroup = av.alignment.findGroup( sequence ); if(stretchGroup!=null && res>stretchGroup.getStartRes() && resres || stretchGroup.getEndRes()= res) { stretchGroup = allGroups[i]; av.setSelectionGroup(stretchGroup); break; } } if(stretchGroup==null) { // define a new group here SequenceGroup sg = new SequenceGroup(); sg.setStartRes(res); sg.setEndRes(res); sg.addSequence( sequence ); av.setSelectionGroup( sg ); stretchGroup = sg; if(av.getConservationSelected()) SliderPanel.setConservationSlider(ap, av.getGlobalColourScheme(), "Background"); if(av.getAbovePIDThreshold()) SliderPanel.setPIDSliderSource(ap, av.getGlobalColourScheme(), "Background"); } else if( ( evt.getModifiers() & InputEvent .BUTTON3_MASK ) == InputEvent.BUTTON3_MASK ) { APopupMenu popup = new APopupMenu(ap, null); this.add(popup); popup.show(this, evt.getX(), evt.getY()); } if(stretchGroup!=null && stretchGroup.getEndRes()==res) // Edit end res position of selected group changeEndRes = true; else if(stretchGroup!=null && stretchGroup.getStartRes()==res) // Edit end res position of selected group changeStartRes = true; } boolean changeEndSeq = false; boolean changeStartSeq = false; boolean changeEndRes = false; boolean changeStartRes = false; SequenceGroup stretchGroup = null; public void doMouseReleasedDefineMode(MouseEvent evt) { mouseDragging = false; if(stretchGroup==null) return; if(stretchGroup.cs instanceof ClustalxColourScheme) { stretchGroup.cs = new ClustalxColourScheme(stretchGroup.sequences, av.alignment.getWidth()); seqCanvas.repaint(); } else if(stretchGroup.cs instanceof ConservationColourScheme) { ConservationColourScheme ccs = (ConservationColourScheme)stretchGroup.cs; stretchGroup.cs = ccs; SliderPanel.setConservationSlider(ap, stretchGroup.cs, stretchGroup.getName()) ; seqCanvas.repaint(); } else { if(stretchGroup.cs !=null && stretchGroup.cs.canThreshold()) { ResidueColourScheme rcs = (ResidueColourScheme) stretchGroup.cs; SliderPanel.setPIDSliderSource(ap, stretchGroup.cs, stretchGroup.getName()); } } changeEndRes = false; changeStartRes = false; stretchGroup = null; ap.repaint(); } boolean remove = false; public void doMouseDraggedDefineMode(MouseEvent evt) { int res = evt.getX()/av.getCharWidth() + av.getStartRes(); int y = evt.getY()/av.getCharHeight() + av.getStartSeq(); if(stretchGroup==null) return; if(res>av.alignment.getWidth()) res = av.alignment.getWidth()-1; if(stretchGroup.getEndRes()==res) // Edit end res position of selected group changeEndRes = true; else if(stretchGroup.getStartRes()==res) // Edit start res position of selected group changeStartRes = true; if(resav.getEndRes()) res = av.getEndRes(); if(changeEndRes) { if(res>stretchGroup.getStartRes()-1) stretchGroup.setEndRes( res ); } else if(changeStartRes) { if(res oldSeq) dragDirection = 1; else if (y < oldSeq) dragDirection = -1; while (y != oldSeq && oldSeq>0 && y 0) running = ap.scrollUp(true); if (mouseDragging && evt.getY() >= getSize().height && av.alignment.getHeight() > av.getEndSeq()) running = ap.scrollUp(false); if (mouseDragging && evt.getX() < 0) running = ap.scrollRight(true); else if (mouseDragging && evt.getX() >= getSize().width) running = ap.scrollRight(false); } try { Thread.sleep(75); } catch (Exception ex) {} } } } }