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