8c908f948b09826c6cb4452ee5b282aca41be85e
galt
  Tue Dec 8 21:52:59 2015 -0800
Multi-region (exonMostly). This work allows people to look at virtual chromosomes from a list of regions and then navigate and perform all of the usual functions on it.

diff --git src/hg/hgTracks/variation.c src/hg/hgTracks/variation.c
index ce989bc..3e0006f 100644
--- src/hg/hgTracks/variation.c
+++ src/hg/hgTracks/variation.c
@@ -1210,73 +1210,77 @@
 /* Clip here so that text will tend to be more visible... */
 if (tg->drawName && vis != tvSquish)
     mapBoxHc(hvg, s->chromStart, s->chromEnd, x1, y, w, heightPer,
 	     tg->track, tg->mapItemName(tg, s), NULL);
 }
 
 static void snpMapDrawItems(struct track *tg, int seqStart, int seqEnd,
         struct hvGfx *hvg, int xOff, int yOff, int width,
         MgFont *font, Color color, enum trackVisibility vis)
 /* Draw snpMap items. */
 {
 double scale = scaleForPixels(width);
 int lineHeight = tg->lineHeight;
 int heightPer = tg->heightPer;
 int w, y;
-boolean withLabels = (withLeftLabels && vis == tvPack && !tg->drawName);
+boolean withLabels = (withLeftLabels && (vis == tvPack || (vis == tvFull && isTypeBedLike(tg))) && !tg->drawName);
 #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
 if (theImgBox != NULL)
     withLabels = (withLeftLabels && (vis == tvPack || vis == tvFull) && !tg->drawName);
 #endif ///def IMAGEv2_NO_LEFTLABEL_ON_FULL
 
 if (!tg->drawItemAt)
     errAbort("missing drawItemAt in track %s", tg->track);
 
-if (vis == tvPack || vis == tvSquish)
+if (vis == tvPack || vis == tvSquish || (vis == tvFull && isTypeBedLike(tg)))
     {
     struct spaceSaver *ss = tg->ss;
     struct spaceNode *sn = NULL;
     hvGfxSetClip(hvg, insideX, yOff, insideWidth, tg->height);
     for (sn = ss->nodeList; sn != NULL; sn = sn->next)
         {
         struct slList *item = sn->val;
         int s = tg->itemStart(tg, item);
         int e = tg->itemEnd(tg, item);
         int x1 = round((s - winStart)*scale) + xOff;
         int x2 = round((e - winStart)*scale) + xOff;
         int textX = x1;
         char *name = tg->itemName(tg, item);
         Color itemColor = tg->itemColor(tg, item, hvg);
         Color itemNameColor = tg->itemNameColor(tg, item, hvg);
 
         y = yOff + lineHeight * sn->row;
         tg->drawItemAt(tg, item, hvg, xOff, y, scale, font, itemColor, vis);
         if (withLabels)
             {
             int nameWidth = mgFontStringWidth(font, name);
             int dotWidth = tl.nWidth/2;
+	    boolean snapLeft = FALSE;
             textX -= nameWidth + dotWidth;
         #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
-            if (theImgBox == NULL && textX < insideX)
+            if (theImgBox == NULL && textX < fullInsideX)
         #else///ifndef IMAGEv2_NO_LEFTLABEL_ON_FULL
-            if (textX < insideX)        /* Snap label to the left. */
+            if (textX < fullInsideX)        /* Snap label to the left. */
         #endif ///ndef IMAGEv2_NO_LEFTLABEL_ON_FULL
+		snapLeft = TRUE;
+	    snapLeft |= (vis == tvFull && isTypeBedLike(tg));
+	    if (snapLeft)
                 {
 		textX = leftLabelX;
                 assert(hvgSide != NULL);
                 hvGfxUnclip(hvgSide);
-                hvGfxSetClip(hvgSide, leftLabelX, yOff, insideWidth, tg->height);
+		hvGfxSetClip(hvgSide, leftLabelX, yOff, fullInsideX - leftLabelX, tg->height);
                 hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, heightPer,
 			    itemNameColor, font, name);
                 hvGfxUnclip(hvgSide);
                 hvGfxSetClip(hvgSide, insideX, yOff, insideWidth, tg->height);
 		}
             else
                 hvGfxTextRight(hvg, textX, y, nameWidth, heightPer,
 			    itemNameColor, font, name);
             }
         if (!tg->mapsSelf && ( ( w = x2-textX ) > 0 ))
 	    mapBoxHgcOrHgGene(hvg, s, e, textX, y, w, heightPer, tg->track, tg->mapItemName(tg, item), name, NULL, FALSE, NULL);
         }
     hvGfxUnclip(hvg);
     }
 else
