46a8a2fde9e17a401843959b8c0197c95d43ea45
braney
  Fri Mar 15 15:54:50 2024 -0700
add quickLiftover chain to the list of tracks coming from an exported
hub

diff --git src/hg/hgTracks/chainTrack.c src/hg/hgTracks/chainTrack.c
index 8aa43a0..8d9fd9e 100644
--- src/hg/hgTracks/chainTrack.c
+++ src/hg/hgTracks/chainTrack.c
@@ -329,41 +329,95 @@
             for(; sf; sf = sf->next)
                 {
                 int temp;
 
                 temp = sf->qStart;
                 sf->qStart = lf->qSize - sf->qEnd;
                 sf->qEnd = lf->qSize - temp;
                 }
 	    }
         }
 if (tg->isBigBed)
     bbiFileClose(&bbClosure.bbi);
 else
     hFreeConn(&sqlClosure.conn);
 }
+
+static void denseChainReverse(struct track *tg, int seqStart, int seqEnd,
+                        struct hvGfx *hvg, int xOff, int yOff, int width,
+                        MgFont *font, Color color, enum trackVisibility vis)
+/* draw a dense chain in a mode that only shows the gaps. */
+{
+hvGfxSetClip(hvgSide, insideX, yOff, insideWidth, tg->height);
+struct slList *item;
+int y = yOff;
+double scale = scaleForWindow(width, seqStart, seqEnd);
+int heightPer = tg->heightPer;
+color = 0x5050ffff;
+for (item = tg->items; item != NULL; item = item->next)
+    {
+    struct linkedFeatures *lf = (struct linkedFeatures *)item;
+    struct simpleFeature *sf = lf->components;
+    unsigned prev = winStart;
+    for (; sf; sf = sf->next)
+        {
+        unsigned s = sf->start;
+        drawScaledBox(hvg, prev, s,  scale, xOff, y, heightPer, color);
+        prev = sf->end;
+        }
+    drawScaledBox(hvg, prev, winEnd,  scale, xOff, y, heightPer, color);
+
+    }
+
+color = 0xff5050ff;
+for (item = tg->items; item != NULL; item = item->next)
+    {
+    struct linkedFeatures *lf = (struct linkedFeatures *)item;
+    struct simpleFeature *sf = lf->components;
+
+    mapBoxHgcOrHgGene(hvg, winStart, winEnd, xOff, yOff, insideWidth, heightPer, tg->track,
+                  lf->extra, "Go to hg38", NULL, TRUE, NULL);
+    struct simpleFeature *prev = NULL;
+    for (; sf; sf = sf->next)
+        {
+        unsigned s = sf->start;
+        if (prev)
+            {
+            if (prev->qEnd != sf->qStart)
+                drawScaledBox(hvg, s, s,  scale, xOff, y, heightPer, color);
+            }
+        prev = sf;
+        }
+    }
+}
+
 void chainDraw(struct track *tg, int seqStart, int seqEnd,
         struct hvGfx *hvg, int xOff, int yOff, int width,
         MgFont *font, Color color, enum trackVisibility vis)
 /* Draw chained features. This loads up the simple features from
  * the chainLink table, calls linkedFeaturesDraw, and then
  * frees the simple features again. */
 {
 
 if (tg->items == NULL)		/*Exit Early if nothing to do */
     return;
 
+char *chainType = trackDbSetting(tg->tdb, "chainType");
+if ((chainType != NULL) && (vis == tvDense) )
+    denseChainReverse(tg, seqStart, seqEnd, hvg, xOff, yOff, width,
+	font, color, vis);
+else
     linkedFeaturesDraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width,
 	font, color, vis);
 }
 
 void bigChainLoadItems(struct track *tg)
 /* Load up all of the chains from correct table into tg->items
  * item list.  At this stage to conserve memory for other tracks
  * we don't load the links into the components list until draw time. */
 {
 boolean doSnake = cartOrTdbBoolean(cart, tg->tdb, "doSnake" , FALSE);
 struct linkedFeatures *list = NULL, *lf;
 int qs;
 char *optionChrStr;
 struct cartOptions *chainCart;