3faf76c42e6b5c97939abd34d88cb55da515418e braney Mon Jul 11 19:12:27 2011 -0700 put hub track groups up top with user tracks. diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c index ba723a1..db14d38 100644 --- src/hg/hgTracks/hgTracks.c +++ src/hg/hgTracks/hgTracks.c @@ -3761,85 +3761,110 @@ /* Determine if any member tracks are visible -- currently * recording this in the parent's visibility setting */ { tdb->visibility = tvDense; } boolean superTrackHasVisibleMembers(struct trackDb *tdb) /* Determine if any member tracks are visible -- currently * recording this in the parent's visibility setting */ { if (!tdbIsSuper(tdb)) return FALSE; return (tdb->visibility != tvHide); } +int hubCmpAlpha(const void *va, const void *vb) +/* Compare to sort hubs based on name */ +{ +const struct trackHub *a = *((struct trackHub **)va); +const struct trackHub *b = *((struct trackHub **)vb); + +return strcmp(a->shortLabel, b->shortLabel); +} + static void groupTracks(struct trackHub *hubList, struct track **pTrackList, struct group **pGroupList, int vis) /* Make up groups and assign tracks to groups. * If vis is -1, restore default groups to tracks. */ { struct group *unknown = NULL; struct group *group, *list = NULL; struct hash *hash = newHash(8); struct track *track; struct trackRef *tr; struct grp* grps = hLoadGrps(database); struct grp *grp; -float maxPriority = 0; +float minPriority = 100000; // something really large /* build group objects from database. */ for (grp = grps; grp != NULL; grp = grp->next) { /* deal with group reordering */ float priority = grp->priority; - if (priority > maxPriority) maxPriority = priority; + // we want to get the minimum priority over 1 (which is custom tracks) + if ((priority > 1.0) && (priority < minPriority)) minPriority = priority; if (withPriorityOverride) { char cartVar[512]; safef(cartVar, sizeof(cartVar), "%s.priority",grp->name); if (vis != -1) priority = (float)cartUsualDouble(cart, cartVar, grp->priority); if (priority == grp->priority) cartRemove(cart, cartVar); } /* create group object; add to list and hash */ AllocVar(group); group->name = cloneString(grp->name); group->label = cloneString(grp->label); group->defaultPriority = grp->priority; group->priority = priority; group->defaultIsClosed = grp->defaultIsClosed; slAddHead(&list, group); hashAdd(hash, grp->name, group); } grpFreeList(&grps); /* build group objects from hub */ { + int count = slCount(hubList); + + if (count) // if we have track hubs + { + slSort(&hubList, hubCmpAlpha); // alphabetize + minPriority -= 1.0; // priority is 1-based + // the idea here is to get enough room between priority 1 + // (which is custom tracks) and the group with the next + // priority number, so that the hub nestle inbetween the + // custom tracks and everything else at the top of the list + // of track groups + double priorityInc = (0.9 * minPriority) / count; + double priority = 1.0 + priorityInc; + struct trackHub *hub; for (hub = hubList; hub != NULL; hub = hub->next) { AllocVar(group); group->name = cloneString(hub->name); group->label = cloneString(hub->shortLabel); - maxPriority += 1; - group->defaultPriority = group->priority = maxPriority; + group->defaultPriority = group->priority = priority; + priority += priorityInc; slAddHead(&list, group); hashAdd(hash, group->name, group); } } + } /* Loop through tracks and fill in their groups. * If necessary make up an unknown group. */ for (track = *pTrackList; track != NULL; track = track->next) { /* handle track reordering feature -- change group assigned to track */ if (withPriorityOverride) { char *groupName = NULL; char cartVar[256]; /* belt and suspenders -- accomodate inconsistent track/trackDb * creation. Note -- with code cleanup, these default variables * could be retired, and the tdb versions used as defaults */ if (!track->defaultGroupName) @@ -5013,31 +5038,30 @@ "more compact modes.</td>\n", MAX_CONTROL_COLUMNS - 2); hPrintf("<td align='right'>"); hButtonWithOnClick("hgt.expandGroups", "expand all", "expand all track groups", "return setAllTrackGroupVisibility(true)"); hPrintf("</td></tr>"); if (!hIsGsidServer()) { cg = startControlGrid(MAX_CONTROL_COLUMNS, "left"); } else { /* 4 cols fit GSID's display better */ cg = startControlGrid(4, "left"); } - boolean isFirstNotCtGroup = TRUE; for (group = groupList; group != NULL; group = group->next) { if (group->trackList == NULL) continue; struct trackRef *tr; /* check if group section should be displayed */ char *otherState; char *indicator; char *indicatorImg; boolean isOpen = !isCollapsedGroup(group); collapseGroupGoodies(isOpen, TRUE, &indicatorImg, &indicator, &otherState); hPrintf("<TR>"); @@ -5045,50 +5069,49 @@ if (!hIsGsidServer()) hPrintf("<th align=\"left\" colspan=%d class='blueToggleBar'>",MAX_CONTROL_COLUMNS); else hPrintf("<th align=\"left\" colspan=%d class='blueToggleBar'>",MAX_CONTROL_COLUMNS-1); hPrintf("<table style='width:100%%;'><tr><td style='text-align:left;'>"); hPrintf("\n<A NAME=\"%sGroup\"></A>",group->name); hPrintf("<IMG class='toggleButton' onclick=\"return toggleTrackGroupVisibility(this, '%s');\" id=\"%s_button\" src=\"%s\" alt=\"%s\" title='%s this group'> ", group->name, group->name, indicatorImg, indicator,isOpen?"Collapse":"Expand"); hPrintf("</td><td style='text-align:center; width:90%%;'>\n<B>%s</B>", group->label); hPrintf("</td><td style='text-align:right;'>\n"); hPrintf("<input type='submit' name='hgt.refresh' value='refresh' title='Update image with your changes'>\n"); hPrintf("</td></tr></table></th>\n"); controlGridEndRow(cg); - /* First track group that is not custom track group gets ruler, + /* First track group that is not the custom track group (#1) + * or a track hub, gets the Base Position track * unless it's collapsed. */ - if (!showedRuler && isFirstNotCtGroup && + if (!showedRuler && !isHubTrack(group->name) && differentString(group->name, "user")) { char *url = trackUrl(RULER_TRACK_NAME, chromName); showedRuler = TRUE; myControlGridStartCell(cg, isOpen, group->name); hPrintf("<A HREF=\"%s\">", url); hPrintf(" %s<BR> ", RULER_TRACK_LABEL); hPrintf("</A>"); hDropListClassWithStyle("ruler", rulerMenu, sizeof(rulerMenu)/sizeof(char *), rulerMenu[rulerMode], rulerMode == tvHide ? "hiddenText" : "normalText", TV_DROPDOWN_STYLE); controlGridEndCell(cg); freeMem(url); } - if (differentString(group->name, "user")) - isFirstNotCtGroup = FALSE; /* Add supertracks to track list, sort by priority and * determine if they have visible member tracks */ groupTrackListAddSuper(cart, group); /* Display track controls */ for (tr = group->trackList; tr != NULL; tr = tr->next) { struct track *track = tr->track; if (tdbIsSuperTrackChild(track->tdb)) /* don't display supertrack members */ continue; myControlGridStartCell(cg, isOpen, group->name); if (track->hasUi) {