@@ -1306,100 +1310,108 @@
 	    y += lineHeight;
             }
         }
     }
 }
 
 static void snpDrawItems(struct track *tg, int seqStart, int seqEnd,
         struct hvGfx *hvg, int xOff, int yOff, int width,
         MgFont *font, Color color, enum trackVisibility vis)
 /* Draw snp items. */
 {
 double scale = scaleForPixels(width);
 int lineHeight = tg->lineHeight;
 int heightPer = tg->heightPer;
 int y, w;
-boolean withLabels = (withLeftLabels && vis == tvPack && !tg->drawName);
+boolean withLabels = (withLeftLabels && (vis == tvPack || (vis == tvFull && isTypeBedLike(tg))) && !tg->drawName);
 #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
 if (theImgBox != NULL)
     withLabels = (withLeftLabels && (vis == tvPack || tvFull) && !tg->drawName);
 #endif ///def IMAGEv2_NO_LEFTLABEL_ON_FULL
 snp125ColorSource = snp125ColorSourceFromCart(cart, tg->tdb);
 
 if (!tg->drawItemAt)
     errAbort("missing drawItemAt in track %s", tg->track);
-if (vis == tvPack || vis == tvSquish)
+if (vis == tvPack || vis == tvSquish || (vis == tvFull && isTypeBedLike(tg)))
     {
     struct spaceSaver *ss = tg->ss;
     struct spaceNode *sn = NULL;
     hvGfxSetClip(hvg, insideX, yOff, insideWidth, tg->height);
     for (sn = ss->nodeList; sn != NULL; sn = sn->next)
         {
         struct slList *item = sn->val;
         int s = tg->itemStart(tg, item);
         int e = tg->itemEnd(tg, item);
         int x1 = round((s - winStart)*scale) + xOff;
         int x2 = round((e - winStart)*scale) + xOff;
         int textX = x1;
         char *name = tg->itemName(tg, item);
 	Color itemColor = tg->itemColor(tg, item, hvg);
         Color itemNameColor = tg->itemNameColor(tg, item, hvg);
         boolean drawNameInverted = FALSE;
 
         y = yOff + lineHeight * sn->row;
         tg->drawItemAt(tg, item, hvg, xOff, y, scale, font, itemColor, vis);
         if (withLabels)
             {
             int nameWidth = mgFontStringWidth(font, name);
             int dotWidth = tl.nWidth/2;
 	    boolean snapLeft = FALSE;
 	    drawNameInverted = highlightItem(tg, item);
             textX -= nameWidth + dotWidth;
-            snapLeft = (textX < insideX);
+
         #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
-            if (theImgBox == NULL && snapLeft)
+            if (theImgBox == NULL && textX < fullInsideX)
         #else///ifndef IMAGEv2_NO_LEFTLABEL_ON_FULL
-            if (snapLeft)
+            if (textX < fullInsideX)        /* Snap label to the left. */
         #endif ///ndef IMAGEv2_NO_LEFTLABEL_ON_FULL
+		snapLeft = TRUE;
+	    snapLeft |= (vis == tvFull && isTypeBedLike(tg));
+	    if (snapLeft)
                 {
 		textX = leftLabelX;
                 assert(hvgSide != NULL);
                 hvGfxUnclip(hvgSide);
-                hvGfxSetClip(hvgSide, leftLabelX, yOff, insideWidth, tg->height);
+                hvGfxSetClip(hvgSide, leftLabelX, yOff, fullInsideX - leftLabelX, tg->height);
 		if (drawNameInverted)
 		    {
 		    int boxStart = leftLabelX + leftLabelWidth - 2 - nameWidth;
                     hvGfxBox(hvgSide, boxStart, y, nameWidth+1, heightPer - 1, color);
                     hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, heightPer,
 		                MG_WHITE, font, name);
 		    }
 		else
                     hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, heightPer,
 			    itemNameColor, font, name);
                 hvGfxUnclip(hvgSide);
                 hvGfxSetClip(hvgSide, insideX, yOff, insideWidth, tg->height);
 		}
             else
 	        {
+		int pdfSlop=nameWidth/5;
+		hvGfxUnclip(hvg);
+		hvGfxSetClip(hvg, textX-1-pdfSlop, y, nameWidth+1+pdfSlop, heightPer);
 		if (drawNameInverted)
 		    {
 		    hvGfxBox(hvg, textX - 1, y, nameWidth+1, heightPer-1, color);
 		    hvGfxTextRight(hvg, textX, y, nameWidth, heightPer, MG_WHITE, font, name);
 		    }
 		else
                     hvGfxTextRight(hvg, textX, y, nameWidth, heightPer,
 			    itemNameColor, font, name);
+                hvGfxUnclip(hvg);
+                hvGfxSetClip(hvg, insideX, yOff, insideWidth, tg->height);
 		}
             }
         if (!tg->mapsSelf && ( ( w = x2-textX ) > 0 ) )
 	    mapBoxHgcOrHgGene(hvg, s, e, textX, y, w, heightPer, tg->track, tg->mapItemName(tg, item), name, NULL, FALSE, NULL);
         }
     hvGfxUnclip(hvg);
     }
 else
     {
     struct slList *item;
     y = yOff;
     for (item = tg->items; item != NULL; item = item->next)
         {
 	Color itemColor = tg->itemColor(tg, item, hvg);
         tg->drawItemAt(tg, item, hvg, xOff, y, scale, font, itemColor, vis);