c65238ee792df4c552cb0716c4717a7b2ffbc3cf max Wed Jul 27 05:27:24 2022 -0700 fixing right-click problem onto highlights when the user clicks onto the left half of a bp, refs #29783 diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index 66ab378..c74aed6 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -375,36 +375,45 @@ // We ignore clicks in the gray tab and track title column // (we really should suppress all drag activity there, // but I don't know how to do that with imgAreaSelect). var leftX = hgTracks.revCmplDisp ? imgOfs.left - slop : imgOfs.left + hgTracks.insideX - slop; var rightX = hgTracks.revCmplDisp ? imgOfs.left + imgWidth - hgTracks.insideX + slop : imgOfs.left + imgWidth + slop; return ( (selection.event.pageX >= leftX) && (selection.event.pageX < rightX) && (selection.event.pageY >= (imgOfs.top - slop)) && (selection.event.pageY < (imgOfs.top + imgHeight + slop))); }, - pixelsToBases: function (img, selStart, selEnd, winStart, winEnd) + pixelsToBases: function (img, selStart, selEnd, winStart, winEnd, addHalfBp) { // Convert image coordinates to chromosome coordinates var imgWidth = jQuery(img).width() - hgTracks.insideX; var width = hgTracks.winEnd - hgTracks.winStart; var mult = width / imgWidth; // mult is bp/pixel multiplier - var halfBpWidth = (imgWidth / width) / 2; // how many pixels does one bp take up; + + // where does a bp position start on the screen? + // For things like drag-select, if the user ends just before the nucleotide itself, do not count + // the nucleotide itself as selected. But for things like clicks onto + // a selection, if the user right-clicks just before the middle of the + // nucleotide, we certainly want to use this position. + var halfBpWidth = 0; + if (addHalfBp) + halfBpWidth = (imgWidth / width) / 2; // how many pixels does one bp take up; + var startDelta; // startDelta is how many bp's to the right/left var x1; // The magic number three appear at another place in the code // as LEFTADD. It was originally annotated as "borders or cgi item calc // ?" by Larry. It has to be used when going any time when converting // between pixels and coordinates. selStart -= 3; selEnd -= 3; if (hgTracks.revCmplDisp) { x1 = Math.min(imgWidth, selStart); startDelta = Math.floor(mult * (imgWidth - x1 - halfBpWidth)); } else { x1 = Math.max(hgTracks.insideX, selStart); @@ -459,37 +468,37 @@ // while they continue to overlap, extend e = Math.min(chromEnd, w.winEnd); virtEnd = w.virtStart + (e - w.winStart); } else { // when they do not overlap anymore, stop break; } } } return {chromStart : virtStart, chromEnd : virtEnd}; }, selectionPixelsToBases: function (img, selection) { // Convert selection x1/x2 coordinates to chromStart/chromEnd. return genomePos.pixelsToBases(img, selection.x1, selection.x2, - hgTracks.winStart, hgTracks.winEnd); + hgTracks.winStart, hgTracks.winEnd, true); }, update: function (img, selection, singleClick) { var pos = genomePos.pixelsToBases(img, selection.x1, selection.x2, - hgTracks.winStart, hgTracks.winEnd); + hgTracks.winStart, hgTracks.winEnd, true); // singleClick is true when the mouse hasn't moved (or has only moved a small amount). if (singleClick) { var center = (pos.chromStart + pos.chromEnd)/2; pos.chromStart = Math.floor(center - hgTracks.newWinWidth/2); pos.chromEnd = pos.chromStart + hgTracks.newWinWidth; // clip if (pos.chromStart < hgTracks.chromStart) pos.chromStart = hgTracks.chromStart; // usually 1 if (pos.chromEnd > hgTracks.chromEnd) pos.chromEnd = hgTracks.chromEnd; // usually virt chrom size // save current position so that that it may be restored after highlight or cancel. genomePos.original = genomePos.getOriginalPos(); genomePos.originalSize = $('#size').text().replace(/,/g, ""); // strip out any commas @@ -3060,31 +3069,31 @@ rightClick.hit(menuItemClicked, menuObject, "viewImg"); return true; } }; menu.push(o); return menu; }, { beforeShow: function(e) { // console.log(mapItems[rightClick.selectedMenuItem]); rightClick.selectedMenuItem = rightClick.findMapItem(e); // find the highlight that was clicked var imageX = (imageV2.imgTbl[0].getBoundingClientRect().left) + imageV2.LEFTADD; var xDiff = (e.clientX) - imageX; - var clickPos = genomePos.pixelsToBases(img, xDiff, xDiff+1, hgTracks.winStart, hgTracks.winEnd); + var clickPos = genomePos.pixelsToBases(img, xDiff, xDiff+1, hgTracks.winStart, hgTracks.winEnd, false); rightClick.clickedHighlightIdx = dragSelect.findHighlightIdxForPos(clickPos); // XXXX? posting.blockUseMap = true; return true; }, hideTransition:'hide', // hideCallback fails if these are not defined. hideSpeed:10, hideCallback: function() { $('p.btn.blueButtons').removeClass('blueButtons'); $('tr.trDraggable.greenRows').removeClass('greenRows'); } }); return; } };