");
-}
-
-static void pruneRedundantCartVis(struct track *trackList)
-/* When the config page or track form has been submitted, there usually
- * are many track visibility cart variables that have not been changed
- * from the default. To keep down cart bloat, prune those out before we
- * save the cart. changeTrackVis does this too, but this is for the
- * more common case where track visibilities are tweaked. */
-{
-struct track *track;
-if (measureTiming)
- uglyTime("Done with trackForm");
-for (track = trackList; track != NULL; track = track->next)
- {
- char *cartVis = cartOptionalString(cart, track->track);
- if (cartVis != NULL && hTvFromString(cartVis) == track->tdb->visibility)
- cartRemove(cart, track->track);
- }
-if (measureTiming)
- {
- uglyTime("Pruned redundant vis from cart");
- }
-}
-
-static int getMaxWindowToDraw(struct trackDb *tdb)
-/* If trackDb setting maxWindowToDraw exists and is a sensible size, return it, else 0. */
-{
-if (tdb == NULL)
- return 0;
-char *maxWinToDraw = trackDbSettingClosestToHome(tdb, "maxWindowToDraw");
-if (isNotEmpty(maxWinToDraw))
- {
- unsigned maxWTD = sqlUnsigned(maxWinToDraw);
- if (maxWTD > 1)
- return maxWTD;
- }
-return 0;
-}
-
-static void drawMaxWindowWarning(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg,
- int xOff, int yOff, int width, MgFont *font, Color color,
- enum trackVisibility vis)
-/* This is a stub drawItems handler to be swapped in for the usual drawItems when the window
- * size is larger than the threshold specified by trackDb setting maxWindowToDraw. */
-{
-int maxWinToDraw = getMaxWindowToDraw(tg->tdb);
-char commafied[256];
-sprintLongWithCommas(commafied, maxWinToDraw);
-char message[512];
-safef(message, sizeof(message), "zoom in to <= %s bases to view items", commafied);
-Color yellow = hvGfxFindRgb(hvg, &undefinedYellowColor);
-hvGfxBox(hvg, xOff, yOff, width, tg->heightPer, yellow);
-hvGfxTextCentered(hvg, xOff, yOff, width, tg->heightPer, MG_BLACK, font, message);
-}
-
-static void dontLoadItems(struct track *tg)
-/* No-op loadItems when we aren't going to try. */
-{
-}
-
-static void checkMaxWindowToDraw(struct track *tg)
-/* If (winEnd - winStart) > trackDb setting maxWindowToDraw, force track to a dense line
- * that will ask the user to zoom in closer to see track items and return TRUE so caller
- * can skip loading items. */
-{
-int maxWinToDraw = getMaxWindowToDraw(tg->tdb);
-if (tdbIsComposite(tg->tdb))
- {
- struct track *subtrack;
- for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next)
- {
- if (!isSubtrackVisible(subtrack))
- continue;
- maxWinToDraw = getMaxWindowToDraw(subtrack->tdb);
- if (maxWinToDraw > 1 && (winEnd - winStart) > maxWinToDraw)
- {
- subtrack->loadItems = dontLoadItems;
- subtrack->drawItems = drawMaxWindowWarning;
- subtrack->limitedVis = tvDense;
- subtrack->limitedVisSet = TRUE;
- }
- }
- }
-else if (maxWinToDraw > 1 && (winEnd - winStart) > maxWinToDraw)
- {
- tg->loadItems = dontLoadItems;
- tg->drawItems = drawMaxWindowWarning;
- tg->limitedVis = tvDense;
- tg->limitedVisSet = TRUE;
- }
-}
-
-#if defined(CONTEXT_MENU) || defined(TRACK_SEARCH)
-static void trackJson(struct dyString *trackDbJson, struct track *track, int count)
-{
-// add entry for given track to the trackDbJson string
-if(count)
- dyStringAppend(trackDbJson, "\n,");
-dyStringPrintf(trackDbJson, "\t%s: {", track->track);
-if(tdbIsSuperTrackChild(track->tdb) || tdbIsCompositeChild(track->tdb))
- dyStringPrintf(trackDbJson, "\n\t\tparentTrack: '%s',", track->tdb->parent->track);
-dyStringPrintf(trackDbJson, "\n\t\ttype: '%s',", track->tdb->type);
-if(sameWord(track->tdb->type, "remote") && trackDbSetting(track->tdb, "url") != NULL)
- dyStringPrintf(trackDbJson, "\n\t\turl: '%s',", trackDbSetting(track->tdb, "url"));
-dyStringPrintf(trackDbJson, "\n\t\tshortLabel: '%s',\n\t\tlongLabel: '%s',\n\t\tcanPack: %d,\n\t\tvisibility: %d\n\t}",
- javaScriptLiteralEncode(track->shortLabel), javaScriptLiteralEncode(track->longLabel), track->canPack, track->limitedVis);
-}
-#endif/// defined(CONTEXT_MENU) || defined(TRACK_SEARCH)
-
-void printTrackInitJavascript(struct track *trackList)
-{
-hPrintf("\n", hgtJsCommand, hgtJsCommand);
-hPrintf("\n");
-}
-
-void jsCommandDispatch(char *command, struct track *trackList)
-/* Dispatch a command sent to us from some javaScript event.
- * This gets executed after the track list is built, but before
- * the track->loadItems methods are called. */
-{
-if (startsWithWord("makeItems", command))
- makeItemsJsCommand(command, trackList, trackHash);
-else
- warn("Unrecognized jsCommand %s", command);
-}
-
-void subtrackVisCartCleanup(struct track *trackList,struct cart *newCart,struct hash *oldVars)
-/* When composite/view vis changes, remove subtrack specific vis */
-{
-struct track *track = trackList;
-for (;track != NULL; track = track->next)
- {
- if(!tdbIsComposite(track->tdb))
- continue;
- boolean compositeWide = cartValueHasChanged(newCart,oldVars,track->track,TRUE);
-
- boolean hasViews = FALSE;
- struct trackDb *tdbView = track->tdb->subtracks;
- for (;tdbView != NULL; tdbView = tdbView->next)
- {
- char * view = NULL;
- if (!tdbIsView(tdbView,&view))
- break;
-
- hasViews = TRUE;
- boolean viewLevel = FALSE;
- if(!compositeWide)
- {
- char settingName[512]; // wgEncodeOpenChromChip.Peaks.vis
- safef(settingName,sizeof(settingName),"%s.%s.vis",track->track,view);
- viewLevel = cartValueHasChanged(newCart,oldVars,settingName,TRUE);
- }
- if(compositeWide || viewLevel)
- cartRemoveFromTdbTree(newCart,tdbView,NULL,TRUE); // clean up children, skipping view
- }
- if (compositeWide && !hasViews)
- cartRemoveFromTdbTree(newCart,track->tdb,NULL,TRUE); // clean up children, skipping composite
- }
-}
-
-void doTrackForm(char *psOutput, struct tempName *ideoTn)
-/* Make the tracks display form with the zoom/scroll buttons and the active
- * image. If the ideoTn parameter is not NULL, it is filled in if the
- * ideogram is created. */
-{
-struct group *group;
-struct track *track;
-char *freezeName = NULL;
-boolean hideAll = cgiVarExists("hgt.hideAll");
-boolean defaultTracks = cgiVarExists("hgt.reset");
-boolean showedRuler = FALSE;
-boolean showTrackControls = cartUsualBoolean(cart, "trackControlsOnMain", TRUE);
-long thisTime = 0, lastTime = 0;
-char *clearButtonJavascript;
-#if defined(CONTEXT_MENU) || defined(TRACK_SEARCH)
-struct dyString *trackDbJson = newDyString(1000);
-int trackDbJsonCount = 1;
-dyStringPrintf(trackDbJson, "\n");
-if(!trackImgOnly)
- hPrintf(dyStringContents(trackDbJson));
-#endif/// defined(CONTEXT_MENU) || defined(TRACK_SEARCH)
-
-printTrackInitJavascript(trackList);
-
-/* Generate two lists of hidden variables for track group visibility. Kludgy,
- but required b/c we have two different navigation forms on this page, but
- we want open/close changes in the bottom form to be submitted even if the user
- submits via the top form. */
-struct dyString *trackGroupsHidden1 = newDyString(1000);
-struct dyString *trackGroupsHidden2 = newDyString(1000);
-for (group = groupList; group != NULL; group = group->next)
- {
- if (group->trackList != NULL)
- {
- int looper;
- for(looper=1;looper<=2;looper++)
- {
- boolean isOpen = !isCollapsedGroup(group);
- char buf[1000];
- safef(buf, sizeof(buf), "\n", collapseGroupVar(group->name), collapseGroupVar(group->name), looper, isOpen ? "0" : "1");
- dyStringAppend(looper == 1 ? trackGroupsHidden1 : trackGroupsHidden2, buf);
- }
- }
- }
-
-#ifdef IMAGEv2_DRAG_SCROLL
-if(theImgBox)
- {
- // If a portal was established, then set the global dimensions back to the portal size
- if(imgBoxPortalDimensions(theImgBox,NULL,NULL,NULL,NULL,&winStart,&winEnd,&(tl.picWidth),NULL))
- {
- winBaseCount = winEnd - winStart;
- insideWidth = tl.picWidth-gfxBorder-insideX;
- }
- }
-#endif//def IMAGEv2_DRAG_SCROLL
-/* Center everything from now on. */
-hPrintf("
\n");
-
-
-if (!hideControls)
- {
- /* set white-space to nowrap to prevent buttons from wrapping when screen is
- * narrow */
- hPrintf("
\n");
- hotLinks();
-
- /* Show title . */
- freezeName = hFreezeFromDb(database);
- if(freezeName == NULL)
- freezeName = "Unknown";
- hPrintf("");
- if (startsWith("zoo",database) )
- {
- hPrintf("%s %s on %s June 2002 Assembly %s target1",
- organization, browserName, organism, freezeName);
- }
- else
- {
- if (sameString(organism, "Archaea"))
- {
- hPrintf("%s %s on Archaeon %s Assembly",
- organization, browserName, freezeName);
- }
- else
- {
- if (stringIn(database, freezeName))
- hPrintf("%s %s on %s %s Assembly",
- organization, browserName, organism, freezeName);
- else
- hPrintf("%s %s on %s %s Assembly (%s)",
- organization, browserName, organism, freezeName, database);
- }
- }
- hPrintf(" \n");
-
- /* This is a clear submit button that browsers will use by default when enter is pressed in position box. */
- hPrintf("");
- /* Put up scroll and zoom controls. */
-#ifndef USE_NAVIGATION_LINKS
- hWrites("move ");
- hButtonWithMsg("hgt.left3", "<<<", "move 95% to the left");
- hButtonWithMsg("hgt.left2", " <<", "move 47.5% to the left");
- hButtonWithMsg("hgt.left1", " < ", "move 10% to the left");
- hButtonWithMsg("hgt.right1", " > ", "move 10% to the right");
- hButtonWithMsg("hgt.right2", ">> ", "move 47.5% to the right");
- hButtonWithMsg("hgt.right3", ">>>", "move 95% to the right");
- hWrites(" zoom in ");
- /* use button maker that determines padding, so we can share constants */
- topButton("hgt.in1", ZOOM_1PT5X);
- topButton("hgt.in2", ZOOM_3X);
- topButton("hgt.in3", ZOOM_10X);
- topButton("hgt.inBase", ZOOM_BASE);
- hWrites(" zoom out ");
- topButton("hgt.out1", ZOOM_1PT5X);
- topButton("hgt.out2", ZOOM_3X);
- topButton("hgt.out3", ZOOM_10X);
- hWrites(" \n");
-#endif//ndef USE_NAVIGATION_LINKS
-
- if (showTrackControls)
- {
- /* Break into a second form so that zooming and scrolling
- * can be done with a 'GET' so that user can back up from details
- * page without Internet Explorer popping up an annoying dialog.
- * Do rest of page as a 'POST' so that the ultra-long URL from
- * all the track controls doesn't break things. IE URL limit
- * is 2000 bytes, but some firewalls impose a ~1000 byte limit.
- * As a side effect of breaking up the page into two forms
- * we need to repeat the position in a hidden variable here
- * so that zoom/scrolling always has current position to work
- * from. */
- hPrintf("", chromName, winStart+1, winEnd);
- hPrintf("\n%s", trackGroupsHidden1->string);
- hPrintf("\n");
- hPrintf("