83b751ac37696b83777d2fe6939e4571e7da0bd4
max
  Mon Jun 12 06:28:58 2023 -0700
adding little trash icons next to custom tracks for quicker disposal, refs #31504

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index f3f5b49..5c741cb 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -128,31 +128,31 @@
 
 boolean withIdeogram = TRUE;            /* Display chromosome ideogram? */
 
 int rulerMode = tvHide;         /* on, off, full */
 struct hvGfx *hvgSide = NULL;   // Extra pointer to a sideLabel image that can be built if needed
 
 char *rulerMenu[] =
 /* dropdown for ruler visibility */
     {
     "hide",
     "dense",
     "full"
     };
 
 char *protDbName;               /* Name of proteome database for this genome. */
-#define MAX_CONTROL_COLUMNS 6
+#define MAX_CONTROL_COLUMNS 8
 #define LOW 1
 #define MEDIUM 2
 #define BRIGHT 3
 #define MAXCHAINS 50000000
 boolean hgDebug = FALSE;      /* Activate debugging code. Set to true by hgDebug=on in command line*/
 int imagePixelHeight = 0;
 struct hash *oldVars = NULL;
 struct jsonElement *jsonForClient = NULL;
 
 boolean hideControls = FALSE;           /* Hide all controls? */
 boolean trackImgOnly = FALSE;           /* caller wants just the track image and track table html */
 boolean ideogramToo =  FALSE;           /* caller wants the ideoGram (when requesting just one track) */
 
 /* Structure returned from resolvePosition.
  * We use this to to expand any tracks to full
@@ -8230,60 +8230,71 @@
 }
 
 static void printMultiRegionButton()
 /* Print button that launches multi-region configuration pop-up */
 {
 boolean isPressed = FALSE;
 if (differentString(virtModeType, "default"))
     isPressed = TRUE;
 char buf[256];
 safef(buf, sizeof buf, "configure %s multi-region display mode", 
                         isPressed ? "or exit" : "");
 hButtonNoSubmitMaybePressed("hgTracksConfigMultiRegionPage", "multi-region", buf,
             "popUpHgt.hgTracks('multi-region config'); return false;", isPressed);
 }
 
+static void printTrackDelIcon(struct track *track)
+/* little track icon after track name. Github uses SVG elements for all icons, apparently that is faster */
+{
+    hPrintf("<div data-track='%s' class='trackDeleteIcon'><svg xmlns='http://www.w3.org/2000/svg' height='0.8em' viewBox='0 0 448 512'><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d='M135.2 17.7C140.6 6.8 151.7 0 163.8 0H284.2c12.1 0 23.2 6.8 28.6 17.7L320 32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32h96l7.2-14.3zM32 128H416V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V128zm96 64c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16z'/></svg></div>", track->track);
+
+}
+
 static void printTrackLink(struct track *track)
 /* print a link hgTrackUi with shortLabel and various icons and mouseOvers */
 {
 if (track->hasUi)
     {
     char *url = trackUrl(track->track, chromName);
     char *longLabel = replaceChars(track->longLabel, "\"", "&quot;");
 
     struct dyString *dsMouseOver = dyStringCreate("%s", longLabel);
     struct trackDb *tdb = track->tdb;
 
     if (tdbIsSuper(tdb))
         dyStringPrintf(dsMouseOver, " - this is a container track with %d subtracks of different types "
                 "(super track)", slCount(tdb->children));
     else if (tdbIsComposite(tdb))
         dyStringPrintf(dsMouseOver, " - this is a container track with %d subtracks of similar types "
                 "(composite track)", slCount(tdb->subtracks));
 
     // Print icons before the title when any are defined
     hPrintIcons(track->tdb);
 
-    hPrintf("<A HREF=\"%s\" title=\"%s\">", url, dyStringCannibalize(&dsMouseOver));
+    hPrintf("<A class='trackLink' HREF=\"%s\" data-group='%s' data-track='%s' title=\"%s\">", url, track->groupName, track->track, dyStringCannibalize(&dsMouseOver));
 
     freeMem(url);
     freeMem(longLabel);
     }
 
 hPrintf("%s", track->shortLabel);
 if (track->hasUi)
     hPrintf("</A>");
+
+if (sameOk(track->groupName, "user"))
+    printTrackDelIcon(track);
+
 hPrintf("<BR>");
 }
 
 void printSearchHelpLink()
 /* print the little search help link next to the go button */
 {
 char *url = cfgOptionDefault("searchHelpUrl","../goldenPath/help/query.html");
 char *label = cfgOptionDefault("searchHelpLabel", "examples");
 if (!url || isEmpty(url))
     return;
 
 printf("<div id='searchHelp'><a target=_blank title='Documentation on what you can enter into the Genome Browser search box' href='%s'>%s</a></div>", url, label);
 }
 
 static void printDatabaseInfoHtml(char* database) 
@@ -9347,30 +9358,31 @@
 		controlGridEndCell(cg);
 		freeMem(url);
 		}
 
 	    /* Add supertracks to track list, sort by priority and
 	     * determine if they have visible member tracks */
 	    groupTrackListAddSuper(cart, group, superHash);
 
 	    /* Display track controls */
             if (group->errMessage)
                 {
 		myControlGridStartCell(cg, isOpen, group->name);
                 hPrintf("%s", group->errMessage);
 		controlGridEndCell(cg);
                 }
+
 	    for (tr = group->trackList; tr != NULL; tr = tr->next)
 		{
 		struct track *track = tr->track;
 		if (tdbIsSuperTrackChild(track->tdb))
 		    /* don't display supertrack members */
 		    continue;
 		myControlGridStartCell(cg, isOpen, group->name);
 
                 printTrackLink(track);
 
 		if (hTrackOnChrom(track->tdb, chromName))
 		    {
 		    if (tdbIsSuper(track->tdb))
 			superTrackDropDown(cart, track->tdb,
 					    superTrackHasVisibleMembers(track->tdb));
@@ -9378,30 +9390,31 @@
                         {
                         /* check for option of limiting visibility to one mode */
                         hTvDropDownClassVisOnly(track->track, track->visibility,
                                                 rTdbTreeCanPack(track->tdb),
                                                 (track->visibility == tvHide) ? "hiddenText"
                                                                               : "normalText",
                                                 trackDbSetting(track->tdb, "onlyVisibility"));
                         }
                     }
 		else
 		    /* If track is not on this chrom print an informational
 		    message for the user. */
 		    hPrintf("[No data-%s]", chromName);
 		controlGridEndCell(cg);
 		}
+
 	    /* now finish out the table */
 	    if (group->next != NULL)
 		controlGridEndRow(cg);
 	    }
         hashFree(&superHash);
 	endControlGrid(&cg);
 	}
 
     if (measureTiming)
         printTrackTiming();
 
     hPrintf("</DIV>\n");
     }
 if (showTrackControls)
     hButton("hgt.refresh", "refresh");