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/bedTrack.c src/hg/hgTracks/bedTrack.c index 465d76fdfe6..33a6d8e244f 100644 --- src/hg/hgTracks/bedTrack.c +++ src/hg/hgTracks/bedTrack.c @@ -7,30 +7,31 @@ #include "jksql.h" #include "bed.h" #include "hdb.h" #include "bedCart.h" #include "bbiFile.h" #include "bigBed.h" #include "hgTracks.h" #include "cds.h" #include "bedTabix.h" #include "obscure.h" #include "bigBedFilter.h" #include "bigBedLabel.h" #include "snake.h" #include "liftOver.h" #include "quickLift.h" +#include "htmlColor.h" #define SEQ_DELIM '~' struct bed *bedLoadPairedTagAlign(char **row) /* Load first six fields of bed. * Add ~seq1~seq2 to end of name * Then remove the sequence to extra field when we convert to linkedFeature. * Assumes seq1 and seq2 are in row[6] and row[7], as they would be with a * pairedTagAlign type (hg/lib/encode/pairedTagAlign.as). It would be good to be * able to check these columns exist but we dont have the sqlResult here. */ { char buf[1024]; struct bed *ret = bedLoad6(row); safef(buf, sizeof(buf), "%s%c%s%c%s", ret->name, SEQ_DELIM, row[6], SEQ_DELIM, row[7]); freez(&(ret->name)); @@ -624,41 +625,43 @@ } } slReverse(&lfList); if(tg->extraUiData) filterBed(tg, &lfList); slSort(&lfList, linkedFeaturesCmp); tg->items = lfList; filterItemsOnNames(tg); maybeLoadSnake(tg); // if we're in snake mode, change the methods } Color colorFromCart(struct track *tg, Color color) /* Return the RGB color from the cart setting 'colorOverride' or just return color */ { +if (!cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, "colorOverrideOn", FALSE)) + return color; char *hexColorStr = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "colorOverride"); -if (hexColorStr==NULL || isEmpty(hexColorStr)) +if (isEmpty(hexColorStr)) return color; -if (hexColorStr[0]=='#') - hexColorStr++; -if (strlen(hexColorStr)!=6) +unsigned rgb; +if (!htmlColorForCode(hexColorStr, &rgb)) return color; -long rgb = strtol(hexColorStr,NULL,16); // Big and little Endians +int r, g, b; +htmlColorToRGB(rgb, &r, &g, &b); tg->itemColor = NULL; tg->itemNameColor = NULL; -return MAKECOLOR_32( ((rgb>>16)&0xff), ((rgb>>8)&0xff), (rgb&0xff) ); +return MAKECOLOR_32(r, g, b); } void bedDrawSimpleAt(struct track *tg, void *item, struct hvGfx *hvg, int xOff, int y, double scale, MgFont *font, Color color, enum trackVisibility vis) /* Draw a single simple bed item at position. */ { struct bed *bed = item; int heightPer = tg->heightPer; int s = max(bed->chromStart, winStart), e = min(bed->chromEnd, winEnd); if (s > e) return; int x1 = round((s-winStart)*scale) + xOff; int x2 = round((e-winStart)*scale) + xOff; int w = x2 - x1;