a1525e0f14f76903c16d5ba788f7a9afcc8c5ed1
max
  Fri Jun 4 04:56:39 2021 -0700
adding folder icons to hgTracks main track list, refs #25035
code review: this is an experiment and initially should remain in the
branch ui-track-icons, until merged on purpose into master.

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 40d192b..7b2670e 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -8001,30 +8001,74 @@
 }
 
 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 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, "\"", """);
+    // Print an icon before the title when one is defined
+    hPrintPennantIcon(track->tdb);
+
+    struct dyString *dsMouseOver = dyStringCreate("%s", 
+longLabel);
+    struct trackDb *tdb = track->tdb;
+
+    if (tdb->children)
+        {
+        dyStringPrintf(dsMouseOver, " - %d subtracks of different types (super track)",
+            slCount(tdb->children));
+        }
+    else if (tdb->subtracks)
+        {
+        dyStringPrintf(dsMouseOver, " - %d subtracks of similar types (composite)",
+            slCount(tdb->subtracks));
+        }
+
+    hPrintf("<A HREF=\"%s\" title=\"%s\">", url, dyStringCannibalize(&dsMouseOver));
+
+    freeMem(url);
+    freeMem(longLabel);
+    }
+
+//if (tdbIsSuper(track->tdb) || tdbIsComposite(track->tdb))
+    //hPrintf("<i id='folderIcon' class='fa fa-folder-o'></i>");
+if (tdbIsSuper(track->tdb))
+    hPrintf("<i id='folderIcon' class='fa fa-folder-o'></i>");
+if (tdbIsComposite(track->tdb))
+    hPrintf("<i id='folderIcon' class='fa fa-folder'></i>");
+
+hPrintf(" %s", track->shortLabel);
+hPrintf("<BR> ");
+if (track->hasUi)
+    hPrintf("</A>");
+}
+
 void doTrackForm(char *psOutput, struct tempName *ideoTn)
 /* Make the tracks display form with the zoom/scroll buttons and the active
  * image.  If the ideoTn parameter is not NULL, it is filled in if the
  * ideogram is created.  */
 {
 struct group *group;
 struct track *track;
 char *freezeName = NULL;
 boolean hideAll = cgiVarExists("hgt.hideAll");
 boolean defaultTracks = cgiVarExists("hgt.reset");
 boolean showedRuler = FALSE;
 boolean showTrackControls = cartUsualBoolean(cart, "trackControlsOnMain", TRUE);
 boolean multiRegionButtonTop = cfgOptionBooleanDefault(MULTI_REGION_CFG_BUTTON_TOP, FALSE);
 long thisTime = 0, lastTime = 0;
 
@@ -9033,48 +9077,32 @@
 		freeMem(url);
 		}
 
 	    /* Add supertracks to track list, sort by priority and
 	     * determine if they have visible member tracks */
 	    groupTrackListAddSuper(cart, group);
 
 	    /* Display track controls */
 	    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);
-		if (track->hasUi)
-		    {
-		    char *url = trackUrl(track->track, chromName);
-		    char *longLabel = replaceChars(track->longLabel, "\"", "&quot;");
-                    hPrintPennantIcon(track->tdb);
 
-                    // Print an icon before the title when one is defined
-                    hPrintf("<A HREF=\"%s\" title=\"%s\">", url, longLabel);
-
-                    freeMem(url);
-                    freeMem(longLabel);
-                    }
-		hPrintf(" %s", track->shortLabel);
-		if (tdbIsSuper(track->tdb))
-		    hPrintf("...");
-		hPrintf("<BR> ");
-		if (track->hasUi)
-		    hPrintf("</A>");
+                printTrackLink(track);
 
 		if (hTrackOnChrom(track->tdb, chromName))
 		    {
 		    if (tdbIsSuper(track->tdb))
 			superTrackDropDown(cart, track->tdb,
 					    superTrackHasVisibleMembers(track->tdb));
 		    else
                         {
                         /* 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"));
                         }
@@ -10753,30 +10781,32 @@
     if (enableMouseOver)
       webIncludeResourceFile("mouseOver.css");
 
     if (!searching)     // NOT doing search
         {
         webIncludeResourceFile("jquery.contextmenu.css");
         jsIncludeFile("jquery.contextmenu.js", NULL);
         webIncludeResourceFile("ui.dropdownchecklist.css");
         jsIncludeFile("ui.dropdownchecklist.js", NULL);
         jsIncludeFile("ddcl.js", NULL);
         }
 
     hPrintf("<div id='hgTrackUiDialog' style='display: none'></div>\n");
     hPrintf("<div id='hgTracksDialog' style='display: none'></div>\n");
 
+    webIncludeResourceFile("font-awesome.min.css");
+
     cartFlushHubWarnings();
     }
 
 
 if (cartVarExists(cart, "chromInfoPage"))
     {
     cartRemove(cart, "chromInfoPage");
     chromInfoPage();
     }
 else if (differentString(cartUsualString(cart, TRACK_SEARCH,"0"),"0"))
     {
     doSearchTracks(groupList);
     }
 else if (sameWord(configPageCall, "configure") ||
          sameWord(configPageCall, "configure tracks and display"))