a430d3db16c5a158c92ca1f4d6004222b5ec239b
angie
  Wed May 7 13:24:34 2014 -0700
Fixing pgSnp full-mode duplicate label bug noticed by Matt.  pgSnpdraws its own labels inside pgSnpDrawAt().  makeActiveImage calls
doLeftLabels which draws the full-mode left labels -- unless there is
a track->drawLeftLabels, in which case doOwnLeftLabels is used to
call track->drawLeftLabels after drawing items.  My solution for now
is to give pgSnp a no-op track->drawLeftLabels to prevent the usual
full mode left labels.  It would be nice to move the label-drawing
code out of pgSnpDrawAt and into pgSnpLeftLabels, but that would take
a lot more dev & testing effort.
refs #9329 notes 58, 60, 62

diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index 3d41fd6..4cf40d7 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -3059,50 +3059,50 @@
     hvGfxSetClip(hvgSide, insideX, yOff, insideWidth, tg->height);
     }
 /* restore state */
 tg->limitedVis = origVis;
 tg->heightPer = origHeightPer;
 tg->lineHeight = origLineHeight;
 }
 
 static void genericDrawItem(struct track *tg, struct spaceNode *sn,
                             struct hvGfx *hvg, int xOff, int yOff, int width,
                             MgFont *font, Color color, Color labelColor, enum trackVisibility vis,
                             double scale, boolean withLeftLabels)
 /* draw one non-overflow item */
 {
 struct slList *item = sn->val;
-boolean withLabels = (withLeftLabels && (vis == tvPack) && !tg->drawName);
 int s = tg->itemStart(tg, item);
 int e = tg->itemEnd(tg, item);
 int sClp = (s < winStart) ? winStart : s;
 int eClp = (e > winEnd)   ? winEnd   : e;
 int x1 = round((sClp - winStart)*scale) + xOff;
 int x2 = round((eClp - winStart)*scale) + xOff;
 int textX = x1;
 
 if (tg->itemNameColor != NULL)
     {
     color = tg->itemNameColor(tg, item, hvg);
     labelColor = color;
     if (withLeftLabels && isTooLightForTextOnWhite(hvg, color))
 	labelColor = somewhatDarkerColor(hvg, color);
     }
 int y = yOff + tg->lineHeight * sn->row;
 tg->drawItemAt(tg, item, hvg, xOff, y, scale, font, color, vis);
-/* pgSnp tracks may change flags between items */
-withLabels = (withLeftLabels && withIndividualLabels && (vis == tvPack) && !tg->drawName);
+
+/* pgSnpDrawAt may change withIndividualLabels between items */
+boolean withLabels = (withLeftLabels && withIndividualLabels && (vis == tvPack) && !tg->drawName);
 if (withLabels)
     {
     char *name = tg->itemName(tg, item);
     int nameWidth = mgFontStringWidth(font, name);
     int dotWidth = tl.nWidth/2;
     boolean snapLeft = FALSE;
     boolean drawNameInverted = highlightItem(tg, item);
     textX -= nameWidth + dotWidth;
     snapLeft = (textX < insideX);
     /* Special tweak for expRatio in pack mode: force all labels
      * left to prevent only a subset from being placed right: */
     snapLeft |= (startsWith("expRatio", tg->tdb->type));
 #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
     if (theImgBox == NULL && snapLeft)
 #else///ifndef IMAGEv2_NO_LEFTLABEL_ON_FULL
@@ -9696,43 +9696,53 @@
 chopByChar(nameCopy, '/', all, el->alleleCount);
 if (differentString(el->alleleFreq, ""))
     chopByChar(cntCopy, ',', freq, el->alleleCount);
 
 for (i=0; i < el->alleleCount; i++)
     {
     if (sameString(el->alleleFreq, "") || sameString(freq[i], "0"))
         freq[i] = "?";
     dyStringPrintf(ds, "%s:%s ", all[i], freq[i]);
     }
 mapBoxHgcOrHgGene(hvg, start, end, x, y, width, height, tg->track,
                   mapItemName, ds->string, directUrl, withHgsid, NULL);
 freeDyString(&ds);
 }
 
+void pgSnpLeftLabels(struct track *tg, int seqStart, int seqEnd,
+		     struct hvGfx *hvg, int xOff, int yOff, int width, int height,
+		     boolean withCenterLabels, MgFont *font, Color color,
+		     enum trackVisibility vis)
+/* pgSnp draws its own left labels when it draws the item; this is a placeholder so the
+ * default full-mode left labels aren't drawn too. */
+{
+}
+
 void pgSnpMethods (struct track *tg)
 /* Personal Genome SNPs: show two alleles with stacked color bars for base alleles and
  * (if available) allele counts in mouseover. */
 {
 bedMethods(tg);
 tg->loadItems = loadPgSnp;
 tg->freeItems = freePgSnp;
 tg->totalHeight = pgSnpHeight;
 tg->itemName = pgSnpName;
 tg->drawItemAt = pgSnpDrawAt;
 tg->mapItem = pgSnpMapItem;
 tg->nextItemButtonable = TRUE;
 tg->nextPrevItem = linkedFeaturesLabelNextPrevItem;
+tg->drawLeftLabels = pgSnpLeftLabels;
 }
 
 void loadBlatz(struct track *tg)
 {
 enum trackVisibility vis = tg->visibility;
 loadXenoPsl(tg);
 if (vis != tvDense)
     {
     lookupProteinNames(tg);
     }
 vis = limitVisibility(tg);
 }
 
 void loadBlast(struct track *tg)
 {