8593c40cb74ab6ee9f2318056626305d9d9544d3
braney
  Fri Apr 10 12:54:44 2026 -0700
Fix color picker from code review, refs #37329, refs #20460

- Replace Spectrum JS color picker with native HTML5 color input,
matching existing Hi-C picker
- Color saved on form submit, not immediately via AJAX
- Add checkbox to enable/disable color override; auto-checks when
user picks a color
- Gate color picker behind hg.conf showColorPicker=on (off by default)
- Only show picker for non-composite tracks that support it: bed,
bigBed, genePred, bigGenePred, wig, bigWig, rmsk, interact,
bigInteract, bigLolly, vcfTabix, vcf
- Add colorFromCart calls to interact, lolly, vcf phased, and pgSnp
drawing code
- Revert hui.js Spectrum changes from cfeb4d4 (no longer needed)
- Use htmlColorForCode()/htmlColorToRGB() from htmlColor.h instead of
hand-rolled hex parsing in colorFromCart

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

diff --git src/hg/hgTracks/lollyTrack.c src/hg/hgTracks/lollyTrack.c
index 85758a5fec4..bc714061350 100644
--- src/hg/hgTracks/lollyTrack.c
+++ src/hg/hgTracks/lollyTrack.c
@@ -160,30 +160,31 @@
         struct hvGfx *hvg, int xOff, int yOff, int width, 
         MgFont *font, Color color, enum trackVisibility vis)
 /* Draw a list of lolly structures. */
 {
 double scale = scaleForWindow(width, seqStart, seqEnd);
 struct lolly *popList = tg->items, *pop;
 struct lollyCartOptions *lollyCart = tg->lollyCart;
 int trackHeight = tg->lollyCart->height ;
 
 if ( tg->visibility == tvDense)  // in dense mode we just draw lines
     {
     for (pop = popList; pop; pop = pop->next)
         {
         int sx = ((pop->start - seqStart) + .5) * scale + xOff; // x coord of center (lower region)
         unsigned color =  getLollyColor(hvg, pop->color);
+        color = colorFromCart(tg, color);
         hvGfxLine(hvg, sx, yOff, sx , yOff+ tl.fontHeight, color);
         }
     return;
     }
 
 doYLabels(tg, hvg, width, trackHeight, tg->lollyCart, xOff, yOff, color, font, FALSE);
 
 if (popList == NULL)   // nothing to draw
     {
     maybeDrawQuickLiftLines(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis);
     return;
     }
 
 boolean noMapBoxes = FALSE;
 int numItems =  slCount(popList);
@@ -213,30 +214,31 @@
 // first draw the lines so they won't overlap any lollies
 yOff += LOLLY_DIAMETER / 2;
 
 if (!lollyCart->noStems)
     for (pop = popList; pop; pop = pop->next)
         {
         int sx = ((pop->start - seqStart) + .5) * scale + xOff; // x coord of center (lower region)
         hvGfxLine(hvg, sx, yOff + trackHeight, sx , yOff+(usableHeight - pop->height), MG_GRAY);
         }
 
 // now draw the sucker part!
 for (pop = popList; pop; pop = pop->next)
     {
     int sx = ((pop->start - seqStart) + .5) * scale + xOff; // x coord of center (lower region)
     unsigned color =  getLollyColor(hvg, pop->color);
+    color = colorFromCart(tg, color);
     hvGfxCircle(hvg, sx, yOff + (usableHeight - (pop->height )), pop->radius, color, TRUE);
     if ( tg->visibility != tvSquish)  
         hvGfxCircle(hvg, sx, yOff + (usableHeight - (pop->height )), pop->radius, MG_BLACK, FALSE);
     if (!noMapBoxes)
         mapBoxHgcOrHgGene(hvg, pop->start, pop->end, sx - pop->radius, yOff + usableHeight - pop->radius - pop->height, 2 * pop->radius,2 * pop->radius,
                           tg->track, pop->name, pop->mouseOver, NULL, TRUE, NULL);
     }
 maybeDrawQuickLiftLines(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis);
 }
 
 void lollyLeftLabels(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)
 // draw the labels on the left margin