dbf7b1ce3e172cf9f85fa2275c15368d27c0ff80
braney
  Tue Feb 15 14:13:37 2011 -0800
a complicated commit to support the arrows in decipher tracks, next item buttons on bigBeds, and the beginnings of BAM wiggles
diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index fa85db1..ba604c5 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -17,30 +17,31 @@
 #include "hCommon.h"
 #include "hgColors.h"
 #include "trackDb.h"
 #include "bedCart.h"
 #include "wiggle.h"
 #include "lfs.h"
 #include "grp.h"
 #include "chromColors.h"
 #include "hgTracks.h"
 #include "subText.h"
 #include "cds.h"
 #include "mafTrack.h"
 #include "wigCommon.h"
 #include "hui.h"
 #include "imageV2.h"
+#include "bigBed.h"
 
 #ifndef GBROWSE
 #include "encode.h"
 #include "expRatioTracks.h"
 #include "hapmapTrack.h"
 #include "retroGene.h"
 #include "switchGear.h"
 #include "variation.h"
 #include "wiki.h"
 #include "wormdna.h"
 #include "aliType.h"
 #include "agpGap.h"
 #include "cgh.h"
 #include "bactigPos.h"
 #include "genePred.h"
@@ -1642,30 +1643,54 @@
                  NULL, &rowOffset);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     struct oreganno *el = oregannoLoad(row);
     if (!oregannoFilterType(el))
         oregannoFree(&el);
     else
         slAddHead(&list, el);
     }
 sqlFreeResult(&sr);
 slReverse(&list);
 tg->items = list;
 hFreeConn(&conn);
 }
 
