64b2c5bd9ab0e2bd59360c39298ae54e97615407 kate Thu Sep 26 13:30:43 2019 -0700 Add UI control to hide empty subtracks. refs #23365 diff --git src/hg/lib/hui.c src/hg/lib/hui.c index fe37255..c103ec1 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -4988,57 +4988,127 @@ } else settings->bgColorIx = COLOR_BG_DEFAULT_IX; // Start with non-default allows alternation puts("'>"); dyStringFree(&dyHtml) // save count of subtracks for use by footer code int subCount = slCount(subtrackRefList); printSubtrackTableHeader(parentTdb, subtrackRefList, settings); printSubtrackTableBody(parentTdb, subtrackRefList, settings, cart); printSubtrackTableFooter(subCount, settings); puts("</TABLE>"); } +boolean compositeHideEmptySubtracksSetting(struct trackDb *tdb, boolean *retDefault, + char **retMultiBedFile, char **retSubtrackIdFile) +/* Parse hideEmptySubtracks setting + * Format: hideEmptySubtracks on|default + * or + * hideEmptySubtracks on|default multiBed.bed subtrackIds.tab + * where multiBed.bed is a bed3Sources bigBed, generated with bedtools multiinter + * post-processed by UCSC multiBed.pl tool + * subtrackIds.tab is a tab-sep file: id subtrackName + * + * Return TRUE if set to true/on/default. retDefault is TRUE if set default, o/w FALSE + */ +{ +if (!tdbIsComposite(tdb)) + return FALSE; +char *hideEmpties = trackDbSetting(tdb, SUBTRACK_HIDE_EMPTIES); +if (!hideEmpties) + return FALSE; +char *orig = cloneString(hideEmpties); +char *words[3]; +int wordCount = chopByWhite(hideEmpties, words, ArraySize(words)); +char *mode = words[0]; +if (differentString(mode, "on") && differentString(mode, "true") && + differentString(mode, "default")) + { + warn("Track %s %s setting invalid: %s", tdb->track, SUBTRACK_HIDE_EMPTIES, orig); + return FALSE; + } +boolean deflt = sameString(mode, "default") ? TRUE : FALSE; +if (retDefault) + *retDefault = deflt; + +if (wordCount == 1) + return TRUE; +if (wordCount != 3) + { + warn("Track %s %s setting invalid: %s", tdb->track, SUBTRACK_HIDE_EMPTIES, orig); + return FALSE; + } +// multi-bed specified (to speed display) +if (retMultiBedFile) + *retMultiBedFile = cloneString(hReplaceGbdb(words[1])); +if (retSubtrackIdFile) + *retSubtrackIdFile = cloneString(words[2]); +return TRUE; +} + +boolean compositeHideEmptySubtracks(struct cart *cart, struct trackDb *tdb, + char **retMutiBedFile, char **retSubtrackIdFile) +/* Parse hideEmptySubtracks setting and check cart + * Return TRUE if we should hide empties + */ +{ +boolean deflt = FALSE; +if (!compositeHideEmptySubtracksSetting(tdb, &deflt, retMutiBedFile, retSubtrackIdFile)) + return FALSE; +char buf[128]; +safef(buf, sizeof buf, "%s.%s", tdb->track, SUBTRACK_HIDE_EMPTIES); +return cartUsualBoolean(cart, buf, deflt); +} + static void compositeUiSubtracks(char *db, struct cart *cart, struct trackDb *parentTdb) // Display list of subtracks and descriptions with checkboxes to control visibility and // possibly other nice things including links to schema and metadata and a release date. { char buffer[SMALLBUF]; struct trackDb *subtrack; // Get list of leaf subtracks to work with struct slRef *subtrackRef, *subtrackRefList = trackDbListGetRefsToDescendantLeaves(parentTdb->subtracks); membersForAll_t* membersForAll = membersForAllSubGroupsGet(parentTdb,NULL); sortOrder_t* sortOrder = sortOrderGet(cart, parentTdb); char *displaySubs = NULL; int subCount = slCount(subtrackRefList); if (subCount > LARGE_COMPOSITE_CUTOFF && membersForAll->dimensions != NULL) { // ignore displaySubtracks setting for large composites with a matrix as // matrix effectively shows all safef(buffer, SMALLBUF,"%s.displaySubtracks", parentTdb->track); displaySubs = cartUsualString(cart, buffer,"some"); // track specific defaults to only selected } else { displaySubs = cartUsualString(cart, "displaySubtracks", "all"); // browser wide defaults to all } boolean displayAll = sameString(displaySubs, "all"); +boolean hideSubtracksDefault; +if (compositeHideEmptySubtracksSetting(parentTdb, &hideSubtracksDefault, NULL, NULL)) + { + printf("<BR><B>Hide empty subtracks:</B> "); + char buf[128]; + safef(buf, sizeof buf, "%s.%s", parentTdb->track, SUBTRACK_HIDE_EMPTIES); + cgiMakeCheckBox(buf, hideSubtracksDefault); + } + // Table wraps around entire list so that "Top" link can float to the correct place. cgiDown(0.7); printf("<table><tr><td class='windowSize'>"); printf("<A NAME='DISPLAY_SUBTRACKS'></A>"); if (sortOrder != NULL) { // First table row contains the display "selected/visible" or "all" radio buttons // NOTE: list subtrack radio buttons are inside tracklist table header if // there are no sort columns. The reason is to ensure spacing of lines // column headers when the only column header is "Restricted Until" printSubtrackListRadioButtons(parentTdb->track, subCount, displayAll); if (membersHaveMatrix(membersForAll)) makeTopLink(parentTdb); printf("</td></tr></table>"); }