6f7f5bac129d59cfb99d47a3f1de118c48e423cd chmalee Wed Jul 23 15:25:01 2025 -0700 When mousing over a track, put a gear icon over the grey bar to hint that a context click is available. Put a 'x' icon to the right (or left in revCmp mode) to allow quick hiding of tracks. Both icons are enabled via hg.conf:greyBarIcons, refs #34420 diff --git src/hg/js/utils.js src/hg/js/utils.js index d510cdd46cd..f4620ae5890 100644 --- src/hg/js/utils.js +++ src/hg/js/utils.js @@ -3832,34 +3832,119 @@ if (jQuery.tableDnD) { var rows = dragReorder.getContiguousRowSet($(this).parents('tr.trDraggable')[0]); if (rows) $( rows ).removeClass("trDrag"); } }, trMouseOver: function (e) { // Trying to make sure there is always a imageV2.lastTrack so that we know where we are var id = ''; var a = /tr_(.*)/.exec($(this).attr('id')); // voodoo if (a && a[1]) { id = a[1]; } if (id.length > 0) { - if ( ! imageV2.lastTrack || imageV2.lastTrack.id !== id) + if ( ! imageV2.lastTrack || imageV2.lastTrack.id !== id) { imageV2.lastTrack = rightClick.makeMapItem(id); // currentMapItem gets set by mapItemMapOver. This is just backup } + + if (typeof greyBarIcons !== 'undefined' && greyBarIcons === true) { + // add a gear icon over the grey bar to bring up the context menu + let tdBtn = document.getElementById("td_btn_" + id); + if (tdBtn) { + if (!document.getElementById("gear_btn_" + id)) { + let span = document.createElement("span"); + span.id = "gear_btn_" + id; + span.classList.add("hgTracksGearIcon", "ui-icon", "ui-icon-gear"); + span.title = "Configure track"; + tdBtn.appendChild(span); + tdBtn.style.position = "relative"; + span.addEventListener("click", (e) => { + // create a contextmenu event that the imgTbl will pick up + e.preventDefault(); + e.stopPropagation(); + e.stopImmediatePropagation(); + const rightClickEvent = new MouseEvent("contextmenu", { + bubbles: true, + cancelable: true, + view: window, + clientX: tdBtn.getBoundingClientRect().left + 15, + clientY: tdBtn.getBoundingClientRect().top, + button: 2, + }); + tdBtn.dispatchEvent(rightClickEvent); + }); + } + } + + // add an 'x' icon in the label area to hide the track + let tdSide = document.getElementById("td_side_" + id); + if (tdSide) { + // mouseover event fires if you stop moving the mouse while still + // hovering the element and then move it again, don't make + // duplicate btns in that case + if (!document.getElementById("close_btn_" + id)) { + let btn = document.createElement("span"); + btn.id = "close_btn_" + id; + btn.classList.add("hgTracksCloseIcon", "ui-icon", "ui-icon-close"); + btn.title = "Hide track"; + tdSide.appendChild(btn); + tdSide.style.position = "relative"; + if (hgTracks && hgTracks.revCmplDisp) { + // set up 'x' icon to the right + btn.classList.add("hgTracksCloseIconRight"); + } else { + // set up 'x' icon to the left + btn.classList.add("hgTracksCloseIconLeft"); + } + btn.addEventListener("click", (e) => { + rightClick.hideTracks([id]); + }); + } + } + } + } + }, + + trMouseLeave: function(e) + { + var id = ''; + var a = /tr_(.*)/.exec($(this).attr('id')); // voodoo + if (a && a[1]) { + id = a[1]; + } + if (id.length > 0) { + // remove 'x' icon in the label area to hide the track + let tdSide = document.getElementById("td_side_" + id); + if (tdSide) { + let btn = document.getElementById("close_btn_" + id); + if (btn) { + btn.remove(); + } + } + + // remove gear icon over the grey bar + let tdBtn = document.getElementById("td_btn_" + id); + if (tdBtn) { + let btn = document.getElementById("gear_btn_" + id); + if (btn) { + btn.remove(); + } + } + } }, mapItemMouseOver: function () { // Record data for current map area item var id = this.id; if (!id || id.length === 0) { id = ''; var tr = $( this ).parents('tr.imgOrd'); if ( $(tr).length === 1 ) { var a = /tr_(.*)/.exec($(tr).attr('id')); // voodoo if (a && a[1]) { id = a[1]; } } @@ -3908,30 +3993,31 @@ var btns = $("p.btn"); if (btns.length > 0) { dragReorder.zipButtons($('#imgTbl')); $(btns).on("mouseenter", dragReorder.buttonMouseOver ); $(btns).on("mouseleave", dragReorder.buttonMouseOut ); $(btns).show(); } var handle = $("td.dragHandle"); if (handle.length > 0) { $(handle).on("mouseenter", dragReorder.dragHandleMouseOver ); $(handle).on("mouseleave", dragReorder.dragHandleMouseOut ); } // setup mouse callbacks for the area tags $("#imgTbl").find("tr").on("mouseover", dragReorder.trMouseOver ); + $("#imgTbl").find("tr").on("mouseleave", dragReorder.trMouseLeave ); $("#imgTbl").find("tr").each( function (i, row) { // save the original y positions of each row //if (row.id in dragReorder.originalHeights === false) { dragReorder.originalHeights[row.id] = row.getBoundingClientRect().y + window.scrollY; //} }); $(".area").each( function(t) { this.onmouseover = dragReorder.mapItemMouseOver; this.onmouseout = dragReorder.mapItemMouseOut; this.onclick = posting.mapClk; }); } };