+struct bed* loadBigBedAsBed (struct track *tg, char *chr, int start, int end)
+/* load bigBed for a range, as a bed list (for next item button). Just grab one item */
+{
+extern struct bbiFile *fetchBbiForTrack(struct track *track);
+struct bbiFile *bbiFile = fetchBbiForTrack(tg);
+struct lm *lm = lmInit(0);
+struct bigBedInterval *intervals = bigBedIntervalQuery(bbiFile, chr, 
+	start, end, 1, lm);
+
+
+struct bed *retBed = NULL;
+if (intervals != NULL)
+    {
+    AllocVar(retBed);
+    retBed->chrom = cloneString(chr);
+    retBed->chromStart = intervals->start;
+    retBed->chromEnd = intervals->end;
+    }
+
+lmCleanup(&lm);
+
+return retBed;
+}
+
 struct bed* loadOregannoAsBed (struct track *tg, char *chr, int start, int end)
 /* load oreganno with filters, for a range, as a bed list (for next item button) */
 {
 char *chromNameCopy = cloneString(chromName);
 int winStartCopy = winStart;
 int winEndCopy = winEnd;
 struct oreganno *el = NULL;
 struct bed *bed, *list = NULL;
 /* set globals and use loadOreganno */
 chromName = chr;
 winStart = start;
 winEnd = end;
 loadOreganno(tg);
 /* now walk through tg->items creating the bed list */
 for (el = tg->items; el != NULL; el = el->next)
@@ -1840,30 +1865,32 @@
     if (start < 0)
 	start = 0;
     }
 size = end - start;
 /* Now it's time to do the search. */
 if (end > start)
     for ( ; sizeWanted > 0 && sizeWanted < BIGNUM; )
 	{
 #ifndef GBROWSE
 	if (sameWord(tg->table, WIKI_TRACK_TABLE))
 	    items = wikiTrackGetBedRange(tg->table, chromName, start, end);
 	else if (sameWord(tg->table, "gvPos"))
 	    items = loadGvAsBed(tg, chromName, start, end);
 	else if (sameWord(tg->table, "oreganno"))
 	    items = loadOregannoAsBed(tg, chromName, start, end);
+	else if (tg->isBigBed)
+	    items = loadBigBedAsBed(tg, chromName, start, end);
 	else
 #endif /* GBROWSE */
 	    {
 	    if (isCustomTrack(tg->table))
 		{
 		struct customTrack *ct = tg->customPt;
 		items = hGetCtBedRange(CUSTOM_TRASH, database, ct->dbTableName, chromName, start, end, NULL);
 		}
 	    else
 		items = hGetBedRange(database, tg->table, chromName, start, end, NULL);
 	    }
 	/* If we got something, or weren't able to search as big as we wanted to */
 	/* (in case we're at the end of the chrom).  */
 	if ((items != NULL) || (size < sizeWanted))
 	    {
@@ -5209,41 +5236,64 @@
 	sqlFreeResult(&sr);
 	}
     }
 hFreeConn(&conn);
 return(col);
 }
 
 static void decipherDrawAt(struct track *tg, void *item,
 	struct hvGfx *hvg, int xOff, int y,
 	double scale, MgFont *font, Color color, enum trackVisibility vis)
 /* Draw a single superfamily item at position. */
 {
 struct bed *bed = item;
 char *sPhenotypes;
 int heightPer = tg->heightPer;
-int x1 = round((double)((int)bed->chromStart-winStart)*scale) + xOff;
-int x2 = round((double)((int)bed->chromEnd-winStart)*scale) + xOff;
+int start = bed->chromStart;
+if (start < winStart)
+    start = winStart;
+int end = bed->chromEnd;
+if (end > winEnd)
+    end = winEnd;
+int x1 = round((double)((int)start-winStart)*scale) + xOff;
+int x2 = round((double)((int)end-winStart)*scale) + xOff;
 int w;
 
 sPhenotypes = decipherPhenotypeList(tg, item);
 w = x2-x1;
+
 if (w < 1)
     w = 1;
 if (color)
     {
-    hvGfxBox(hvg, x1, y, w, heightPer, decipherColor(tg, item, hvg));
+    void drawTri(struct hvGfx *hvg, int x, int y1, int y2, Color color, char strand);
+    int ourX = x1;
+    int ourW = w;
+    if (bed->chromStart < winStart)
+	{
+	assert(x1 == xOff);
+	ourX += heightPer/2;
+	ourW -= heightPer/2;
+	drawTri(hvg, xOff, y, y + heightPer -1,decipherColor(tg, item, hvg), '-');
+	}
+
+    if (bed->chromEnd > winEnd)
+	{
+	ourW -= heightPer/2;
+	drawTri(hvg, x2 - heightPer/2, y, y + heightPer -1,decipherColor(tg, item, hvg), '+');
+	}
+    hvGfxBox(hvg, ourX, y, ourW, heightPer, decipherColor(tg, item, hvg));
 
     if (vis == tvFull)
         {
         hvGfxTextRight(hvg, x1-mgFontStringWidth(font, sPhenotypes)-2, y,
 		    mgFontStringWidth(font, sPhenotypes),
                     heightPer, MG_BLACK, font, sPhenotypes);
         }
     if (tg->drawName && vis != tvSquish)
 	{
 	/* Clip here so that text will tend to be more visible... */
 	char *s = tg->itemName(tg, bed);
 	w = x2-x1;
 	if (w > mgFontStringWidth(font, s))
 	    {
 	    Color textColor = hvGfxContrastingColor(hvg, color);
@@ -9955,31 +10005,31 @@
 tg->itemNameColor = cactusNameColor;
 tg->drawLeftLabels = cactusLeftLabels;
 }
 
 void blastMethods(struct track *tg)
 /* blast protein track methods */
 {
 tg->loadItems = loadBlast;
 tg->itemName = refGeneName;
 tg->mapItemName = refGeneMapName;
 tg->itemColor = blastColor;
 tg->itemNameColor = blastNameColor;
 }
 
 
-static void drawTri(struct hvGfx *hvg, int x, int y1, int y2, Color color,
+void drawTri(struct hvGfx *hvg, int x, int y1, int y2, Color color,
 	char strand)
 /* Draw traingle. */
 {
 struct gfxPoly *poly = gfxPolyNew();
 int half = (y2 - y1) / 2;
 if (strand == '-')
     {
     gfxPolyAddPoint(poly, x, y1+half);
     gfxPolyAddPoint(poly, x+half, y1);
     gfxPolyAddPoint(poly, x+half, y2);
     }
 else
     {
     gfxPolyAddPoint(poly, x, y1);
     gfxPolyAddPoint(poly, x+half, y1+half);
@@ -11753,38 +11803,47 @@
 }
 
 void fillInFromType(struct track *track, struct trackDb *tdb)
 /* Fill in various function pointers in track from type field of tdb. */
 {
 char *typeLine = tdb->type, *words[8], *type;
 int wordCount;
 if (typeLine == NULL)
     return;
 wordCount = chopLine(cloneString(typeLine), words);
 if (wordCount <= 0)
     return;
 type = words[0];
 
 #ifndef GBROWSE
-if (sameWord(type, "bed") || sameWord(type, "bedLogR"))
+if (sameWord(type, "bed"))
     {
     complexBedMethods(track, tdb, FALSE, wordCount, words);
     /* bed.h includes genePred.h so should be able to use these trackDb
        settings. */
     if (trackDbSetting(track->tdb, GENEPRED_CLASS_TBL) !=NULL)
         track->itemColor = genePredItemClassColor;
     }
+/*
+else if (sameWord(type, "bedLogR"))
+    {
+    wordCount++;
+    words[1] = "9";
+    complexBedMethods(track, tdb, FALSE, wordCount, words);
+    //track->bedSize = 10;
+    }
+    */
 else if (sameWord(type, "bigBed"))
     {
     bigBedMethods(track, tdb, wordCount, words);
     if (trackShouldUseAjaxRetrieval(track))
         track->loadItems = dontLoadItems;
     }
 else if (sameWord(type, "bedGraph"))
     {
     bedGraphMethods(track, tdb, wordCount, words);
     }
 else if (sameWord(type, "bigWig"))
     {
     bigWigMethods(track, tdb, wordCount, words);
     if (trackShouldUseAjaxRetrieval(track))
         track->loadItems = dontLoadItems;  // TODO: Dummy drawItems as well?
@@ -11904,30 +11963,34 @@
     {
     repeatMethods(track);
     }
 else if (sameWord(type, "ld2"))
     {
     ldMethods(track);
     }
 else if (sameWord(type, "factorSource"))
     {
     factorSourceMethods(track);
     }
 else if (sameWord(type, "remote"))
     {
     remoteMethods(track);
     }
+else if (sameWord(type, "bamWig"))
+    {
+    bamWigMethods(track, tdb, wordCount, words);
+    }
 else if (sameWord(type, "interaction"))
     {
     interactionMethods(track);
     }
 else if (sameWord(type, "gvf"))
     {
     gvfMethods(track);
     }
 #endif /* GBROWSE */
 }
 
 static void compositeLoad(struct track *track)
 /* Load all subtracks */
 {
 struct track *subtrack;