From 02f2f19fdecb0b7afa5b61b07c56d46d40948674 Mon Sep 17 00:00:00 2001 From: amwaterhouse Date: Thu, 16 Mar 2006 15:27:23 +0000 Subject: [PATCH] Scrolls when editing --- src/jalview/gui/SeqPanel.java | 545 ++++++++++++++++++++++++----------------- 1 file changed, 327 insertions(+), 218 deletions(-) diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index b9ba9f3..2fe27b3 100755 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -25,8 +25,6 @@ import jalview.schemes.*; import java.awt.*; import java.awt.event.*; -import java.util.*; - import javax.swing.*; @@ -36,7 +34,9 @@ import javax.swing.*; * @author $author$ * @version $Revision$ */ -public class SeqPanel extends JPanel +public class SeqPanel extends JPanel implements MouseListener, + MouseMotionListener, MouseWheelListener + { /** DOCUMENT ME!! */ public SeqCanvas seqCanvas; @@ -50,7 +50,7 @@ public class SeqPanel extends JPanel protected AlignViewport av; // if character is inserted or deleted, we will need to recalculate the conservation - int seqEditOccurred = -1; + boolean seqEditOccurred = false; ScrollThread scrollThread = null; boolean mouseDragging = false; boolean editingSeqs = false; @@ -89,130 +89,12 @@ public class SeqPanel extends JPanel ap = p; - - addMouseMotionListener(new MouseMotionAdapter() - { - public void mouseMoved(MouseEvent evt) - { - doMouseMoved(evt); - if (editingSeqs) - { - // This is because MacOSX creates a mouseMoved - // If control is down - if(!av.isDataset()) - doMouseDragged(evt); - } - } - - public void mouseDragged(MouseEvent evt) - { - if (editingSeqs) - { - if(!av.isDataset()) - doMouseDragged(evt); - } - else - { - if(!av.isDataset()) - doMouseDraggedDefineMode(evt); - } - } - }); - - addMouseWheelListener(new MouseWheelListener() - { - public void mouseWheelMoved(MouseWheelEvent e) - { - - if (mouseWheelPressed) - { - Font font = av.getFont(); - int fontSize = font.getSize(); - if (e.getWheelRotation() > 0 && fontSize < 51) - fontSize++; - else if (fontSize > 1) - fontSize--; - - av.setFont(new Font(font.getName(), font.getStyle(), fontSize)); - ap.fontChanged(); - } - else - { - if (e.getWheelRotation() > 0) - ap.scrollUp(false); - else - ap.scrollUp(true); - } - - } - }); - - - if(!av.isDataset()) - { - addMouseListener(new MouseAdapter() - { - public void mouseReleased(MouseEvent evt) - { - mouseWheelPressed = false; - - if (editingSeqs) - { - doMouseReleased(evt); - } - else - { - doMouseReleasedDefineMode(evt); - } - } - - public void mousePressed(MouseEvent evt) - { - if (javax.swing.SwingUtilities.isMiddleMouseButton(evt)) - { - mouseWheelPressed = true; - return; - } - - if (evt.isShiftDown() || evt.isAltDown() || - evt.isControlDown()) - { - if (evt.isAltDown() || evt.isControlDown()) - { - groupEditing = true; - - } - - editingSeqs = true; - doMousePressed(evt); - } - else - { - doMousePressedDefineMode(evt); - } - } - - public void mouseExited(MouseEvent evt) - { - if (editingSeqs) - { - return; - } - - doMouseExitedDefineMode(evt); - } - - public void mouseEntered(MouseEvent evt) - { - if (editingSeqs) - { - return; - } - - doMouseEnteredDefineMode(evt); - } - }); - } + if(!av.isDataset()) + { + addMouseMotionListener(this); + addMouseListener(this); + addMouseWheelListener(this); + } } int startWrapBlock=-1; @@ -284,35 +166,70 @@ public class SeqPanel extends JPanel return seq; } + void endEditing() + { + startseq = -1; + lastres = -1; + seqEditOccurred = false; + editingSeqs = false; + groupEditing = false; + } /** * DOCUMENT ME! * * @param evt DOCUMENT ME! */ - public void doMouseReleased(MouseEvent evt) + public void mouseReleased(MouseEvent evt) { - if (seqEditOccurred > -1) + mouseDragging = false; + + if (!editingSeqs) + { + doMouseReleasedDefineMode(evt); + return; + } + + if (seqEditOccurred) { - editOccurred(seqEditOccurred); + editOccurred(); } - startseq = -1; - lastres = -1; - seqEditOccurred = -1; - editingSeqs = false; - groupEditing = false; - + endEditing(); ap.repaint(); } + + /** * DOCUMENT ME! * * @param evt DOCUMENT ME! */ - public void doMousePressed(MouseEvent evt) + public void mousePressed(MouseEvent evt) { + if (javax.swing.SwingUtilities.isMiddleMouseButton(evt)) + { + mouseWheelPressed = true; + return; + } + + if (evt.isShiftDown() || evt.isAltDown() || + evt.isControlDown()) + { + if (evt.isAltDown() || evt.isControlDown()) + { + groupEditing = true; + } + editingSeqs = true; + } + else + { + doMousePressedDefineMode(evt); + return; + } + + ap.alignFrame.addHistoryItem(new HistoryItem("Edit Sequence", av.alignment, HistoryItem.EDIT)); @@ -345,8 +262,15 @@ public class SeqPanel extends JPanel * * @param evt DOCUMENT ME! */ - public void doMouseMoved(MouseEvent evt) + public void mouseMoved(MouseEvent evt) { + if (editingSeqs) + { + // This is because MacOSX creates a mouseMoved + // If control is down, other platforms will not. + mouseDragged(evt); + } + int res = findRes(evt); int seq = findSeq(evt); @@ -463,9 +387,14 @@ public class SeqPanel extends JPanel * * @param evt DOCUMENT ME! */ - public void doMouseDragged(MouseEvent evt) + public void mouseDragged(MouseEvent evt) { - // If we're dragging we're editing + if (!editingSeqs) + { + doMouseDraggedDefineMode(evt); + return; + } + int res = findRes(evt); if (res < 0) @@ -484,25 +413,131 @@ public class SeqPanel extends JPanel { dragRight = false; } + else if(av.hasHiddenColumns) + { + //Stop editing if the user has dragged beyond hiddenBoundary + int lastCol = av.getColumnSelection().getHiddenRegionBoundary(lastres); + if( lastCol < res) + { + if(lastres!=lastCol) + { + endEditing(); + return; + } + } + } + + if(!groupEditing && av.hasHiddenRows) + { + if(av.alignment.getSequenceAt(startseq).getHiddenSequences()!=null) + { + groupEditing = true; + } + } + if (res != lastres) { + SequenceI seq; // Group editing if (groupEditing) { SequenceGroup sg = av.getSelectionGroup(); - if (sg == null) + if (av.hasHiddenRows) { - lastres = -1; + //sg might be null as the user may only see 1 sequence + if(sg==null) + { + sg = new SequenceGroup(); + sg.addSequence(av.alignment.getSequenceAt(startseq), false); + } + + SequenceGroup tmp = new SequenceGroup(); + //Do any of the sequences have hidden associates? + for (int s = 0; s < sg.getSize(); s++) + { + seq = sg.getSequenceAt(s); + tmp.addSequence(seq, false); + if (seq.getHiddenSequences()!=null) + { + for(int h=0; h 1) + { + res = lastres+1; + } + + + int lastCol = av.getColumnSelection(). + getHiddenRegionBoundary(res); + + if(lastCol!=res) + { + for (blankColumn = lastCol; + blankColumn > lastres; + blankColumn--) + { + boolean blank = true; + for (int s = 0; s < sg.getSize(); s++) + { + seq = sg.getSequenceAt(s); + + if (seq.getSequence().length() <= blankColumn) + { + continue; + } + + if (!jalview.util.Comparison.isGap( + seq.getSequence().charAt(blankColumn))) + { + blank = false; + continue; + } + } + if (blank) + break; + } + + + if (blankColumn <= lastres) + { + endEditing(); + return; + } + } + else + blankColumn = -1; + + } + + sg.setEndRes(sg.getEndRes() + (res - lastres)); } // drag to left @@ -510,11 +545,10 @@ public class SeqPanel extends JPanel { /// Are we able to delete? // ie are all columns blank? - boolean deleteAllowed = false; for (int s = 0; s < sg.getSize(); s++) { - SequenceI seq = sg.getSequenceAt(s); + seq = sg.getSequenceAt(s); for (int j = res; j < lastres; j++) { @@ -527,37 +561,29 @@ public class SeqPanel extends JPanel seq.getSequence().charAt(j))) { // Not a gap, block edit not valid - res = j + 1; - deleteAllowed = false; - - continue; + endEditing(); + return; } - - deleteAllowed = true; } } - if (!deleteAllowed) + if(res j) + if (seq.getLength()-1 > res) { - deleteChar(res, k); + deleteChar(res, seq); } } } @@ -576,12 +602,13 @@ public class SeqPanel extends JPanel } else /////Editing a single sequence/////////// { + seq = av.alignment.getSequenceAt(startseq); if ((res < av.getAlignment().getWidth()) && (res > lastres)) { // dragging to the right for (int j = lastres; j < res; j++) { - insertChar(j, startseq); + insertChar(j, seq, j); } } else if ((res < av.getAlignment().getWidth()) && @@ -594,7 +621,7 @@ public class SeqPanel extends JPanel av.alignment.getSequenceAt(startseq) .getSequence().charAt(res))) { - deleteChar(res, startseq); + deleteChar(res, seq); } else { @@ -605,11 +632,77 @@ public class SeqPanel extends JPanel } } + mouseDragging = true; + if(scrollThread!=null) + scrollThread.setEvent(evt); + endEdit = res; lastres = res; seqCanvas.repaint(); } + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mouseEntered(MouseEvent e) + { + if(oldSeq < 0) + oldSeq = 0; + + if (scrollThread != null) + { + scrollThread.running = false; + scrollThread = null; + } + } + + /** + * DOCUMENT ME! + * + * @param e DOCUMENT ME! + */ + public void mouseExited(MouseEvent e) + { + if (av.getWrapAlignment()) + { + return; + } + + if (mouseDragging) + { + scrollThread = new ScrollThread(); + } + } + + public void mouseClicked(MouseEvent evt) + {} + + public void mouseWheelMoved(MouseWheelEvent e) + { + if (mouseWheelPressed) + { + Font font = av.getFont(); + int fontSize = font.getSize(); + if (e.getWheelRotation() > 0 && fontSize < 51) + fontSize++; + else if (fontSize > 1) + fontSize--; + + av.setFont(new Font(font.getName(), font.getStyle(), fontSize)); + ap.fontChanged(); + } + else + { + if (e.getWheelRotation() > 0) + ap.scrollUp(false); + else + ap.scrollUp(true); + } + + } + /** * DOCUMENT ME! @@ -617,10 +710,45 @@ public class SeqPanel extends JPanel * @param j DOCUMENT ME! * @param seq DOCUMENT ME! */ - public void insertChar(int j, int seq) + void insertChar(int j, SequenceI seq, int blankColumn) { - av.alignment.getSequenceAt(seq).insertCharAt(j, av.getGapCharacter()); - seqEditOccurred = seq; + if(av.hasHiddenColumns) + { + //Find the next gap before the end of the visible region boundary + int lastCol = av.getColumnSelection().getHiddenRegionBoundary(j); + if(lastCol != j) + { + if (!groupEditing || lastCol <= j) + { + blankColumn = lastCol; + //If lastCol > j, theres a boundary after the gap insertion + if (lastCol > j) + { + for (blankColumn = lastCol; blankColumn > j; blankColumn--) + { + if (jalview.util.Comparison.isGap(seq.getCharAt(blankColumn))) + { + //Theres a space, so break and insert the gap + break; + } + } + + if (blankColumn <= j) + { + endEditing(); + return; + } + } + + } + + // Editing with hidden regions only!! + seq.deleteCharAt(blankColumn); + } + } + + seq.insertCharAt(j, av.getGapCharacter()); + seqEditOccurred = true; } /** @@ -629,12 +757,23 @@ public class SeqPanel extends JPanel * @param j DOCUMENT ME! * @param seq DOCUMENT ME! */ - public void deleteChar(int j, int seq) + public void deleteChar(int j, SequenceI seq) { - av.alignment.getSequenceAt(seq).deleteCharAt(j); - seqEditOccurred = seq; + if (av.hasHiddenColumns) + { + //Find the next gap before the end of the visible region boundary + int lastCol = av.getColumnSelection().getHiddenRegionBoundary(j); + + //If lastCol > j, theres a boundary after the gap insertion + if (lastCol > j) + { + seq.insertCharAt(lastCol, av.getGapCharacter()); + } + } + + seq.deleteCharAt(j); + seqEditOccurred = true; - av.alignment.getWidth(); seqCanvas.repaint(); } @@ -643,7 +782,7 @@ public class SeqPanel extends JPanel * * @param i DOCUMENT ME! */ - void editOccurred(int i) + void editOccurred() { if (endEdit == startEdit) { @@ -781,17 +920,12 @@ public class SeqPanel extends JPanel */ public void doMouseReleasedDefineMode(MouseEvent evt) { - if (mouseDragging) - { - stretchGroup.recalcConservation(); - mouseDragging = false; - } - if (stretchGroup == null) { return; } + if(stretchGroup.cs!=null) { if (stretchGroup.cs instanceof ClustalxColourScheme) @@ -805,6 +939,7 @@ public class SeqPanel extends JPanel { SliderPanel.setConservationSlider(ap, stretchGroup.cs, stretchGroup.getName()); + stretchGroup.recalcConservation(); } else { @@ -831,14 +966,15 @@ public class SeqPanel extends JPanel if(wrappedBlock!=startWrapBlock) return; - if (stretchGroup == null) - { + if (stretchGroup == null) + { return; - } + } + - if (res > av.alignment.getWidth()) + if(y > av.alignment.getHeight()) { - res = av.alignment.getWidth() - 1; + y = av.alignment.getHeight() -1; } if (stretchGroup.getEndRes() == res) @@ -856,10 +992,6 @@ public class SeqPanel extends JPanel { res = av.getStartRes(); } - else if (res > av.getEndRes() && !av.getWrapAlignment()) - { - res = av.getEndRes(); - } if (changeEndRes) { @@ -887,7 +1019,8 @@ public class SeqPanel extends JPanel dragDirection = -1; } - while ((y != oldSeq) && (oldSeq > 0) && (y < av.alignment.getHeight())) + + while ((y != oldSeq) && (oldSeq > -1) && (y < av.alignment.getHeight())) { // This routine ensures we don't skip any sequences, as the // selection is quite slow. @@ -895,6 +1028,9 @@ public class SeqPanel extends JPanel oldSeq += dragDirection; + if(oldSeq<0) + break; + Sequence nextSeq = (Sequence) av.getAlignment().getSequenceAt(oldSeq); if (stretchGroup.sequences.contains(nextSeq)) @@ -912,7 +1048,9 @@ public class SeqPanel extends JPanel } } - oldSeq = y; + if(oldSeq < 0) + oldSeq = -1; + mouseDragging = true; if (scrollThread != null) @@ -923,36 +1061,7 @@ public class SeqPanel extends JPanel seqCanvas.repaint(); } - /** - * DOCUMENT ME! - * - * @param e DOCUMENT ME! - */ - public void doMouseEnteredDefineMode(MouseEvent e) - { - if (scrollThread != null) - { - scrollThread.running = false; - } - } - - /** - * DOCUMENT ME! - * - * @param e DOCUMENT ME! - */ - public void doMouseExitedDefineMode(MouseEvent e) - { - if (av.getWrapAlignment()) - { - return; - } - if (mouseDragging) - { - scrollThread = new ScrollThread(); - } - } // this class allows scrolling off the bottom of the visible alignment class ScrollThread extends Thread -- 1.7.10.2