3b32d1894e840bca920fb7ff03d1c2f5af1d7a24
kuhn
  Wed Mar 12 11:57:27 2014 -0700
added a 100X zoom-out button.  working with Jonathan.  refs #7475
diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index d5c3521..1a66fe1 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -58,31 +58,31 @@
 #include "imageV2.h"
 #include "suggest.h"
 #include "search.h"
 #include "errCatch.h"
 #include "iupac.h"
 #include "botDelay.h"
 #include "chromInfo.h"
 
 /* Other than submit and Submit all these vars should start with hgt.
  * to avoid weeding things out of other program's namespaces.
  * Because the browser is a central program, most of it's cart
  * variables are not hgt. qualified.  It's a good idea if other
  * program's unique variables be qualified with a prefix though. */
 char *excludeVars[] = { "submit", "Submit", "dirty", "hgt.reset",
             "hgt.in1", "hgt.in2", "hgt.in3", "hgt.inBase",
-            "hgt.out1", "hgt.out2", "hgt.out3",
+            "hgt.out1", "hgt.out2", "hgt.out3", "hgt.out4",
             "hgt.left1", "hgt.left2", "hgt.left3",
             "hgt.right1", "hgt.right2", "hgt.right3",
             "hgt.dinkLL", "hgt.dinkLR", "hgt.dinkRL", "hgt.dinkRR",
             "hgt.tui", "hgt.hideAll", "hgt.visAllFromCt",
 	    "hgt.psOutput", "hideControls", "hgt.toggleRevCmplDisp",
 	    "hgt.collapseGroups", "hgt.expandGroups", "hgt.suggest",
 	    "hgt.jump", "hgt.refresh", "hgt.setWidth",
             "hgt.trackImgOnly", "hgt.ideogramToo", "hgt.trackNameFilter", "hgt.imageV1", "hgt.suggestTrack", "hgt.setWidth",
              TRACK_SEARCH,         TRACK_SEARCH_ADD_ROW,     TRACK_SEARCH_DEL_ROW, TRACK_SEARCH_PAGER,
             "hgt.contentType", "hgt.positionInput", "hgt.internal",
             NULL };
 
 /* These variables persist from one incarnation of this program to the
  * next - living mostly in the cart. */
 boolean baseShowPos;           /* TRUE if should display full position at top of base track */
@@ -1695,30 +1695,32 @@
 int newWinWidth = winWidth;
 int i, ws, we = 0, ps, pe = 0;
 int mid, ns, ne;
 double wScale = (double)winWidth/boxes;
 double pScale = (double)insideWidth/boxes;
 char message[32];
 char *zoomType = cartCgiUsualString(cart, RULER_BASE_ZOOM_VAR, ZOOM_3X);
 
 safef(message, sizeof(message), "%s zoom", zoomType);
 if (sameString(zoomType, ZOOM_1PT5X))
     newWinWidth = winWidth/1.5;
 else if (sameString(zoomType, ZOOM_3X))
     newWinWidth = winWidth/3;
 else if (sameString(zoomType, ZOOM_10X))
     newWinWidth = winWidth/10;
+else if (sameString(zoomType, ZOOM_100X))
+    newWinWidth = winWidth/100;
 else if (sameString(zoomType, ZOOM_BASE))
     newWinWidth = insideWidth/tl.mWidth;
 else
     errAbort("invalid zoom type %s", zoomType);
 
 if (newWinWidth < 1)
     newWinWidth = 1;
 
 for (i=1; i<=boxes; ++i)
     {
     ps = pe;
     ws = we;
     pe = round(pScale*i);
     we = round(wScale*i);
     mid = (ws + we)/2 + winStart;
@@ -4601,30 +4603,31 @@
                        "return imageV2.navigateButtonClick(this);");
     hButtonWithOnClick("hgt.right2", ">> ", "move 47.5% to the right",
                        "return imageV2.navigateButtonClick(this);");
     hButtonWithOnClick("hgt.right3", ">>>", "move 95% to the right",
                        "return imageV2.navigateButtonClick(this);");
     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);
