7da0c98cb4a828c7f743d1605577f1e8c4787941
max
  Fri May 22 04:15:21 2015 -0700
adding keyboard shortcuts, refs #15370

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 7c777ce..12e0a5c 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -5766,30 +5766,100 @@
 
 
 void resetVars()
 /* Reset vars except for position and database. */
 {
 static char *except[] = {"db", "position", NULL};
 char *cookieName = hUserCookie();
 char *sessionId = cgiOptionalString(cartSessionVarName());
 char *userId = findCookieData(cookieName);
 struct cart *oldCart = cartNew(userId, sessionId, NULL, NULL);
 cartRemoveExcept(oldCart, except);
 cartCheckout(&oldCart);
 cgiVarExcludeExcept(except);
 }
 
+void setupHotkeys() 
+/* setup keyboard shortcuts and a help dialog for it */
+{
+// XX remove if statement after July 2015
+if (!cfgOptionDefault("hotkeys", FALSE))
+    return;
+// wire the keyboard hotkeys
+hPrintf("<script type='text/javascript'>\n");
+// left
+hPrintf("Mousetrap.bind('ctrl+j', function() { $('input[name=\"hgt.left1\"]').click() }); \n");
+hPrintf("Mousetrap.bind('j', function() { $('input[name=\"hgt.left2\"]').click() }); \n");
+hPrintf("Mousetrap.bind('J', function() { $('input[name=\"hgt.left3\"]').click() }); \n");
+
+// right
+hPrintf("Mousetrap.bind('ctrl+l', function() { $('input[name=\"hgt.right1\"]').click() }); \n");
+hPrintf("Mousetrap.bind('l', function() { $('input[name=\"hgt.right2\"]').click() }); \n");
+hPrintf("Mousetrap.bind('L', function() { $('input[name=\"hgt.right3\"]').click() }); \n");
+
+// zoom in
+hPrintf("Mousetrap.bind('ctrl+i', function() { $('input[name=\"hgt.in1\"]').click() }); \n");
+hPrintf("Mousetrap.bind('i', function() { $('input[name=\"hgt.in2\"]').click() }); \n");
+hPrintf("Mousetrap.bind('I', function() { $('input[name=\"hgt.in3\"]').click() }); \n");
+hPrintf("Mousetrap.bind('b', function() { $('input[name=\"hgt.inBase\"]').click() }); \n");
+
+// zoom out
+hPrintf("Mousetrap.bind('ctrl+k', function() { $('input[name=\"hgt.out1\"]').click() }); \n");
+hPrintf("Mousetrap.bind('k', function() { $('input[name=\"hgt.out2\"]').click() }); \n");
+hPrintf("Mousetrap.bind('K', function() { $('input[name=\"hgt.out3\"]').click() }); \n");
+hPrintf("Mousetrap.bind('0', function() { $('input[name=\"hgt.out4\"]').click() }); \n");
+
+// buttons
+hPrintf("Mousetrap.bind('c f', function() { $('input[name=\"hgTracksConfigPage\"]').click() }); \n");
+hPrintf("Mousetrap.bind('t s', function() { $('input[name=\"hgt_tSearch\"]').click() }); \n");
+hPrintf("Mousetrap.bind('h a', function() { $('input[name=\"hgt.hideAll\"]').click() }); \n");
+hPrintf("Mousetrap.bind('d t', function() { $('input[name=\"hgt.reset\"]').click() }); \n");
+hPrintf("Mousetrap.bind('d o', function() { $('input[name=\"hgt.defaultImgOrder\"]').click() }); \n");
+hPrintf("Mousetrap.bind('c t', function() { document.customTrackForm.submit();return false; }); \n");
+hPrintf("Mousetrap.bind('t h', function() { document.trackHubForm.submit();return false; }); \n");
+hPrintf("Mousetrap.bind('r s', function() { $('input[name=\"hgt.setWidth\"]').click() }); \n");
+hPrintf("Mousetrap.bind('r f', function() { $('input[name=\"hgt.refresh\"]').click() }); \n");
+hPrintf("Mousetrap.bind('r v', function() { $('input[name=\"hgt.toggleRevCmplDisp\"]').click() }); \n");
+
+// focus
+hPrintf("Mousetrap.bind('/', function() { $('input[name=\"hgt.positionInput\"]').focus() }, 'keyup'); \n");
+hPrintf("Mousetrap.bind('?', function() { $( \"#hotkeyHelp\" ).dialog({width:'600'});}); \n");
+
+hPrintf("</script>\n");
+
+// help dialog
+hPrintf("<div style=\"display:none\" id=\"hotkeyHelp\" title=\"Keyboard shortcuts\">\n");
+hPrintf("<table style=\"width:580px; border-color:#666666; border-collapse:collapse\">\n");
+hPrintf("<tr><td style=\"width:18ch\">left 10&#37;</td><td width=\"auto\" class=\"hotkey\">ctrl+j</td>  <td style=\"width:24ch\"> track search</td><td class=\"hotkey\">t then s</td>               </tr>\n"); // percent sign
+hPrintf("<tr><td> left 1/2 screen</td><td class=\"hotkey\">j</td>   <td> default tracks</td><td class=\"hotkey\">d then t</td>             </tr>\n");
+hPrintf("<tr><td> left one screen</td><td class=\"hotkey\">J</td>   <td> default order</td><td class=\"hotkey\">d then o</td>              </tr>\n");
+hPrintf("<tr><td> right 10&#37;</td><td class=\"hotkey\">ctrl+l</td><td> hide all</td><td class=\"hotkey\">h then a</td>                   </tr>\n"); // percent sign
+hPrintf("<tr><td> right 1/2 screen</td><td class=\"hotkey\">l</td>  <td> custom tracks</td><td class=\"hotkey\">c then t</td>              </tr>\n");
+hPrintf("<tr><td> right one screen</td><td class=\"hotkey\">L</td>  <td> track hubs</td><td class=\"hotkey\">t then h</td>                 </tr>\n");
+hPrintf("<tr><td> zoom in 1.5x</td><td class=\"hotkey\">ctrl+i</td> <td> configure</td><td class=\"hotkey\">c then f</td>                  </tr>\n"); 
+hPrintf("<tr><td> zoom in 3x</td><td class=\"hotkey\">i</td>        <td> reverse</td><td class=\"hotkey\">r then v</td>                    </tr>\n");
+hPrintf("<tr><td> zoom in 10x</td><td class=\"hotkey\">I</td>       <td> resize</td><td class=\"hotkey\">r then s</td>                     </tr>\n");
+hPrintf("<tr><td> zoom in base level</td><td class=\"hotkey\">b</td><td> refresh</td><td class=\"hotkey\">r then f</td>                    </tr>\n");
+hPrintf("<tr><td> zoom out 1.5x</td><td class=\"hotkey\">ctrl+k</td><td> jump to position box</td><td class=\"hotkey\">/</td>        </tr>\n"); 
+hPrintf("<tr><td> zoom out 3x</td><td class=\"hotkey\">k</td>               </tr>\n");
+hPrintf("<tr><td> zoom out 10x</td><td class=\"hotkey\">K</td>              </tr>\n");
+hPrintf("<tr><td> zoom out 100x</td><td class=\"hotkey\">0</td>             </tr>\n");
+hPrintf("</table>\n");
+hPrintf("<img style=\"margin:8px\" src=\"../images/shortcutHelp.png\">");
+hPrintf("</div>\n");
+}
+
 void doMiddle(struct cart *theCart)
 /* Print the body of an html file.   */
 {
 cart = theCart;
 measureTiming = hPrintStatus() && isNotEmpty(cartOptionalString(cart, "measureTiming"));
 if (measureTiming)
     measureTime("Startup");
 
 hgBotDelay();
 if (measureTiming)
     measureTime("Bottleneck delay");
 
 char *debugTmp = NULL;
 /* Uncomment this to see parameters for debugging. */
 /* struct dyString *state = NULL; */
@@ -5835,30 +5905,33 @@
     ideogramToo = cartUsualBoolean(cart, "hgt.ideogramToo", FALSE);
     hideControls = TRUE;
     withNextItemArrows = FALSE;
     withNextExonArrows = FALSE;
     hgFindMatches = NULL;     // XXXX necessary ???
     }
 
 jsonForClient = newJsonObject(newHash(8));
 jsonObjectAdd(jsonForClient, "cgiVersion", newJsonString(CGI_VERSION));
 boolean searching = differentString(cartUsualString(cart, TRACK_SEARCH,"0"), "0");
 
 if(!trackImgOnly)
     {
     // Write out includes for css and js files
     hWrites(commonCssStyles());
+    // XX remove if statement after July 2015
+    if (cfgOptionDefault("hotkeys", FALSE))
+        jsIncludeFile("mousetrap.min.js", NULL);
     jsIncludeFile("jquery.js", NULL);
     jsIncludeFile("jquery-ui.js", NULL);
     jsIncludeFile("utils.js", NULL);
     jsIncludeFile("ajax.js", NULL);
     jsIncludeFile("jquery.watermarkinput.js", NULL);
     if(!searching)
         {
         jsIncludeFile("jquery.history.js", NULL);
         jsIncludeFile("jquery.imgareaselect.js", NULL);
         }
     jsIncludeFile("autocomplete.js", NULL);
     jsIncludeFile("hgTracks.js", NULL);
 
 #ifdef LOWELAB
     jsIncludeFile("lowetooltip.js", NULL);
@@ -5958,16 +6031,19 @@
 jsonObjectAdd(jsonForClient, "enableHighlightingDialog",
               newJsonBoolean(cartUsualBoolean(cart, "enableHighlightingDialog", TRUE)));
 hPrintf("<script type='text/javascript'>\n");
 jsonPrint((struct jsonElement *) jsonForClient, "hgTracks", 0);
 hPrintf("</script>\n");
 
 if (measureTiming)
     measureTime("Time at end of doMiddle, next up cart write");
 if (cartOptionalString(cart, "udcTimeout"))
     {
     warn("The Genome Browser cart currently includes the \"udcTimeout\" string. "
 	"While this is useful for debugging hubs, it may negatively impact "
 	"performance.   To clear this variable, click "
 	"<A HREF=hgTracks?hgsid=%s&udcTimeout=[]>here</A>.",cartSessionId(cart));
     }
+
+setupHotkeys();
+
 }