7d9e5c172d1b2ae2de50b00f344e199006b8ffab
markd
  Sun Apr 27 23:24:19 2025 -0700
Fixed mangled composite track UI when score filtering is disabled.  This caused form and table begin/end mismatches.  Also a little bit of movement of some inconsistent code to make it easier to understand where score fitler config is called.

diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index d053ae2d17d..89e85d84370 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -4664,30 +4664,33 @@
 safef(option, sizeof(option), "%s.%s", name, MAX_Y );
 cgiMakeDoubleVarWithLimits(option, maxY, "Range max", 0, NO_VALUE, NO_VALUE);
 /*
 printf("<TR valign=middle><th align=right>Drawing method:</th><td align=left>");
 safef(option, sizeof(option), "%s.%s", name, POPMETHOD);
 char *popMethodVal = cartOrTdbString(cart, tdb, "popMethod", NULL);
         
 cgiMakeDropListFull(option, popMethodLabels, popMethodValues,
     ArraySize(popMethodValues), popMethodVal, NULL, NULL);
     */
 
 puts("</td></TR>");
 
 printf("</TABLE>");
 cfgEndBox(boxed);
+// N.B. scoreCfgUi maybe creates a box, so this is called after cfgEndBox
+// unclear what the logic is with box creation here
+scoreCfgUi(db, cart,tdb,name,title,1000,boxed);
 }
 
 void labelMakeCheckBox(struct cart *cart, struct trackDb *tdb, char *sym, char *desc,
                        boolean defaultOn)
 /* add a checkbox for the user to select a component of a label (e.g. ID, name, other info).
  * NOTE: This does not have a track name argument, so the correct tdb must be passed in:
  * if setting is at composite level, then pass in composite tdb, likewise for view. */
 {
 char suffix[512];
 safef(suffix, sizeof(suffix), "label.%s", sym);
 boolean option = cartUsualBooleanClosestToHome(cart, tdb, FALSE, suffix, defaultOn);
 char cartVar[1024];
 safef(cartVar, sizeof cartVar, "%s.%s", tdb->track, suffix);
 cgiMakeCheckBox(cartVar, option);
 printf(" %s&nbsp;&nbsp;&nbsp;", desc);
@@ -4939,82 +4942,64 @@
     }
 
 // Cfg could be explicitly blocked, but if tdb is example subtrack
 // then blocking should have occurred before we got here.
 if (!tdbIsSubtrack(tdb) && trackDbSettingBlocksConfiguration(tdb,FALSE))
     return;
 
 // composite/view must pass in example subtrack
 // NOTE: if subtrack types vary then there shouldn't be cfg at composite/view level!
 while (tdb->subtracks)
 tdb = tdb->subtracks;
 
 switch(cType)
     {
     case cfgBedScore:
-			{
-			char *scoreMax = trackDbSettingClosestToHome(tdb, SCORE_FILTER _MAX);
-			int maxScore = (scoreMax ? sqlUnsigned(scoreMax):1000);
-			scoreCfgUi(db, cart,tdb,prefix,title,maxScore,boxed);
-
-            if(startsWith("bigBed", tdb->type))
-                {
-                labelCfgUi(db, cart, tdb, prefix);
-                mergeSpanCfgUi(cart, tdb, prefix);
-                wigOption(cart, prefix, title, tdb);
-                }
-			}
+                        bedScoreCfgUi(db,cart,tdb,prefix,title,boxed);
 			break;
     case cfgPeak:
 			encodePeakCfgUi(cart,tdb,prefix,title,boxed);
 			break;
     case cfgWig:        wigCfgUi(cart,tdb,prefix,title,boxed);
 			break;
     case cfgWigMaf:     wigMafCfgUi(cart,tdb,prefix,title,boxed, db);
 			break;
     case cfgGenePred:   genePredCfgUi(db, cart,tdb,prefix,title,boxed);
-                        if(startsWith("bigGenePred", tdb->type))
-                            {
-                            char *scoreMax = trackDbSettingClosestToHome(tdb, SCORE_FILTER _MAX);
-                            int maxScore = (scoreMax ? sqlUnsigned(scoreMax):1000);
-                            scoreCfgUi(db, cart,tdb,prefix,title,maxScore,boxed);
-                            }
 			break;
     case cfgChain:      chainCfgUi(db,cart,tdb,prefix,title,boxed, NULL);
 			break;
     case cfgNetAlign:   netAlignCfgUi(db,cart,tdb,prefix,title,boxed);
 			break;
     case cfgBedFilt:    bedFiltCfgUi(cart,tdb,prefix,title, boxed);
 			break;
     case cfgBam:        bamCfgUi(cart, tdb, prefix, title, boxed);
 			break;
     case cfgVcf:        vcfCfgUi(cart, tdb, prefix, title, boxed);
 			break;
     case cfgLong:       longRangeCfgUi(cart, tdb, prefix, title, boxed);
 			break;
     case cfgSnake:      snakeCfgUi(cart, tdb, prefix, title, boxed);
 			break;
     case cfgPsl:        pslCfgUi(db,cart,tdb,prefix,title,boxed);
                         break;
     case cfgBarChart:   barChartCfgUi(db,cart,tdb,prefix,title,boxed);
                         break;
     case cfgInteract:   interactCfgUi(db,cart,tdb,prefix,title,boxed);
                         break;
     case cfgBigRmsk:    bigRmskCfgUi(db,cart,tdb,prefix,title,boxed);
                         break;
     case cfgLollipop:   lollyCfgUi(db,cart,tdb,prefix,title,boxed);
-			scoreCfgUi(db, cart,tdb,prefix,title,1000,boxed);
                         break;
     case cfgHic:        hicCfgUi(db,cart,tdb,prefix,title,boxed);
                         break;
     case cfgBigDbSnp:   bigDbSnpCfgUi(db, cart, tdb, prefix, title, boxed);
                         break;
     default:            warn("Track type is not known to multi-view composites. type is: %d ",
 			     cType);
 			break;
     }
 }
 
 char *encodeRestrictionDate(char *db,struct trackDb *trackDb,boolean excludePast)
 // Create a string for ENCODE restriction date of this track
 // if return is not null, then free it after use
 {
@@ -7093,30 +7078,31 @@
         jsIncludeFile("hui.js",NULL);
     if (!didHighlightSelector)
         printHighlightColorPicker(cart, tdb);
 
     if (!isBoxOpened)   // Note filterBy boxes are not double "boxed",
         printf("<BR>"); // if there are no other filters
     highlightBySetCfgUi(cart,tdb,highlightBySet,TRUE, name, TRUE);
     filterBySetFree(&highlightBySet);
     skipScoreFilter = TRUE;
     }
 
 boolean scoreFilterOk = (trackDbSettingClosestToHome(tdb, NO_SCORE_FILTER) == NULL) && !skipScoreFilter;
 boolean glvlScoreMin = (trackDbSettingClosestToHome(tdb, GRAY_LEVEL_SCORE_MIN) != NULL);
 if (! (scoreFilterOk || glvlScoreMin))
    {
+   if (isBoxOpened)
       cfgEndBox(boxed);
    return;
    }
 
 boxed = cfgBeginBoxAndTitle(tdb, boxed, title);
 
 if (scoreFilterOk)
     {
     int minLimit=0,maxLimit=maxScore,minVal=0,maxVal=maxScore;
     getScoreIntRangeFromCart(cart,tdb,parentLevel,SCORE_FILTER,&minLimit,&maxLimit,
                                                                &minVal,  &maxVal);
 
     boolean filterByRange = trackDbSettingClosestToHomeOn(tdb, SCORE_FILTER _BY_RANGE);
     if (filterByRange)
         {
@@ -7767,30 +7753,45 @@
 option = cartUsualBoolean(cart, varName, FALSE);
 cgiMakeCheckBox(varName, option);
 printf(" %s&nbsp;&nbsp;&nbsp;", "pseudogenes");
 
 printf("<BR><B>Tagged Sets:</B> ");
 safef(varName, sizeof(varName), "%s.show.set", tdb->track);
 char *setString = cartUsualString(cart, varName, "basic");
 cgiMakeRadioButton(varName, "MANE_Select", sameString(setString, "MANE_Select"));
 printf(" %s&nbsp;&nbsp;&nbsp;", "MANE only");
 cgiMakeRadioButton(varName, "basic", sameString(setString, "basic"));
 printf(" %s&nbsp;&nbsp;&nbsp;", "BASIC only");
 cgiMakeRadioButton(varName, "all", sameString(setString, "all"));
 printf(" %s&nbsp;&nbsp;&nbsp;", "All");
 }
 
+void bedScoreCfgUi(char *db, struct cart *cart, struct trackDb *tdb, char *name, char *title, boolean boxed)
+/* Put up bed-specific score controls */
+{
+char *scoreMax = trackDbSettingClosestToHome(tdb, SCORE_FILTER _MAX);
+int maxScore = (scoreMax ? sqlUnsigned(scoreMax):1000);
+scoreCfgUi(db, cart,tdb,name,title,maxScore,boxed);
+
+if(startsWith("bigBed", tdb->type))
+    {
+    labelCfgUi(db, cart, tdb, name);
+    mergeSpanCfgUi(cart, tdb, name);
+    wigOption(cart, name, title, tdb);
+    }
+}
+
 void genePredCfgUi(char *db, struct cart *cart, struct trackDb *tdb, char *name, char *title, boolean boxed)
 /* Put up genePred-specific controls */
 {
 char varName[64];
 boolean parentLevel = isNameAtParentLevel(tdb,name);
 char *geneLabel = cartUsualStringClosestToHome(cart, tdb,parentLevel, "label", "gene");
 boxed = cfgBeginBoxAndTitle(tdb, boxed, title);
 
 labelCfgUi(db, cart, tdb, name);
 boolean isGencode3 = trackDbSettingOn(tdb, "isGencode3");
 
 if (sameString(name, "acembly"))
     {
     char *acemblyClass = cartUsualStringClosestToHome(cart,tdb,parentLevel,"type",
                                                       acemblyEnumToString(0));
@@ -7848,30 +7849,38 @@
     filterBySetFree(&filterBySet);
     }
 filterBy_t *highlightBySet = highlightBySetGet(tdb,cart,name);
 if (highlightBySet != NULL)
     {
     printf("<BR>");
     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) */
 {
 boolean parentLevel = isNameAtParentLevel(tdb,option);
 if (*option == '\0')
     safef(option, optionSize, "%s.%s", tdb->track, species);
 else
     {
     char *suffix = option + strlen(option);
     int suffixSize = optionSize - strlen(option);
     safef(suffix,suffixSize,".%s",species);
     }
 return cartUsualBooleanClosestToHome(cart,tdb, parentLevel, species,defaultState);