+    topButton("hgt.out4", ZOOM_100X);
     hWrites("<div style='height:0.3em;'></div>\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. */
@@ -4699,31 +4702,33 @@
         "title='zoom in 1.5x'>&gt;&nbsp;&lt;</a>\n");
 hPrintf("<td width='60' align='left'><a href='?hgt.in2=1' "
         "title='zoom in 3x'>&gt;&gt;&nbsp;&lt;&lt;</a>\n");
 hPrintf("<td width='80' align='left'><a href='?hgt.in3=1' "
         "title='zoom in 10x'>&gt;&gt;&gt;&nbsp;&lt;&lt;&lt;</a>\n");
 hPrintf("<td width='40' align='left'><a href='?hgt.inBase=1' "
         "title='zoom in to base range'>&gt;<i>base</i>&lt;</a>\n");
 
 hPrintf("<td>&nbsp;</td>\n"); // Without width cell expands table with, forcing others to sides
 hPrintf("<td width='40' align='right'><a href='?hgt.out1=1' "
         "title='zoom out 1.5x'>&lt;&nbsp;&gt;</a>\n");
 hPrintf("<td width='60' align='right'><a href='?hgt.out2=1' "
         "title='zoom out 3x'>&lt;&lt;&nbsp;&gt;&gt;</a>\n");
 hPrintf("<td width='80' align='right'><a href='?hgt.out3=1' "
         "title='zoom out 10x'>&lt;&lt;&lt;&nbsp;&gt;&gt;&gt;</a>\n");
-hPrintf("<td>&nbsp;</td>\n"); // Without width cell expands table with, forcing others to sides
+hPrintf("<td width='80' align='right'><a href='?hgt.out4=1' "
+        "title='zoom out 100x'>&lt;&lt;&lt;&nbsp;&gt;&gt;&gt;</a>\n");
+hPrintf("<td>&nbsp;</td>\n"); // Without width cell expands table width, forcing others to sides
 hPrintf("<td width='20' align='right'><a href='?hgt.right1=1' "
         "title='move 10&#37; to the right'>&gt;</a>\n");
 
 hPrintf("<td width='30' align='right'><a href='?hgt.right2=1' "
         "title='move 47.5&#37; to the right'>&gt;&gt;</a>\n");
 hPrintf("<td width='40' align='right'><a href='?hgt.right3=1' """
         "title='move 95&#37; to the right'>&gt;&gt;&gt;</a>\n");
 hPrintf("</tr></table>\n");
 #endif///def USE_NAVIGATION_LINKS
 
 /* Make clickable image and map. */
 makeActiveImage(trackList, psOutput);
 fflush(stdout);
 
 if(trackImgOnly)
@@ -5339,30 +5344,32 @@
     relativeScroll(0.95);
 else if (cgiVarExists("hgt.inBase"))
     zoomToBaseLevel();
 else if (cgiVarExists("hgt.in3"))
     zoomAroundCenter(1.0/10.0);
 else if (cgiVarExists("hgt.in2"))
     zoomAroundCenter(1.0/3.0);
 else if (cgiVarExists("hgt.in1"))
     zoomAroundCenter(1.0/1.5);
 else if (cgiVarExists("hgt.out1"))
     zoomAroundCenter(1.5);
 else if (cgiVarExists("hgt.out2"))
     zoomAroundCenter(3.0);
 else if (cgiVarExists("hgt.out3"))
     zoomAroundCenter(10.0);
+else if (cgiVarExists("hgt.out4"))
+    zoomAroundCenter(100.0);
 else if (cgiVarExists("hgt.dinkLL"))
     dinkWindow(TRUE, -dinkSize("dinkL"));
 else if (cgiVarExists("hgt.dinkLR"))
     dinkWindow(TRUE, dinkSize("dinkL"));
 else if (cgiVarExists("hgt.dinkRL"))
     dinkWindow(FALSE, -dinkSize("dinkR"));
 else if (cgiVarExists("hgt.dinkRR"))
     dinkWindow(FALSE, dinkSize("dinkR"));
 
 /* Clip chromosomal position to fit. */
 if (winEnd < winStart)
     {
     int temp = winEnd;
     winEnd = winStart;
     winStart = temp;