520d704e34f2eea59592fa24a4b830e1df0adcf4 galt Wed Mar 30 15:26:33 2016 -0700 Fixes #17096. Enhanced nextExon hover labels explains what it does now. diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index 9afd22a..08ce117 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -2297,40 +2297,43 @@ /* Draw a mapBox over the arrow-button on an *item already in the window*. */ /* Clicking this will do one of several things: */ { boolean result = FALSE; struct linkedFeatures *lf = item; struct simpleFeature *exons = lf->components; struct simpleFeature *exon = exons; char *nextExonText; char *prevExonText; long newWinSize = virtWinEnd - virtWinStart; long bufferToEdge = 0.05 * newWinSize; long newWinStart, newWinEnd; int numExons = 0; int exonIx = 0; struct slRef *exonList = NULL, *ref; +boolean isExon = FALSE; if (startsWith("chain", tg->tdb->type) || startsWith("lrg", tg->tdb->track)) { nextExonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "nextExonText", "Next Block"); prevExonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "prevExonText", "Prev Block"); } else { - nextExonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "nextExonText", "Next Exon Edge"); - prevExonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "prevExonText", "Prev Exon Edge"); + nextExonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "nextExonText", "Next Exon"); + prevExonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "prevExonText", "Prev Exon"); } +if (sameString(nextExonText,"Next Exon")) + isExon = TRUE; while (exon != NULL) /* Make a stupid list of exons separate from what's given. */ /* It seems like lf->components isn't necessarily sorted. */ { refAdd(&exonList, exon); exon = exon->next; } /* Now sort it. */ if (next) slSort(&exonList, exonSlRefCmp); else slSort(&exonList, exonSlRefReverseCmp); numExons = slCount(exonList); // translate tall and exons @@ -2386,60 +2389,102 @@ boolean revStrand = (lf->orientation == -1); exon = ref->val; // translate exon long xExonStart = cr->vStart, xExonEnd = cr->vEnd; if ((xExonEnd != -1) && ((xExonEnd - xExonStart) > (newWinSize - (2 * bufferToEdge)))) bigExon = TRUE; if (next && (xExonEnd != -1) && (xExonEnd > virtWinEnd)) /* right overhang (but left side of screen in reverse-strand-display) */ { if (xExonStart < virtWinEnd) { /* not an intron hanging over edge. */ if ((xTallStart != -1) && (xTallStart > virtWinEnd) && (xTallStart < xExonEnd) && (xTallStart > xExonStart)) + { linkedFeaturesMoveWinEnd(xTallStart, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); + if (isExon) + { + nextExonText = "Coding Start of Exon"; + prevExonText = "Coding End of Exon"; + } + } else if ((xTallEnd != -1) && (xTallEnd > virtWinEnd) && (xTallEnd < xExonEnd) && (xTallEnd > xExonStart)) + { linkedFeaturesMoveWinEnd(xTallEnd, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); + if (isExon) + { + nextExonText = "Coding End of Exon"; + prevExonText = "Coding Start of Exon"; + } + } else + { linkedFeaturesMoveWinEnd(xExonEnd, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); + if (isExon) + { + nextExonText = "End of Exon"; + prevExonText = "Start of Exon"; + } + } } else if (bigExon) linkedFeaturesMoveWinStart(xExonStart, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); else linkedFeaturesMoveWinEnd(xExonEnd, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); if (!revStrand) safef(mouseOverText, sizeof(mouseOverText), "%s (%d/%d)", nextExonText, exonIx+1, numExons); else safef(mouseOverText, sizeof(mouseOverText), "%s (%d/%d)", prevExonText, numExons-exonIx, numExons); mapBoxJumpTo(hvg, x, y, w, h, tg, virtChromName, newWinStart, newWinEnd, mouseOverText); result = TRUE; break; } else if (!next && (xExonStart != -1) && (xExonStart < virtWinStart)) /* left overhang */ { if (xExonEnd > virtWinStart) { /* not an intron hanging over the edge. */ if ((xTallEnd != -1) && (xTallEnd < virtWinStart) && (xTallEnd > xExonStart) && (xTallEnd < xExonEnd)) + { linkedFeaturesMoveWinStart(xTallEnd, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); + if (isExon) + { + nextExonText = "Coding Start of Exon"; + prevExonText = "Coding End of Exon"; + } + } else if ((xTallStart != -1) && (xTallStart < virtWinStart) && (xTallStart > xExonStart) && (xTallStart < xExonEnd)) + { linkedFeaturesMoveWinStart(xTallStart, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); + if (isExon) + { + nextExonText = "Coding End of Exon"; + prevExonText = "Coding Start of Exon"; + } + } else + { linkedFeaturesMoveWinStart(xExonStart, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); + if (isExon) + { + nextExonText = "End of Exon"; + prevExonText = "Start of Exon"; + } + } } else if (bigExon) linkedFeaturesMoveWinEnd(xExonEnd, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); else linkedFeaturesMoveWinStart(xExonStart, bufferToEdge, newWinSize, &newWinStart, &newWinEnd); if (!revStrand) safef(mouseOverText, sizeof(mouseOverText), "%s (%d/%d)", prevExonText, numExons-exonIx, numExons); else safef(mouseOverText, sizeof(mouseOverText), "%s (%d/%d)", nextExonText, exonIx+1, numExons); mapBoxJumpTo(hvg, x, y, w, h, tg, virtChromName, newWinStart, newWinEnd, mouseOverText); result = TRUE; break; } } slFreeList(&exonList);