From 947f3eec987c61ea044731137930ef7d0c89128f Mon Sep 17 00:00:00 2001 From: James Procter Date: Wed, 8 Mar 2023 15:08:57 +0000 Subject: [PATCH] =?utf8?q?JAL-2349=20handle=20matrix=5Fclicked=20on=20mouse=5F?= =?utf8?q?release=20rather=20than=20mouse=5Fpressed=20so=20click-drag=20to=20?= =?utf8?q?resize=20the=20annotation=20row=20doesn=E2=80=99t=20trigger=20a=20?= =?utf8?q?selection=20event=20as=20well.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/jalview/gui/AnnotationPanel.java | 249 +++++++++++++++++++--------------- 1 file changed, 138 insertions(+), 111 deletions(-) diff --git a/src/jalview/gui/AnnotationPanel.java b/src/jalview/gui/AnnotationPanel.java index b112383..c7751e3 100755 --- a/src/jalview/gui/AnnotationPanel.java +++ b/src/jalview/gui/AnnotationPanel.java @@ -601,130 +601,154 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, firstDragX = mouseDragLastX; firstDragY = mouseDragLastY; } - else + } + } + else + { + // no row (or row that can be adjusted) was pressed. Simulate a ruler click + ap.getScalePanel().mousePressed(evt); + } + } + + /** + * checks whether the annotation row under the mouse click evt's handles the + * event + * + * @param evt + * @return false if evt was not handled + */ + boolean matrix_clicked(MouseEvent evt) + { + int[] rowIndex = getRowIndexAndOffset(evt.getY(), + av.getAlignment().getAlignmentAnnotation()); + int yOffset = rowIndex[1]; + + if (rowIndex == null) + { + System.err.println("IMPLEMENTATION ERROR: matrix click out of range."); + } + AlignmentAnnotation clicked = av.getAlignment() + .getAlignmentAnnotation()[rowIndex[0]]; + if (clicked.graph != AlignmentAnnotation.CONTACT_MAP) + { + return false; + } + + // TODO - use existing threshold to select related sections of matrix + GraphLine thr = clicked.getThreshold(); + + int currentX = getColumnForXPos(evt.getX()); + ContactListI forCurrentX = av.getContactList(clicked, currentX); + if (forCurrentX != null) + { + ContactGeometry cXcgeom = new ContactGeometry(forCurrentX, + clicked.graphHeight); + ContactGeometry.contactInterval cXci = cXcgeom.mapFor(yOffset, + yOffset); + /** + * start and end range corresponding to the row range under the mouse at + * column currentX + */ + int fr, to; + fr = Math.min(cXci.cStart, cXci.cEnd); + to = Math.max(cXci.cStart, cXci.cEnd); + + if (evt.isControlDown()) + { + ContactMatrixI matrix = av.getContactMatrix(clicked); + + if (matrix != null) { - GraphLine thr = aa[graphStretch].getThreshold(); - - int currentX = getColumnForXPos(evt.getX()); - ContactListI forCurrentX = av.getContactList(aa[graphStretch], - currentX); - if (forCurrentX != null) + // simplest approach is to select all group containing column + if (matrix.hasGroups()) { - ContactGeometry cXcgeom = new ContactGeometry(forCurrentX, - aa[graphStretch].graphHeight); - ContactGeometry.contactInterval cXci = cXcgeom.mapFor(yOffset, - yOffset); - /** - * start and end range corresponding to the row range under the - * mouse at column currentX - */ - int fr, to; - fr = Math.min(cXci.cStart, cXci.cEnd); - to = Math.max(cXci.cStart, cXci.cEnd); - - if (evt.isControlDown()) + SequenceI rseq = clicked.sequenceRef; + BitSet grp = matrix.getGroupsFor(currentX); + for (int c = fr; c <= to; c++) { - ContactMatrixI matrix = av.getContactMatrix(aa[graphStretch]); - - if (matrix != null) - { - // simplest approach is to select all group containing column - if (matrix.hasGroups()) - { - SequenceI rseq = aa[graphStretch].sequenceRef; - BitSet grp = matrix.getGroupsFor(currentX); - for (int c=fr;c<=to; c++) - { - BitSet additionalGrp = matrix.getGroupsFor(c); - grp.or(additionalGrp); - } - HiddenColumns hc = av.getAlignment().getHiddenColumns(); - for (int p = grp.nextSetBit(0); p >= 0; p = grp - .nextSetBit(p + 1)) - { - int offp = (rseq != null) - ? rseq.findIndex(rseq.getStart() - 1 + p) - : p; - - if (!av.hasHiddenColumns() || hc.isVisible(offp)) - { - av.getColumnSelection().addElement(offp); - } - } - } - // possible alternative for interactive selection - threshold - // gives 'ceiling' for forming a cluster - // when a row+column is selected, farthest common ancestor less - // than thr is used to compute cluster + BitSet additionalGrp = matrix.getGroupsFor(c); + grp.or(additionalGrp); + } + HiddenColumns hc = av.getAlignment().getHiddenColumns(); + for (int p = grp.nextSetBit(0); p >= 0; p = grp + .nextSetBit(p + 1)) + { + int offp = (rseq != null) + ? rseq.findIndex(rseq.getStart() - 1 + p) + : p; + if (!av.hasHiddenColumns() || hc.isVisible(offp)) + { + av.getColumnSelection().addElement(offp); } } + } + // possible alternative for interactive selection - threshold + // gives 'ceiling' for forming a cluster + // when a row+column is selected, farthest common ancestor less + // than thr is used to compute cluster + + } + } + else + { + // select corresponding range in segment under mouse + { + for (int c = fr; c <= to; c++) + { + av.getColumnSelection().addElement(c); + } + av.getColumnSelection().addElement(currentX); + } + // PAE SPECIFIC + // and also select everything lower than the max range adjacent + // (kind of works) + if (PAEContactMatrix.PAEMATRIX.equals(clicked.getCalcId())) + { + int c = fr - 1; + ContactRange cr = forCurrentX.getRangeFor(fr, to); + double cval; + // TODO: could use GraphLine instead of arbitrary picking + // TODO: could report mean/median/variance for partitions + // (contiguous selected vs unselected regions and inter-contig + // regions) + // controls feathering - what other elements in row/column + // should we select + double thresh = cr.getMean() + (cr.getMax() - cr.getMean()) * .15; + while (c > 0) + { + cval = forCurrentX.getContactAt(c); + if (// cr.getMin() <= cval && + cval <= thresh) + { + av.getColumnSelection().addElement(c--); + } else { - // select corresponding range in segment under mouse - { - for (int c = fr; c <= to; c++) - { - av.getColumnSelection().addElement(c); - } - av.getColumnSelection().addElement(currentX); - } - // PAE SPECIFIC - // and also select everything lower than the max range adjacent - // (kind of works) - if (PAEContactMatrix.PAEMATRIX - .equals(aa[graphStretch].getCalcId())) - { - int c = fr - 1; - ContactRange cr = forCurrentX.getRangeFor(fr, to); - double cval; - // TODO: could use GraphLine instead of arbitrary picking - // TODO: could report mean/median/variance for partitions - // (contiguous selected vs unselected regions and inter-contig - // regions) - // controls feathering - what other elements in row/column - // should we select - double thresh = cr.getMean() - + (cr.getMax() - cr.getMean()) * .15; - while (c > 0) - { - cval = forCurrentX.getContactAt(c); - if (// cr.getMin() <= cval && - cval <= thresh) - { - av.getColumnSelection().addElement(c--); - } - else - { - break; - } - } - c = to; - while (c < forCurrentX.getContactHeight()) - { - cval = forCurrentX.getContactAt(c); - if (// cr.getMin() <= cval && - cval <= thresh) - { - av.getColumnSelection().addElement(c++); - } - else - { - break; - } - } - } + break; + } + } + c = to; + while (c < forCurrentX.getContactHeight()) + { + cval = forCurrentX.getContactAt(c); + if (// cr.getMin() <= cval && + cval <= thresh) + { + av.getColumnSelection().addElement(c++); + } + else + { + break; } } } } } - else - { - ap.getScalePanel().mousePressed(evt); - } - } + ap.paintAlignment(false, false); + return true; + } /** * Construct and display a context menu at the right-click position * @@ -797,7 +821,10 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI, ap.adjustAnnotationHeight(); } dragMode = DragMode.Undefined; - ap.getScalePanel().mouseReleased(evt); + if (!matrix_clicked(evt)) + { + ap.getScalePanel().mouseReleased(evt); + } /* * isPopupTrigger is set in mouseReleased on Windows -- 1.7.10.2