86a4a9bd5fd7e7be7bb912172b862485c0c7bb4e galt Thu Apr 12 11:03:57 2018 -0700 Need to set limitedVis consistently across all windows after loading tracks. fixes #21267 diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c index 6aa2777..89474c8 100644 --- src/hg/hgTracks/hgTracks.c +++ src/hg/hgTracks/hgTracks.c @@ -1458,31 +1458,30 @@ static void doLabelNextItemButtons(struct track *track, struct track *parentTrack, struct hvGfx *hvg, MgFont *font, int y, int trackPastTabX, int trackPastTabWidth, int fontHeight, int insideHeight, Color labelColor) /* If the track allows label next-item buttons (next gene), draw them. */ /* The button will cause hgTracks to run again with the additional CGI */ /* vars nextItem=trackName or prevItem=trackName, which will then */ /* signal the browser to find the next thing on the track before it */ /* does anything else. */ { int portWidth = fullInsideWidth; int portX = fullInsideX; // If a portal was established, then set the portal dimensions long portalStart,chromStart; double basesPerPixel; -// TODO GALT need to tweak it still for virtchrom stuff, e.g. maybe change some var names or types to long if (theImgBox && imgBoxPortalDimensions(theImgBox,&chromStart,NULL,NULL,NULL,&portalStart,NULL, &portWidth,&basesPerPixel)) { portX = (int)((portalStart - chromStart) / basesPerPixel); portX += gfxBorder; if (withLeftLabels) portX += tl.leftLabelWidth + gfxBorder; portWidth = portWidth-gfxBorder-insideX; } int arrowWidth = insideHeight; int arrowButtonWidth = arrowWidth + 2 * NEXT_ITEM_ARROW_BUFFER; int rightButtonX = portX + portWidth - arrowButtonWidth - 1; char buttonText[256]; Color fillColor = lightGrayIndex(); @@ -4722,31 +4721,33 @@ // but before things are checked for overflow or limitedVis? // The fixed non-overflow tracks like knownGene used to initialize // ss and track height during loadItems(). That was delayed // because we now need all windows to be fully loaded before // calculating their joint ss layout and height. // set heights and visibilities. struct window *window = NULL; for(window=windows;window;window=window->next) { setGlobalsFromWindow(window); trackList = window->trackList; for (track = trackList; track != NULL; track = track->next) { if (tdbIsCompositeChild(track->tdb)) // When single track is requested via AJAX, + { limitedVisFromComposite(track); // it could be a subtrack + } else { limitVisibility(track); } if (tdbIsComposite(track->tdb)) { struct track *subtrack; for (subtrack = track->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (!isSubtrackVisible(subtrack)) continue; // subtrack vis can be explicit or inherited from composite/view. // Then it could be limited because of pixel height @@ -5350,32 +5351,30 @@ (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot if (isCenterLabelConditional(track)) // sometimes calls track height, especially when no data there { imgTrackUpdateCenterLabelSeen(curImgTrack,isCenterLabelConditionallySeen(track) ? clNowSeen : clNotSeen); } } if (trackShouldUseAjaxRetrieval(track)) { y += REMOTE_TRACK_HEIGHT; } else { int savey = y; // GALT y = doCenterLabels(track, track, hvg, font, y, fullInsideWidth); // calls track height - // TODO GALT why do I just pass track here instead of parentTrack? Did I lose something? - // have to look at old code to see. y = savey + flatTrack->maxHeight; } } hvGfxUnclip(hvg); setGlobalsFromWindow(windows); // first window } /* Draw tracks. */ { // brace allows local vars long lastTime = 0; @@ -5469,95 +5468,89 @@ if (yEnd != y) warn("Slice height for track %s does not add up. Expecting %d != %d actual", track->shortLabel, yEnd - yStart - 1, y - yStart); } calcWiggleOrdering(cart, flatTracks); y++; } /* post draw tracks leftLabels */ /* if a track can draw its left labels, now is the time since it * knows what exactly happened during drawItems */ -// TODO GALT Parellelize or not? if (withLeftLabels) { y = yAfterRuler; for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next) { track = flatTrack->track; if (track->limitedVis == tvHide) continue; if (theImgBox) { // side label slice of tracks - // ORIG sliceHeight = trackPlusLabelHeight(track, fontHeight); sliceHeight = flatTrack->maxHeight; sliceOffsetY = y; curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL); curSlice = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL, sliceWidth[stSide],sliceHeight, sliceOffsetX[stSide],sliceOffsetY); (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot } if (trackShouldUseAjaxRetrieval(track)) y += REMOTE_TRACK_HEIGHT; #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL else if (track->drawLeftLabels != NULL && (theImgBox == NULL || track->limitedVis == tvDense)) #else ///ndef IMAGEv2_NO_LEFTLABEL_ON_FULL else if (track->drawLeftLabels != NULL) #endif ///ndef IMAGEv2_NO_LEFTLABEL_ON_FULL - { // TODO parallelize? + { setGlobalsFromWindow(windows); y = doOwnLeftLabels(track, hvgSide, font, y); setGlobalsFromWindow(windows); // first window } else - // ORIG y += trackPlusLabelHeight(track, fontHeight); y += flatTrack->maxHeight; } } /* Make map background. */ y = yAfterRuler; for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next) { track = flatTrack->track; if (track->limitedVis != tvHide) { if (theImgBox) { // Set imgTrack in case any map items will be set - // ORIG sliceHeight = trackPlusLabelHeight(track, fontHeight); sliceHeight = flatTrack->maxHeight; sliceOffsetY = y; curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL); } - // TODO Parallelize? setGlobalsFromWindow(windows); // first window doTrackMap(track, hvg, y, fontHeight, trackPastTabX, trackPastTabWidth); - // ORIG y += trackPlusLabelHeight(track, fontHeight); y += flatTrack->maxHeight; } } /* Finish map. */ hPrintf("</MAP>\n"); // turn off inPlaceUpdate when rows in imgTbl can arbitrarily reappear and disappear (see redmine #7306 and #6944) jsonObjectAdd(jsonForClient, "inPlaceUpdate", newJsonBoolean(withLeftLabels && withCenterLabels)); jsonObjectAdd(jsonForClient, "rulerClickHeight", newJsonNumber(rulerClickHeight)); if(newWinWidth) { jsonObjectAdd(jsonForClient, "newWinWidth", newJsonNumber(newWinWidth)); } @@ -6745,31 +6738,30 @@ /* or maybe errabort ? */ label[3] = 0; len = 4; } if (len % 2 != 0) paddedLabel[3] = 0; if (len == strlen(paddedLabel)) strcpy(paddedLabel, label); else { int i; for (i=0; i<len; i++) paddedLabel[i+1] = label[i]; } hButtonWithOnClick(var, paddedLabel, NULL, "return imageV2.navigateButtonClick(this);"); -// TODO GALT could consider trying to give these all the same class and then attach handlers at the class level. } void limitSuperTrackVis(struct track *track) /* Limit track visibility by supertrack parent */ { if (tdbIsSuperTrackChild(track->tdb)) { assert(track->tdb->parent != NULL); if (sameString("hide", cartUsualString(cart, track->tdb->parent->track, track->tdb->parent->isShow ? "show" : "hide"))) track->visibility = tvHide; } } struct track *rFindTrackWithTable(char *tableName, struct track *trackList) @@ -7477,30 +7469,54 @@ } } boolean windowsHaveMultipleChroms() /* Are there multiple different chromosomes in the windows list? */ { struct window *window; for (window=windows->next; window; window=window->next) { if (!sameString(window->chromName,windows->chromName)) return TRUE; } return FALSE; } +static void setSharedLimitedVisAcrossWindows(struct track *track) +/* Look for lowest limitedVis across all windows + * if found, set all windows to same lowest limited vis. */ +{ +enum trackVisibility sharedVis = 99; +struct track *tg; +for (tg=track; tg; tg=tg->nextWindow) + { + if (tg->limitedVisSet) + { + if (tg->limitedVis < sharedVis) + sharedVis = tg->limitedVis; + } + } +if (sharedVis != 99) + { + for (tg=track; tg; tg=tg->nextWindow) + { + tg->limitedVis = sharedVis; + tg->limitedVisSet = TRUE; + } + } +} + static void setSharedErrorsAcrossWindows(struct track *track) /* Look for network errors across all windows * if found, set all windows to same errMsg and set bigWarn track handlers. */ { char *sharedErrMsg = NULL; struct track *tg; for (tg=track; tg; tg=tg->nextWindow) { if (!sharedErrMsg && tg->networkErrMsg) { sharedErrMsg = tg->networkErrMsg; break; } } if (sharedErrMsg) @@ -7837,43 +7853,54 @@ // TODO does this work for subtracks or parents/children? } } if (measureTiming) { thisTime = clock1000(); track->loadTime = thisTime - lastTime; } } } } if (ptMax > 0) { - // TODO GALT parallel actually not sure if anything to worry about here /* wait for remote parallel load to finish */ remoteParallelLoadWait(atoi(cfgOptionDefault("parallelFetch.timeout", "90"))); // wait up to default 90 seconds. if (measureTiming) measureTime("Waiting for parallel (%d threads for %d tracks) remote data fetch", ptMax, pfdListCount); } } trackLoadingInProgress = FALSE; setGlobalsFromWindow(windows); // first window // restore globals trackList = windows->trackList; // restore track list +// Some loadItems() calls will have already set limitedVis. +// Look for lowest limitedVis across all windows +// if found, set all windows to same lowest limitedVis +for (track = trackList; track != NULL; track = track->next) + { + setSharedLimitedVisAcrossWindows(track); + struct track *sub; + for (sub=track->subtracks; sub; sub=sub->next) + { + setSharedLimitedVisAcrossWindows(sub); + } + } // Look for network errors across all windows // if found, set all windows to same errMsg and set bigWarn track handlers. for (track = trackList; track != NULL; track = track->next) { setSharedErrorsAcrossWindows(track); struct track *sub; for (sub=track->subtracks; sub; sub=sub->next) { setSharedErrorsAcrossWindows(sub); } } @@ -8450,31 +8477,30 @@ 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); } /* Add supertracks to track list, sort by priority and * determine if they have visible member tracks */ groupTrackListAddSuper(cart, group); - // TODO GALT probably nothing to do here /* 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) { char *url = trackUrl(track->track, chromName); char *longLabel = replaceChars(track->longLabel, "\"", """); hPrintPennantIcon(track->tdb); // Print an icon before the title when one is defined @@ -9373,31 +9399,30 @@ cartSetString(cart, "org", organism); cartSetString(cart, "db", database); char newPos[256]; // disguise the cart pos var if (virtualSingleChrom()) // DISGUISE VMODE safef(newPos, sizeof newPos, "%s", windowsSpanPosition()); else // usual safef(newPos, sizeof newPos, "%s:%ld-%ld", virtChromName, virtWinStart+1, virtWinEnd); position = cloneString(newPos); cartSetString(cart, "position", position); cartSetString(cart, "oldPosition", position); //cartSetString(cart, "lastPosition", position); // this is set in cart.c -// TODO GALT is it possible and worthwhile to just use lastPosition instead of oldPosition? cartSetBoolean(cart, "virtMode", virtMode); cartSetString(cart, "virtModeType", virtModeType); virtModeType = cartString(cart, "virtModeType"); // refresh the pointer after changing hash lastVirtModeType=virtModeType; cartSetString(cart, "lastVirtModeType", lastVirtModeType); lastVirtModeType = cartString(cart, "lastVirtModeType"); // refresh lastVirtModeExtraState=virtModeExtraState; cartSetString(cart, "lastVirtModeExtraState", lastVirtModeExtraState); lastVirtModeExtraState = cartString(cart, "lastVirtModeExtraState"); // refresh