cfeb4d454d22011d7f637d060e7a51057d168504 braney Mon Mar 30 12:01:16 2026 -0700 Add color picker support for most track types, refs #20460 Co-Authored-By: Claude Opus 4.6 (1M context) diff --git src/hg/lib/hui.c src/hg/lib/hui.c index a20b7954ae4..baa53636309 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -6030,35 +6030,41 @@ safef(varName, sizeof(varName), "%s.nameFilter", name); char *onlyTransStr = cartUsualString(cart, varName, ""); cgiMakeTextVar(varName, onlyTransStr, 60); printInfoIcon("Enter the primary accession of the track, so RefSeq IDs for the RefSeq track, Gencode IDs for the Gencode track, etc. Separate multiple accessions with commas."); puts("\n\n"); } void colorTrackOption(struct cart *cart, char *name, struct trackDb *tdb) /* color picker for overriding track color */ { char varName[1024]; safef(varName, sizeof(varName), "%s.colorOverride", name); -char *colorValue = cartUsualString(cart, varName, ""); +char defaultColor[16]; +safef(defaultColor, sizeof(defaultColor), "#%02x%02x%02x", tdb->colorR, tdb->colorG, tdb->colorB); + +char *rawCartValue = cartOptionalString(cart, varName); +boolean hasOverride = (rawCartValue != NULL && rawCartValue[0] != '\0'); +char *colorValue = hasOverride ? rawCartValue : defaultColor; +boolean hasItemRgb = !trackDbSettingOff(tdb, "itemRgb"); printf(" 
", name); -jsInlineF("makeHighlightPicker('%s', document.getElementById('colorPicker_%s'), '%s', 'Change track color:  ', '%s');", - varName, name, name, colorValue); // id="xx" is necessary as id contains a dot +jsInlineF("makeHighlightPicker('%s', document.getElementById('colorPicker_%s'), '%s', 'Change track color:  ', '%s', '%s', %s, %s);", + varName, name, name, colorValue, defaultColor, hasItemRgb ? "true" : "false", hasOverride ? "true" : "false"); puts("
\n\n"); } void wiggleScaleDropDownJavascript(char *name) /* print some js that deactivates the min/max range if autoscaling is activated */ { struct dyString *dy = dyStringNew(1024); dyStringPrintf(dy, " $(\"[name='%s.autoScale']\").change(function()\n", name); dyStringPrintf(dy, " {\n"); dyStringPrintf(dy, " val= $(this).find(':selected').val(); \n"); dyStringPrintf(dy, " if (val!=\"use vertical viewing range setting\")\n"); dyStringPrintf(dy, " {\n"); dyStringPrintf(dy, " $(\"[name='%s.minY']\")[0].disabled=true;\n", name); dyStringPrintf(dy, " $(\"[name='%s.maxY']\")[0].disabled=true;\n", name); dyStringPrintf(dy, " $(\".%sAutoScaleDesc\").attr('style', 'color:grey;');\n", name); @@ -7882,31 +7888,30 @@ { printf("
"); filterBySetCfgUi(cart,tdb,filterBySet,FALSE, name); filterBySetFree(&filterBySet); } filterBy_t *highlightBySet = highlightBySetGet(tdb,cart,name); if (highlightBySet != NULL) { printf("
"); highlightBySetCfgUi(cart,tdb,highlightBySet,FALSE, name, TRUE); filterBySetFree(&highlightBySet); } squishyPackOption(cart, name, title, tdb); filterNameOption(cart, name, tdb); -colorTrackOption(cart, name, tdb); wigOption(cart, name, title, tdb); cfgEndBox(boxed); // N.B. scoreCfgUi maybe creates a box, so this is called after cfgEndBox // unclear what the logic is with box creation here if (startsWith("bigGenePred", tdb->type)) { char *scoreMax = trackDbSettingClosestToHome(tdb, SCORE_FILTER _MAX); int maxScore = (scoreMax ? sqlUnsigned(scoreMax):1000); scoreCfgUi(db, cart,tdb,name,title,maxScore,boxed); } } static boolean isSpeciesOn(struct cart *cart, struct trackDb *tdb, char *species, char *option, int optionSize, boolean defaultState) /* check the cart to see if species is turned off or on (default is defaultState) */ {