X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FSeqPanel.java;h=0878cbb1cbeaaa328887a9a8e5beb96d79bce69e;hb=496ecb05d48de1ca8471658fd32824f808bb8823;hp=d18ecf7db860ecf6ad69942e44ccea5c9c8996af;hpb=14985603cea28569e295ddabb219da8034f1c7b2;p=jalview.git diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index d18ecf7..0878cbb 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -60,6 +60,7 @@ import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.swing.JPanel; @@ -182,7 +183,7 @@ public class SeqPanel extends JPanel implements MouseListener, * @param evt * @return */ - int findRes(MouseEvent evt) + int findColumn(MouseEvent evt) { int res = 0; int x = evt.getX(); @@ -388,38 +389,12 @@ public class SeqPanel extends JPanel implements MouseListener, endEditing(); if (av.getWrapAlignment()) { - ap.scrollToWrappedVisible(seqCanvas.cursorX); + av.getRanges().scrollToWrappedVisible(seqCanvas.cursorX); } else { - while (seqCanvas.cursorY < av.getRanges().getStartSeq()) - { - ap.scrollUp(true); - } - while (seqCanvas.cursorY + 1 > av.getRanges().getEndSeq()) - { - ap.scrollUp(false); - } - if (!av.getWrapAlignment()) - { - HiddenColumns hidden = av.getAlignment().getHiddenColumns(); - while (seqCanvas.cursorX < hidden.adjustForHiddenColumns(av - .getRanges().getStartRes())) - { - if (!ap.scrollRight(false)) - { - break; - } - } - while (seqCanvas.cursorX > hidden.adjustForHiddenColumns(av - .getRanges().getEndRes())) - { - if (!ap.scrollRight(true)) - { - break; - } - } - } + av.getRanges().scrollToVisible(seqCanvas.cursorX, seqCanvas.cursorY, + av); } setStatusMessage(av.getAlignment().getSequenceAt(seqCanvas.cursorY), seqCanvas.cursorX, seqCanvas.cursorY); @@ -589,6 +564,7 @@ public class SeqPanel extends JPanel implements MouseListener, @Override public void mouseReleased(MouseEvent evt) { + boolean didDrag = mouseDragging; // did we come here after a drag mouseDragging = false; mouseWheelPressed = false; @@ -601,7 +577,7 @@ public class SeqPanel extends JPanel implements MouseListener, if (!editingSeqs) { - doMouseReleasedDefineMode(evt); + doMouseReleasedDefineMode(evt, didDrag); return; } @@ -641,7 +617,7 @@ public class SeqPanel extends JPanel implements MouseListener, } int seq = findSeq(evt); - int res = findRes(evt); + int res = findColumn(evt); if (seq < 0 || res < 0) { @@ -695,17 +671,16 @@ public class SeqPanel extends JPanel implements MouseListener, if (av.isFollowHighlight()) { - /* - * if scrollToPosition requires a scroll adjustment, this flag prevents - * another scroll event being propagated back to the originator - * - * @see AlignmentPanel#adjustmentValueChanged - */ - ap.setDontScrollComplement(true); + // don't allow highlight of protein/cDNA to also scroll a complementary + // panel,as this sets up a feedback loop (scrolling panel 1 causes moused + // over residue to change abruptly, causing highlighted residue in panel 2 + // to change, causing a scroll in panel 1 etc) + ap.setToScrollComplementPanel(false); if (ap.scrollToPosition(results, false)) { seqCanvas.revalidate(); } + ap.setToScrollComplementPanel(true); } setStatusMessage(results); seqCanvas.highlightSearchResults(results); @@ -740,25 +715,27 @@ public class SeqPanel extends JPanel implements MouseListener, mouseDragged(evt); } - int res = findRes(evt); + final int column = findColumn(evt); int seq = findSeq(evt); - int pos; - if (res < 0 || seq < 0 || seq >= av.getAlignment().getHeight()) + if (column < 0 || seq < 0 || seq >= av.getAlignment().getHeight()) { return; } SequenceI sequence = av.getAlignment().getSequenceAt(seq); - if (res >= sequence.getLength()) + if (column >= sequence.getLength()) { return; } - pos = setStatusMessage(sequence, res, seq); + /* + * set status bar message, returning residue position in sequence + */ + final int pos = setStatusMessage(sequence, column, seq); if (ssm != null && pos > -1) { - mouseOverSequence(sequence, res, pos); + mouseOverSequence(sequence, column, pos); } tooltipText.setLength(6); // Cuts the buffer back to @@ -768,7 +745,8 @@ public class SeqPanel extends JPanel implements MouseListener, { for (int g = 0; g < groups.length; g++) { - if (groups[g].getStartRes() <= res && groups[g].getEndRes() >= res) + if (groups[g].getStartRes() <= column + && groups[g].getEndRes() >= column) { if (!groups[g].getName().startsWith("JTreeGroup") && !groups[g].getName().startsWith("JGroup")) @@ -784,14 +762,11 @@ public class SeqPanel extends JPanel implements MouseListener, } } - // use aa to see if the mouse pointer is on a - if (av.isShowSequenceFeatures()) + if (av.isShowSequenceFeatures() && pos != -1) { - int rpos; List features = ap.getFeatureRenderer() - .findFeaturesAtRes(sequence.getDatasetSequence(), - rpos = sequence.findPosition(res)); - seqARep.appendFeatures(tooltipText, rpos, features, + .findFeaturesAtRes(sequence.getDatasetSequence(), pos); + seqARep.appendFeatures(tooltipText, pos, features, this.ap.getSeqPanel().seqCanvas.fr.getMinMax()); } if (tooltipText.length() == 6) // @@ -858,17 +833,20 @@ public class SeqPanel extends JPanel implements MouseListener, // avcontroller or viewModel /** - * Set status message in alignment panel + * Sets the status message in alignment panel, showing the sequence number + * (index) and id, residue and residue position for the given sequence and + * column position. Returns the calculated residue position in the sequence, + * or -1 for a gapped column position. * * @param sequence * aligned sequence object - * @param res + * @param column * alignment column * @param seq * index of sequence in alignment - * @return position of res in sequence + * @return position of column in sequence or -1 if at a gap */ - int setStatusMessage(SequenceI sequence, int res, int seq) + int setStatusMessage(SequenceI sequence, final int column, int seq) { StringBuilder text = new StringBuilder(32); @@ -883,7 +861,7 @@ public class SeqPanel extends JPanel implements MouseListener, /* * Try to translate the display character to residue name (null for gap). */ - final String displayChar = String.valueOf(sequence.getCharAt(res)); + final String displayChar = String.valueOf(sequence.getCharAt(column)); if (av.getAlignment().isNucleotide()) { residue = ResidueProperties.nucleotideName.get(displayChar); @@ -906,7 +884,7 @@ public class SeqPanel extends JPanel implements MouseListener, int pos = -1; if (residue != null) { - pos = sequence.findPosition(res); + pos = sequence.findPosition(column); text.append(" (").append(Integer.toString(pos)).append(")"); } ap.alignFrame.statusBar.setText(text.toString()); @@ -950,30 +928,36 @@ public class SeqPanel extends JPanel implements MouseListener, } /** - * DOCUMENT ME! - * - * @param evt - * DOCUMENT ME! + * {@inheritDoc} */ @Override public void mouseDragged(MouseEvent evt) { if (mouseWheelPressed) { + boolean inSplitFrame = ap.av.getCodingComplement() != null; + boolean copyChanges = inSplitFrame && av.isProteinFontAsCdna(); + int oldWidth = av.getCharWidth(); // Which is bigger, left-right or up-down? if (Math.abs(evt.getY() - lastMousePress.getY()) > Math.abs(evt .getX() - lastMousePress.getX())) { + /* + * on drag up or down, decrement or increment font size + */ int fontSize = av.font.getSize(); + boolean fontChanged = false; if (evt.getY() < lastMousePress.getY()) { + fontChanged = true; fontSize--; } else if (evt.getY() > lastMousePress.getY()) { + fontChanged = true; fontSize++; } @@ -982,24 +966,56 @@ public class SeqPanel extends JPanel implements MouseListener, fontSize = 1; } - av.setFont( - new Font(av.font.getName(), av.font.getStyle(), fontSize), - true); - av.setCharWidth(oldWidth); - ap.fontChanged(); + if (fontChanged) + { + Font newFont = new Font(av.font.getName(), av.font.getStyle(), + fontSize); + av.setFont(newFont, true); + av.setCharWidth(oldWidth); + ap.fontChanged(); + if (copyChanges) + { + ap.av.getCodingComplement().setFont(newFont, true); + SplitFrame splitFrame = (SplitFrame) ap.alignFrame + .getSplitViewContainer(); + splitFrame.adjustLayout(); + splitFrame.repaint(); + } + } } else { + /* + * on drag left or right, decrement or increment character width + */ + int newWidth = 0; if (evt.getX() < lastMousePress.getX() && av.getCharWidth() > 1) { - av.setCharWidth(av.getCharWidth() - 1); + newWidth = av.getCharWidth() - 1; + av.setCharWidth(newWidth); } else if (evt.getX() > lastMousePress.getX()) { - av.setCharWidth(av.getCharWidth() + 1); + newWidth = av.getCharWidth() + 1; + av.setCharWidth(newWidth); + } + if (newWidth > 0) + { + ap.paintAlignment(false); + if (copyChanges) + { + /* + * need to ensure newWidth is set on cdna, regardless of which + * panel the mouse drag happened in; protein will compute its + * character width as 1:1 or 3:1 + */ + av.getCodingComplement().setCharWidth(newWidth); + SplitFrame splitFrame = (SplitFrame) ap.alignFrame + .getSplitViewContainer(); + splitFrame.adjustLayout(); + splitFrame.repaint(); + } } - - ap.paintAlignment(false); } FontMetrics fm = getFontMetrics(av.getFont()); @@ -1016,7 +1032,7 @@ public class SeqPanel extends JPanel implements MouseListener, return; } - int res = findRes(evt); + int res = findColumn(evt); if (res < 0) { @@ -1492,6 +1508,11 @@ public class SeqPanel extends JPanel implements MouseListener, } } + /** + * Handler for double-click on a position with one or more sequence features. + * Opens the Amend Features dialog to allow feature details to be amended, or + * the feature deleted. + */ @Override public void mouseClicked(MouseEvent evt) { @@ -1508,22 +1529,25 @@ public class SeqPanel extends JPanel implements MouseListener, List features = seqCanvas.getFeatureRenderer() .findFeaturesAtRes(sequence.getDatasetSequence(), - sequence.findPosition(findRes(evt))); + sequence.findPosition(findColumn(evt))); - if (features != null && features.size() > 0) + if (!features.isEmpty()) { + /* + * highlight the first feature at the position on the alignment + */ SearchResultsI highlight = new SearchResults(); highlight.addResult(sequence, features.get(0).getBegin(), features .get(0).getEnd()); seqCanvas.highlightSearchResults(highlight); - } - if (features != null && features.size() > 0) - { - seqCanvas.getFeatureRenderer().amendFeatures( - new SequenceI[] { sequence }, - features.toArray(new SequenceFeature[features.size()]), - false, ap); + /* + * open the Amend Features dialog; clear highlighting afterwards, + * whether changes were made or not + */ + List seqs = Collections.singletonList(sequence); + seqCanvas.getFeatureRenderer().amendFeatures(seqs, features, false, + ap); seqCanvas.highlightSearchResults(null); } } @@ -1537,23 +1561,23 @@ public class SeqPanel extends JPanel implements MouseListener, { if (e.isShiftDown()) { - ap.scrollRight(true); + av.getRanges().scrollRight(true); } else { - ap.scrollUp(false); + av.getRanges().scrollUp(false); } } else { if (e.isShiftDown()) { - ap.scrollRight(false); + av.getRanges().scrollRight(false); } else { - ap.scrollUp(true); + av.getRanges().scrollUp(true); } } // TODO Update tooltip for new position. @@ -1567,7 +1591,7 @@ public class SeqPanel extends JPanel implements MouseListener, */ public void doMousePressedDefineMode(MouseEvent evt) { - final int res = findRes(evt); + final int res = findColumn(evt); final int seq = findSeq(evt); oldSeq = seq; needOverviewUpdate = false; @@ -1626,7 +1650,7 @@ public class SeqPanel extends JPanel implements MouseListener, if (av.cursorMode) { - seqCanvas.cursorX = findRes(evt); + seqCanvas.cursorX = findColumn(evt); seqCanvas.cursorY = findSeq(evt); seqCanvas.repaint(); return; @@ -1678,17 +1702,17 @@ public class SeqPanel extends JPanel implements MouseListener, * * @param evt * @param res - * @param sequence + * @param sequences */ void showPopupMenu(MouseEvent evt) { - final int res = findRes(evt); + final int res = findColumn(evt); final int seq = findSeq(evt); SequenceI sequence = av.getAlignment().getSequenceAt(seq); List allFeatures = ap.getFeatureRenderer() .findFeaturesAtRes(sequence.getDatasetSequence(), sequence.findPosition(res)); - List links = new ArrayList(); + List links = new ArrayList<>(); for (SequenceFeature sf : allFeatures) { if (sf.links != null) @@ -1705,12 +1729,15 @@ public class SeqPanel extends JPanel implements MouseListener, } /** - * DOCUMENT ME! + * Update the display after mouse up on a selection or group * * @param evt - * DOCUMENT ME! + * mouse released event details + * @param afterDrag + * true if this event is happening after a mouse drag (rather than a + * mouse down) */ - public void doMouseReleasedDefineMode(MouseEvent evt) + public void doMouseReleasedDefineMode(MouseEvent evt, boolean afterDrag) { if (stretchGroup == null) { @@ -1719,7 +1746,8 @@ public class SeqPanel extends JPanel implements MouseListener, // always do this - annotation has own state // but defer colourscheme update until hidden sequences are passed in boolean vischange = stretchGroup.recalcConservation(true); - needOverviewUpdate |= vischange && av.isSelectionDefinedGroup(); + needOverviewUpdate |= vischange && av.isSelectionDefinedGroup() + && afterDrag; if (stretchGroup.cs != null) { stretchGroup.cs.alignmentChanged(stretchGroup, @@ -1753,7 +1781,7 @@ public class SeqPanel extends JPanel implements MouseListener, */ public void doMouseDraggedDefineMode(MouseEvent evt) { - int res = findRes(evt); + int res = findColumn(evt); int y = findSeq(evt); if (wrappedBlock != startWrapBlock) @@ -1921,23 +1949,23 @@ public class SeqPanel extends JPanel implements MouseListener, if (mouseDragging && (evt.getY() < 0) && (av.getRanges().getStartSeq() > 0)) { - running = ap.scrollUp(true); + running = av.getRanges().scrollUp(true); } if (mouseDragging && (evt.getY() >= getHeight()) && (av.getAlignment().getHeight() > av.getRanges() .getEndSeq())) { - running = ap.scrollUp(false); + running = av.getRanges().scrollUp(false); } if (mouseDragging && (evt.getX() < 0)) { - running = ap.scrollRight(false); + running = av.getRanges().scrollRight(false); } else if (mouseDragging && (evt.getX() >= getWidth())) { - running = ap.scrollRight(true); + running = av.getRanges().scrollRight(true); } } @@ -1964,7 +1992,20 @@ public class SeqPanel extends JPanel implements MouseListener, // shared between viewports. boolean iSentTheSelection = (av == source || (source instanceof AlignViewport && ((AlignmentViewport) source) .getSequenceSetId().equals(av.getSequenceSetId()))); - if (iSentTheSelection || !av.followSelection) + + if (iSentTheSelection) + { + // respond to our own event by updating dependent dialogs + if (ap.getCalculationDialog() != null) + { + ap.getCalculationDialog().validateCalcTypes(); + } + + return; + } + + // process further ? + if (!av.followSelection) { return; } @@ -2044,7 +2085,8 @@ public class SeqPanel extends JPanel implements MouseListener, } else { - av.getColumnSelection().setElementsFrom(colsel); + av.getColumnSelection().setElementsFrom(colsel, + av.getAlignment().getHiddenColumns()); } } av.isColSelChanged(true); @@ -2064,6 +2106,13 @@ public class SeqPanel extends JPanel implements MouseListener, PaintRefresher.Refresh(this, av.getSequenceSetId()); // ap.paintAlignment(false); } + + // lastly, update dependent dialogs + if (ap.getCalculationDialog() != null) + { + ap.getCalculationDialog().validateCalcTypes(); + } + } /** @@ -2108,6 +2157,12 @@ public class SeqPanel extends JPanel implements MouseListener, av.setColumnSelection(cs); av.getAlignment().setHiddenColumns(hs); + // lastly, update any dependent dialogs + if (ap.getCalculationDialog() != null) + { + ap.getCalculationDialog().validateCalcTypes(); + } + PaintRefresher.Refresh(this, av.getSequenceSetId()); return true;