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.\n", MAX_CONTROL_COLUMNS - 2); hPrintf(""); hButtonWithOnClick("hgt.expandGroups", "expand all", "expand all track groups", "return setAllTrackGroupVisibility(true)"); hPrintf(""); 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(""); @@ -5045,50 +5069,49 @@ if (!hIsGsidServer()) hPrintf("",MAX_CONTROL_COLUMNS); else hPrintf("",MAX_CONTROL_COLUMNS-1); hPrintf("
"); hPrintf("\n",group->name); hPrintf("\"%s\"  ", group->name, group->name, indicatorImg, indicator,isOpen?"Collapse":"Expand"); hPrintf("\n%s", group->label); hPrintf("\n"); hPrintf("\n"); hPrintf("
\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("", url); hPrintf(" %s
", RULER_TRACK_LABEL); hPrintf("
"); 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) {