96a5f2b02386cf2ce9330afa1df0599ce6361b20
braney
  Fri Dec 17 18:27:25 2010 -0800
BAM tracks that have too many items to map now draw one big map box with a message telling the user to zoom in if they want to click on an item. #1279
diff --git src/hg/hgTracks/bamTrack.c src/hg/hgTracks/bamTrack.c
index b6e6bd1..5a8b4d6 100644
--- src/hg/hgTracks/bamTrack.c
+++ src/hg/hgTracks/bamTrack.c
@@ -500,33 +500,37 @@
 	}
     }
 if (tg->visibility != tvDense)
     {
     slReverse(&(tg->items));
     if (isPaired)
 	slSort(&(tg->items), linkedFeaturesSeriesCmp);
     else if (sameString(colorMode, BAM_COLOR_MODE_STRAND))
 	slSort(&(tg->items), linkedFeaturesCmpOri);
     else if (sameString(colorMode, BAM_COLOR_MODE_GRAY) &&
 	     sameString(grayMode, BAM_GRAY_MODE_ALI_QUAL))
 	slSort(&(tg->items), linkedFeaturesCmpScore);
     else
 	slSort(&(tg->items), linkedFeaturesCmpStart);
     if (slCount(tg->items) > MAX_ITEMS_FOR_MAPBOX)
+        {
+        // flag drawItems to make a mapBox for the whole track
+        tg->customInt = 1;
 	tg->mapItem = dontMapItem;
     }
 }
+}
 
 void bamLoadItems(struct track *tg)
 /* Load single-ended-only BAM data into tg->items item list, unless zoomed out so far
  * that the data would just end up in dense mode and be super-slow. */
 {
 bamLoadItemsCore(tg, FALSE);
 }
 
 void bamPairedLoadItems(struct track *tg)
 /* Load possibly paired BAM data into tg->items item list, unless zoomed out so far
  * that the data would just end up in dense mode and be super-slow. */
 {
 bamLoadItemsCore(tg, TRUE);
 }
 
@@ -663,30 +667,67 @@
 			       MgFont *font, Color color, enum trackVisibility vis)
 /* If this is invoked, we are hiding item labels.  In full mode, that means no left labels.
  * In dense mode, we do need the left label to show shortLabel. */
 {
 if (tg->limitedVis == tvDense)
     {
     int fontHeight = mgFontLineHeight(font);
     if (isCenterLabelIncluded(tg))
 	yOff += fontHeight;
     hvGfxTextRight(hvg, xOff, yOff, width, tg->lineHeight, color, font, tg->shortLabel);
     }
 return;
 }
 
 
+void bamLinkedFeaturesSeriesDraw(struct track *tg,
+	int seqStart, int seqEnd,
+        struct hvGfx *hvg, int xOff, int yOff, int width,
+        MgFont *font, Color color, enum trackVisibility vis)
+/* Draw bam linked features items. */
+{
+linkedFeaturesSeriesDraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width,
+        font, color, vis);
+
+if(tg->customInt)
+    {
+    mapBoxHc(hvg, seqStart, seqEnd, xOff, yOff, width, tg->height, 
+        tg->track, tg->track, 
+        "Too many items in display.  Zoom in to click on items");
+    // just do this once
+    tg->customInt = 0;
+    }
+}
+
+void bamLinkedFeaturesDraw(struct track *tg, int seqStart, int seqEnd,
+        struct hvGfx *hvg, int xOff, int yOff, int width,
+        MgFont *font, Color color, enum trackVisibility vis)
+/* Draw linked features items. */
+{
+linkedFeaturesDraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width,
+        font, color, vis);
+
+if(tg->customInt)
+    {
+    mapBoxHc(hvg, seqStart, seqEnd, xOff, yOff, width, tg->height, 
+        tg->track, tg->track, 
+        "Too many items in display.  Zoom in to click on items");
+    // just do this once
+    tg->customInt = 0;
+    }
+}
+
 void bamMethods(struct track *track)
 /* Methods for BAM alignment files. */
 {
 #if (defined USE_BAM && defined KNETFILE_HOOKS)
 knetUdcInstall();
 if (udcCacheTimeout() < 300)
     udcSetCacheTimeout(300);
 #endif//def USE_BAM && KNETFILE_HOOKS
 
 track->canPack = TRUE;
 boolean compositeLevel = isNameAtCompositeLevel(track->tdb, BAM_PAIR_ENDS_BY_NAME);
 boolean isPaired = cartUsualBooleanClosestToHome(cart, track->tdb, compositeLevel,
 			 BAM_PAIR_ENDS_BY_NAME,
 			 (trackDbSettingClosestToHome(track->tdb, BAM_PAIR_ENDS_BY_NAME) != NULL));
 char *tdbShowNames = trackDbSetting(track->tdb, BAM_SHOW_NAMES);
@@ -697,36 +738,38 @@
 if (sameString(colorMode, BAM_COLOR_MODE_TAG) && userTag != NULL)
     {
     if (! (isalpha(userTag[0]) && isalnum(userTag[1]) && userTag[2] == '\0'))
 	{
 	warn("%s: BAM tag '%s' is not valid -- must be a letter followed by a letter or number.",
 	     track->tdb->shortLabel, htmlEncode(userTag));
 	compositeLevel = isNameAtCompositeLevel(track->tdb, BAM_COLOR_TAG);
 	cartRemoveVariableClosestToHome(cart, track->tdb, compositeLevel, BAM_COLOR_TAG);
 	}
     }
 
 if (isPaired)
     {
     linkedFeaturesSeriesMethods(track);
     track->loadItems = bamPairedLoadItems;
+    track->drawItems = bamLinkedFeaturesSeriesDraw;
     track->drawItemAt = bamPairedDrawAt;
     }
 else
     {
     linkedFeaturesMethods(track);
     track->loadItems = bamLoadItems;
+    track->drawItems = bamLinkedFeaturesDraw;
     track->drawItemAt = bamDrawAt;
     }
 if (!showNames)
     {
     track->drawName = TRUE; // ironic, but this is how to suppress item labels in pack mode.
     track->drawLeftLabels = maybeDrawLeftLabels;
     }
 
 track->nextItemButtonable = track->nextExonButtonable = FALSE;
 track->nextPrevItem = NULL;
 track->nextPrevExon = NULL;
 if (differentString(colorMode, "off"))
     track->colorShades = shadesOfGray;
 }