X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fappletgui%2FAlignmentPanel.java;h=458ed54f5dfd4ce0ae08811b2a667d98ca2629e3;hb=36e7c887ef91f49f6065dea063180f7de146b3e1;hp=5a2c5ef4d5d2bf9101b6c380c57918e49aef53d9;hpb=ed2283c5f54da377a2a2fdbdb7aec75ed7041714;p=jalview.git diff --git a/src/jalview/appletgui/AlignmentPanel.java b/src/jalview/appletgui/AlignmentPanel.java index 5a2c5ef..458ed54 100644 --- a/src/jalview/appletgui/AlignmentPanel.java +++ b/src/jalview/appletgui/AlignmentPanel.java @@ -20,6 +20,16 @@ */ package jalview.appletgui; +import jalview.analysis.AnnotationSorter; +import jalview.api.AlignViewportI; +import jalview.api.AlignmentViewPanel; +import jalview.bin.JalviewLite; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SearchResultsI; +import jalview.datamodel.SequenceI; +import jalview.structure.StructureSelectionManager; +import jalview.viewmodel.ViewportRanges; + import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; @@ -34,15 +44,6 @@ import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.util.List; -import jalview.analysis.AnnotationSorter; -import jalview.api.AlignViewportI; -import jalview.api.AlignmentViewPanel; -import jalview.bin.JalviewLite; -import jalview.datamodel.AlignmentI; -import jalview.datamodel.SearchResults; -import jalview.datamodel.SequenceI; -import jalview.structure.StructureSelectionManager; - public class AlignmentPanel extends Panel implements AdjustmentListener, AlignmentViewPanel { @@ -65,13 +66,17 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, AnnotationLabels alabels; + ViewportRanges vpRanges; + // this value is set false when selection area being dragged boolean fastPaint = true; - public void finalize() + @Override + public void finalize() throws Throwable { alignFrame = null; av = null; + vpRanges = null; seqPanel = null; seqPanelHolder = null; sequenceHolderPanel = null; @@ -80,6 +85,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, annotationPanel = null; annotationPanelHolder = null; annotationSpaceFillerHolder = null; + super.finalize(); } public AlignmentPanel(AlignFrame af, final AlignViewport av) @@ -94,6 +100,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, alignFrame = af; this.av = av; + vpRanges = av.getRanges(); seqPanel = new SeqPanel(av, this); idPanel = new IdPanel(av, this); scalePanel = new ScalePanel(av, this); @@ -121,9 +128,10 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, addComponentListener(new ComponentAdapter() { + @Override public void componentResized(ComponentEvent evt) { - setScrollValues(av.getStartRes(), av.getStartSeq()); + setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq()); if (getSize().height > 0 && annotationPanelHolder.getSize().height > 0) { @@ -146,6 +154,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, final AlignmentPanel ap = this; av.addPropertyChangeListener(new java.beans.PropertyChangeListener() { + @Override public void propertyChange(java.beans.PropertyChangeEvent evt) { if (evt.getPropertyName().equals("alignment")) @@ -162,15 +171,18 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { return av; } + public SequenceRenderer getSequenceRenderer() { return seqPanel.seqCanvas.sr; } + @Override public jalview.api.FeatureRenderer getFeatureRenderer() { return seqPanel.seqCanvas.fr; } + @Override public jalview.api.FeatureRenderer cloneFeatureRenderer() { @@ -178,6 +190,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, nfr.transferSettings(seqPanel.seqCanvas.fr); return nfr; } + public void alignmentChanged() { av.alignmentChanged(this); @@ -285,7 +298,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, * Highlight the given results on the alignment. * */ - public void highlightSearchResults(SearchResults results) + public void highlightSearchResults(SearchResultsI results) { scrollToPosition(results); seqPanel.seqCanvas.highlightSearchResults(results); @@ -298,7 +311,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, * @param results * @return false if results were not found */ - public boolean scrollToPosition(SearchResults results) + public boolean scrollToPosition(SearchResultsI results) { return scrollToPosition(results, true); } @@ -312,10 +325,10 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, * - when set, the overview will be recalculated (takes longer) * @return false if results were not found */ - public boolean scrollToPosition(SearchResults results, + public boolean scrollToPosition(SearchResultsI results, boolean redrawOverview) { - return scrollToPosition(results, redrawOverview, false); + return scrollToPosition(results, 0, redrawOverview, false); } /** @@ -327,7 +340,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, * - when set, the overview will be recalculated (takes longer) * @return false if results were not found */ - public boolean scrollToPosition(SearchResults results, + public boolean scrollToPosition(SearchResultsI results, + int verticalOffset, boolean redrawOverview, boolean centre) { // do we need to scroll the panel? @@ -339,6 +353,10 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { return false; } + /* + * allow for offset of target sequence (actually scroll to one above it) + */ + SequenceI seq = alignment.getSequenceAt(seqIndex); int[] r = results.getResults(seq, 0, alignment.getWidth()); if (r == null) @@ -370,7 +388,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, */ if (centre) { - int offset = (av.getEndRes() - av.getStartRes() + 1) / 2 - 1; + int offset = (vpRanges.getEndRes() - vpRanges.getStartRes() + 1) / 2 - 1; start = Math.max(start - offset, 0); end = Math.min(end + offset, seq.getEnd() - 1); } @@ -383,6 +401,11 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { return false; } + + /* + * allow for offset of target sequence (actually scroll to one above it) + */ + seqIndex = Math.max(0, seqIndex - verticalOffset); return scrollTo(start, end, seqIndex, false, redrawOverview); } return true; @@ -396,11 +419,12 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, int start = -1; if (av.hasHiddenColumns()) { - start = av.getColumnSelection().findColumnPosition(ostart); - end = av.getColumnSelection().findColumnPosition(end); + AlignmentI al = av.getAlignment(); + start = al.getHiddenColumns().findColumnPosition(ostart); + end = al.getHiddenColumns().findColumnPosition(end); if (start == end) { - if (!scrollToNearest && !av.getColumnSelection().isVisible(ostart)) + if (!scrollToNearest && !al.getHiddenColumns().isVisible(ostart)) { // don't scroll - position isn't visible return false; @@ -411,6 +435,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { start = ostart; } + if (!av.getWrapAlignment()) { /* @@ -449,37 +474,38 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, // setScrollValues(start, seqIndex); // } // logic copied from jalview.gui.AlignmentPanel: - if ((startv = av.getStartRes()) >= start) - { - /* - * Scroll left to make start of search results visible - */ - setScrollValues(start - 1, seqIndex); - } - else if ((endv = av.getEndRes()) <= end) - { - /* - * Scroll right to make end of search results visible - */ - setScrollValues(startv + 1 + end - endv, seqIndex); - } - else if ((starts = av.getStartSeq()) > seqIndex) - { - /* - * Scroll up to make start of search results visible - */ - setScrollValues(av.getStartRes(), seqIndex); - } - else if ((ends = av.getEndSeq()) <= seqIndex) - { - /* - * Scroll down to make end of search results visible - */ - setScrollValues(av.getStartRes(), starts + seqIndex - ends + 1); - } + if ((startv = vpRanges.getStartRes()) >= start) + { + /* + * Scroll left to make start of search results visible + */ + setScrollValues(start - 1, seqIndex); + } + else if ((endv = vpRanges.getEndRes()) <= end) + { + /* + * Scroll right to make end of search results visible + */ + setScrollValues(startv + 1 + end - endv, seqIndex); + } + else if ((starts = vpRanges.getStartSeq()) > seqIndex) + { /* - * Else results are already visible - no need to scroll + * Scroll up to make start of search results visible */ + setScrollValues(vpRanges.getStartRes(), seqIndex); + } + else if ((ends = vpRanges.getEndSeq()) <= seqIndex) + { + /* + * Scroll down to make end of search results visible + */ + setScrollValues(vpRanges.getStartRes(), starts + seqIndex - ends + + 1); + } + /* + * Else results are already visible - no need to scroll + */ } else { @@ -497,10 +523,11 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { int cwidth = seqPanel.seqCanvas .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width); - if (res <= av.getStartRes() || res >= (av.getStartRes() + cwidth)) + if (res <= vpRanges.getStartRes() + || res >= (vpRanges.getStartRes() + cwidth)) { vscroll.setValue(res / cwidth); - av.startRes = vscroll.getValue() * cwidth; + vpRanges.setStartRes(vscroll.getValue() * cwidth); } } @@ -534,6 +561,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, * automatically adjust annotation panel height for new annotation whilst * ensuring the alignment is still visible. */ + @Override public void adjustAnnotationHeight() { // TODO: display vertical annotation scrollbar if necessary @@ -552,78 +580,68 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, } /** - * calculate the annotation dimensions and refresh slider values accordingly. - * need to do repaints/notifys afterwards. + * Calculate the annotation dimensions and refresh slider values accordingly. + * Need to do repaints/notifys afterwards. */ protected void validateAnnotationDimensions(boolean adjustPanelHeight) { - boolean modified = false; - int height = av.calcPanelHeight(); - int minsize = 0; - if (hscroll.isVisible()) - { - height += (minsize = hscroll.getPreferredSize().height); - } - if (apvscroll.isVisible()) - { - minsize += apvscroll.getPreferredSize().height; - } - int mheight = height; - Dimension d = sequenceHolderPanel.getSize(), e = idPanel.getSize(); - int seqandannot = d.height - scalePanelHolder.getSize().height; + int rowHeight = av.getCharHeight(); + int alignmentHeight = rowHeight * av.getAlignment().getHeight(); + int annotationHeight = av.calcPanelHeight(); + + int mheight = annotationHeight; + Dimension d = sequenceHolderPanel.getSize(); + + int availableHeight = d.height - scalePanelHolder.getHeight(); if (adjustPanelHeight) { - // NOTE: this logic is different in the application. Need a better - // algorithm to define behaviour - // sets initial preferred height - // try and set height according to alignment - float sscaling = (float) ((av.getCharHeight() * av.getAlignment() - .getHeight()) / (1.0 * mheight)); - if (sscaling > 0.5) - { - // if the alignment is too big then - // default is 0.5 split - height = seqandannot / 2; - } - else + /* + * If not enough vertical space, maximize annotation height while keeping + * at least two rows of alignment visible + */ + if (annotationHeight + alignmentHeight > availableHeight) { - // otherwise just set the panel so that one row of sequence is visible - height = -av.getCharHeight() * 1 - + (int) (seqandannot * (1 - sscaling)); + annotationHeight = Math.min(annotationHeight, availableHeight - 2 + * rowHeight); } } else { // maintain same window layout whilst updating sliders - height = annotationPanelHolder.getSize().height; + annotationHeight = annotationPanelHolder.getSize().height; } - if (seqandannot - height < 5) + if (availableHeight - annotationHeight < 5) { - height = seqandannot; + annotationHeight = availableHeight; } - annotationPanel.setSize(new Dimension(d.width, height)); - alabels.setSize(new Dimension(e.width, height)); - annotationSpaceFillerHolder.setSize(new Dimension(e.width, height)); - annotationPanelHolder.setSize(new Dimension(d.width, height)); + + annotationPanel.setSize(new Dimension(d.width, annotationHeight)); + annotationPanelHolder.setSize(new Dimension(d.width, annotationHeight)); // seqPanelHolder.setSize(d.width, seqandannot - height); seqPanel.seqCanvas .setSize(d.width, seqPanel.seqCanvas.getSize().height); + + Dimension e = idPanel.getSize(); + alabels.setSize(new Dimension(e.width, annotationHeight)); + annotationSpaceFillerHolder.setSize(new Dimension(e.width, + annotationHeight)); + int s = apvscroll.getValue(); - if (s > mheight - height) + if (s > mheight - annotationHeight) { s = 0; } - apvscroll.setValues(s, height, 0, mheight); + apvscroll.setValues(s, annotationHeight, 0, mheight); annotationPanel.setScrollOffset(apvscroll.getValue(), false); alabels.setScrollOffset(apvscroll.getValue(), false); } public void setWrapAlignment(boolean wrap) { - av.startSeq = 0; - av.startRes = 0; + vpRanges.setStartSeq(0); + vpRanges.setStartRes(0); scalePanelHolder.setVisible(!wrap); hscroll.setVisible(!wrap); @@ -708,13 +726,14 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, if (av.hasHiddenColumns()) { - width = av.getColumnSelection().findColumnPosition(width); + width = av.getAlignment().getHiddenColumns() + .findColumnPosition(width); } if (x < 0) { x = 0; } - ; + hextent = seqPanel.seqCanvas.getSize().width / av.getCharWidth(); vextent = seqPanel.seqCanvas.getSize().height / av.getCharHeight(); @@ -731,8 +750,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, if ((hextent + x) > width) { - System.err.println("hextent was " + hextent + " and x was " + x); - + // System.err.println("hextent was " + hextent + " and x was " + x); + // x = width - hextent; } @@ -752,17 +771,10 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, x = 0; } - av.setStartSeq(y); - - int endSeq = y + vextent; - if (endSeq > av.getAlignment().getHeight()) - { - endSeq = av.getAlignment().getHeight(); - } - - av.setEndSeq(endSeq); - av.setStartRes(x); - av.setEndRes((x + (seqPanel.seqCanvas.getSize().width / av + vpRanges.setStartSeq(y); + vpRanges.setEndSeq(y + vextent); + vpRanges.setStartRes(x); + vpRanges.setEndRes((x + (seqPanel.seqCanvas.getSize().width / av .getCharWidth())) - 1); hscroll.setValues(x, hextent, 0, width); @@ -776,10 +788,11 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, } + @Override public void adjustmentValueChanged(AdjustmentEvent evt) { - int oldX = av.getStartRes(); - int oldY = av.getStartSeq(); + int oldX = vpRanges.getStartRes(); + int oldY = vpRanges.getStartSeq(); if (evt == null || evt.getSource() == apvscroll) { @@ -793,8 +806,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, if (evt == null || evt.getSource() == hscroll) { int x = hscroll.getValue(); - av.setStartRes(x); - av.setEndRes(x + seqPanel.seqCanvas.getSize().width + vpRanges.setStartRes(x); + vpRanges.setEndRes(x + seqPanel.seqCanvas.getSize().width / av.getCharWidth() - 1); } @@ -805,14 +818,14 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { int rowSize = seqPanel.seqCanvas .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width); - av.setStartRes(vscroll.getValue() * rowSize); - av.setEndRes((vscroll.getValue() + 1) * rowSize); + vpRanges.setStartRes(vscroll.getValue() * rowSize); + vpRanges.setEndRes((vscroll.getValue() + 1) * rowSize); } else { - av.setStartSeq(offy); - av.setEndSeq(offy + seqPanel.seqCanvas.getSize().height - / av.getCharHeight()); + vpRanges.setStartSeq(offy); + vpRanges.setEndSeq(offy + seqPanel.seqCanvas.getSize().height + / av.getCharHeight() - 1); } } @@ -821,8 +834,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, overviewPanel.setBoxPosition(); } - int scrollX = av.startRes - oldX; - int scrollY = av.startSeq - oldY; + int scrollX = vpRanges.getStartRes() - oldX; + int scrollY = vpRanges.getStartSeq() - oldY; if (av.getWrapAlignment() || !fastPaint || av.MAC) { @@ -832,13 +845,13 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { // Make sure we're not trying to draw a panel // larger than the visible window - if (scrollX > av.endRes - av.startRes) + if (scrollX > vpRanges.getEndRes() - vpRanges.getStartRes()) { - scrollX = av.endRes - av.startRes; + scrollX = vpRanges.getEndRes() - vpRanges.getStartRes(); } - else if (scrollX < av.startRes - av.endRes) + else if (scrollX < vpRanges.getStartRes() - vpRanges.getEndRes()) { - scrollX = av.startRes - av.endRes; + scrollX = vpRanges.getStartRes() - vpRanges.getEndRes(); } idPanel.idCanvas.fastPaint(scrollY); @@ -847,7 +860,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, scalePanel.repaint(); if (av.isShowAnnotation()) { - annotationPanel.fastPaint(av.getStartRes() - oldX); + annotationPanel.fastPaint(vpRanges.getStartRes() - oldX); } } sendViewPosition(); @@ -902,14 +915,14 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, * @param seqOffset * the number of visible sequences to show above the mapped region */ - protected void scrollToCentre(SearchResults sr, int seqOffset) + protected void scrollToCentre(SearchResultsI sr, int seqOffset) { /* * To avoid jumpy vertical scrolling (if some sequences are gapped or not * mapped), we can make the scroll-to location a sequence above the one * actually mapped. */ - SequenceI mappedTo = sr.getResultSequence(0); + SequenceI mappedTo = sr.getResults().get(0).getSequence(); List seqs = av.getAlignment().getSequences(); /* @@ -931,28 +944,28 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, { return; // failsafe, shouldn't happen } - sequenceIndex = Math.max(0, sequenceIndex - seqOffset); - sr.getResults().get(0) - .setSequence(av.getAlignment().getSequenceAt(sequenceIndex)); /* * Scroll to position but centring the target residue. Also set a state flag * to prevent adjustmentValueChanged performing this recursively. */ setFollowingComplementScroll(true); - scrollToPosition(sr, true, true); + // this should be scrollToPosition(sr,verticalOffset, + scrollToPosition(sr, seqOffset, true, true); } private void sendViewPosition() { StructureSelectionManager.getStructureSelectionManager(av.applet) - .sendViewPosition(this, av.startRes, av.endRes, av.startSeq, - av.endSeq); + .sendViewPosition(this, vpRanges.getStartRes(), + vpRanges.getEndRes(), vpRanges.getStartSeq(), + vpRanges.getEndSeq()); } /** * Repaint the alignment and annotations, and, optionally, any overview window */ + @Override public void paintAlignment(boolean updateOverview) { final AnnotationSorter sorter = new AnnotationSorter(getAlignment(), @@ -963,6 +976,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, if (updateOverview) { + // TODO: determine if this paintAlignment changed structure colours jalview.structure.StructureSelectionManager .getStructureSelectionManager(av.applet) .sequenceColoursChanged(this); @@ -974,16 +988,22 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, } } + @Override public void update(Graphics g) { paint(g); } + @Override public void paint(Graphics g) { invalidate(); Dimension d = idPanel.idCanvas.getSize(); - idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height); + final int canvasHeight = seqPanel.seqCanvas.getSize().height; + if (canvasHeight != d.height) + { + idPanel.idCanvas.setSize(d.width, canvasHeight); + } if (av.getWrapAlignment()) { @@ -991,7 +1011,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, if (av.hasHiddenColumns()) { - maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1; + maxwidth = av.getAlignment().getHiddenColumns() + .findColumnPosition(maxwidth) - 1; } int canvasWidth = seqPanel.seqCanvas @@ -1007,7 +1028,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener, } else { - setScrollValues(av.getStartRes(), av.getStartSeq()); + setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq()); } seqPanel.seqCanvas.repaint();