src/hg/js/hgTracks.js 1.52

1.52 2010/02/12 21:15:41 tdreszer
Good work on dragScroll. Ajax refresh of whole image not yet working but form.submit() works.
Index: src/hg/js/hgTracks.js
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/js/hgTracks.js,v
retrieving revision 1.51
retrieving revision 1.52
diff -b -B -U 4 -r1.51 -r1.52
--- src/hg/js/hgTracks.js	30 Dec 2009 19:48:20 -0000	1.51
+++ src/hg/js/hgTracks.js	12 Feb 2010 21:15:41 -0000	1.52
@@ -473,8 +473,10 @@
                         pxDown = convertFromBases(selRange.beg)
                         pxUp = convertFromBases(selRange.end)
                         hiliteShow(pxDown,pxUp);
                     }
+                    //if((selRange.end - selRange.beg) < 50000)
+                    //    dontAsk = true;
                     if(dontAsk || confirm("Jump to new position:\n\n"+chr.name+":"+commify(selRange.beg)+"-"+commify(selRange.end)+" size:"+commify(selRange.width)) ) {
                         setPositionByCoordinates(chr.name, selRange.beg, selRange.end)
                         $('.cytoBand').mousedown( function(e) { return false; }); // Stop the presses :0)
                         document.TrackHeaderForm.submit();
@@ -690,8 +692,10 @@
     var count=0;
     var countN=0;
     for(var ix=0;ix<rows.length;ix++) {    // Need to have buttons in order
         var btn = $( rows[ix] ).find("p.btn");
+        if( btn.length == 0)
+            continue;
         var classList = $( btn ).attr("class").split(" ");
         var curMatchesLast=(classList[0] == lastClass);
         if(lastBtn != undefined) {
             $( lastBtn ).removeClass('btnN btnU btnL btnD');
@@ -771,8 +775,14 @@
 
 /////////////////////////////////////////////////////
 // Drag Scroll code
 jQuery.fn.panImages = function(imgOffset,imgBoxLeftOffset){
+    // globals across all panImages
+    var leftLimit   = imgBoxLeftOffset*-1;
+    var rightLimit  = (imgBoxPortalWidth - imgBoxWidth + leftLimit);
+    var prevX       = (imgOffset + imgBoxLeftOffset)*-1;
+    var portalWidth = 0;
+
 this.each(function(){
 
     var pic;
     var pan;
@@ -789,36 +799,33 @@
     if(pan == undefined || pic == undefined) {
         throw "Not a div with a child image! 'panImages' can only be used with divs contain images.";
     }
 
-    var leftLimit   = imgBoxLeftOffset*-1; // This hides the leftLabel if the image contains it
-    var prevX       = imgOffset*-1;
+    // globals across all panImages
+    portalWidth     = $(pan).width();
+    // globals to one panImage
     var newX        = 0;
     var mouseDownX  = 0;
     var mouseIsDown = false;
-    var portalWidth = $(pan).width();
-    //var ie=( $.browser.msie == true );
+    var beyondImage = false;
+    var atEdge      = false;
 
     initialize();
 
     function initialize(){
 
-        pan.css( 'cursor', 'w-resize');//'move');
+        pan.css( 'cursor', 'w-resize');
 
         panAdjustHeight(prevX);
 
         pan.mousedown(function(e){
             if(mouseIsDown == false) {
                 mouseIsDown = true;
 
                 mouseDownX = e.clientX;
-                //if(ie) {  // Doesn't work (yet?)
-                //    pic.ondrag='panner';
-                //    pic.ondragend='panMouseUp';
-                //} else {
+                atEdge = (!beyondImage && (prevX >= leftLimit || prevX <= rightLimit));
                     $(document).bind('mousemove',panner);
                     $(document).bind( 'mouseup', panMouseUp);  // Will exec only once
-                //}
                 return false;
             }
         });
     }
@@ -827,62 +834,83 @@
         //if(!e) e = window.event;
         if ( mouseIsDown ) {
             var relativeX = (e.clientX - mouseDownX);
 
-            // Would be good to:
-            // 1) Slow scroll near edge
-            // 2) Allow scrolling past edge
-            // 3) ajax to new image when scrolled off edge
             if(relativeX != 0) {
                 blockUseMap = true;
+                var decelerator = 1;
+                var wingSize    = 1000; // 0 stops the scroll at the edges.
                 // Remeber that offsetX (prevX) is negative
-                if ( (prevX + relativeX) >= leftLimit ) { // scrolled all the way to the left
+                newX = prevX + relativeX;
+                if ( newX >= leftLimit ) { // scrolled all the way to the left
+                    if(atEdge) {  // Do not drag straight off edge.  Force second drag
+                        beyondImage = true;
+                        newX = leftLimit + (newX - leftLimit)/decelerator;// slower
+                        if( newX >= leftLimit + wingSize) // Don't go too far over the edge!
+                        newX =  leftLimit + wingSize;
+                    } else
                     newX = leftLimit;
-                    // get new image?
-                } else if ( (prevX + relativeX) < (imgBoxPortalWidth - imgBoxWidth + leftLimit) ) { // scrolled all the way to the right
-                    newX = (imgBoxPortalWidth - imgBoxWidth + leftLimit);
-                    // get new image?
+
+                } else if ( newX < rightLimit ) { // scrolled all the way to the right
+                    if(atEdge) {  // Do not drag straight off edge.  Force second drag
+                        beyondImage = true;
+                        newX = rightLimit - (rightLimit - newX)/decelerator;// slower
+                        if( newX < rightLimit - wingSize) // Don't go too far over the edge!
+                            newX = rightLimit - wingSize;
                 } else
-                    newX = prevX + relativeX;
+                        newX = rightLimit;
 
-                $(".panImg").css( {'left': newX.toString() + "px" });
-                $('.tdData').css( {'backgroundPosition': newX.toString() + "px" } );
-                //$('#imgTbl').css( {backgroundPosition:  newX.toString() +"px " + newY.toString() + "px"} )
-                // Now is the time to get left-right, then march through data images to trim horizontal
-                panUpdatePosition(newX);
+                } else if(newX >= rightLimit && newX < leftLimit)
+                    beyondImage = false; // could have scrolled back without mouse up
+
+                var nowPos = newX.toString() + "px";
+                $(".panImg").css( {'left': nowPos });
+                $('.tdData').css( {'backgroundPosition': nowPos } );
+                panUpdatePosition(newX,false);
             }
         }
     }
     function panMouseUp(e) {  // Must be a separate function instead of pan.mouseup event.
         //if(!e) e = window.event;
         if(mouseIsDown) {
 
-            if(prevX != newX)
-                panAdjustHeight(newX);
-            //if(prevX != newX) {
-                prevX = newX;
-                //if(ie) {
-                //    pic.ondrag=''; pic.ondragend='';
-                //} else {
                     $(document).unbind('mousemove',panner);
                     $(document).unbind('mouseup',panMouseUp);
-                //}
                 mouseIsDown = false;
+
+            if(beyondImage) {
+                // FIXME:
+                // 1) When dragging beyondImage, side label is seen. Only solution may be 2 images!
+                //    NOTE: tried clip:rect() but this only works with position:absolute!
+                // 2) Would be nice to support drag within AND beyond image:
+                //    a) Within stops at border, and then second drag needed to go beyond
+                //    b) Within needs support for next/prev arrows
+                // 3) AJAX does not work on full image.  Larry's callback routine needs extension beyond songle track
+                //$.ajax({type: "GET", url: "../cgi-bin/hgTracks",
+                //    data: "hgt.trackImgOnly=1&hgsid=" + getHgsid(), dataType: "html",
+                //    trueSuccess: handleUpdateTrackMap, success: catchErrorOrDispatch,
+                //    cmd: "wholeImage",  cache: false });
+                document.TrackHeaderForm.submit();
+                return true; // Make sure the setTimeout below is not called.
+            }
+            if(prevX != newX) {
+                panAdjustHeight(newX);
+                prevX = newX;
+            }
                 setTimeout('blockUseMap=false;',50); // Necessary incase the selectEnd was over a map item. select takes precedence.
-            //}
         }
     }
-    function panUpdatePosition(newOffsetX)
+    function panUpdatePosition(newOffsetX,bounded)
     {
         // Updates the 'position/search" display with change due to panning
         var portalWidthBases = imgBoxPortalEnd - imgBoxPortalStart;
         var portalScrolledX  = (imgBoxPortalOffsetX+imgBoxLeftLabel) + newOffsetX;
 
         var newPortalStart = imgBoxPortalStart - Math.round(portalScrolledX*imgBoxBasesPerPixel); // As offset goes down, bases seen goes up!
-        if( newPortalStart < imgBoxChromStart)     // Stay within bounds
+        if( newPortalStart < imgBoxChromStart && bounded)     // Stay within bounds
             newPortalStart = imgBoxChromStart;
         var newPortalEnd = newPortalStart + portalWidthBases;
-        if( newPortalEnd > imgBoxChromEnd) {
+        if( newPortalEnd > imgBoxChromEnd && bounded) {
             newPortalEnd = imgBoxChromEnd;
             newPortalStart = newPortalEnd - portalWidthBases;
         }
         if(newPortalStart > 0) {
@@ -1069,8 +1097,10 @@
 
             // Turn on drag scrolling.
             $("div.scroller").panImages(imgBoxPortalOffsetX,imgBoxLeftLabel);
         }
+        //$("#zoomSlider").slider({ min: -4, max: 3, step: 1 });//, handle: '.ui-slider-handle' });
+
         // Temporary warning while new imageV2 code is being worked through
         if($('#map').children("AREA").length > 0) {
             warn('Using imageV2, but old map is not empty!');
         }
@@ -1081,17 +1111,8 @@
         }
     }
 });
 
-////////// Attempts to get back button to work with us
-//window.onload = function () {
-//    // Requires "Signed Scripts" and "UniversalBrowserRead" http://www.mozilla.org/projects/security/components/signed-scripts.html
-//    if(window.history.next != undefined && window.history.next.length > 10) {
-//	warn("Not at the end of time.");
-//    } else
-//	warn("At the end of time.");
-//}
-
 function rulerModeToggle (ele)
 {
     autoHideSetting = !ele.checked;
     var obj = imgAreaSelect.data('imgAreaSelect');
@@ -1543,9 +1564,9 @@
         if(b[1]) {
             $('#chrom').attr('src', b[1]);
         }
     }
-    if(imageV2 && this.cmd && this.cmd != 'selectWholeGene') {
+    if(imageV2 && this.cmd && this.cmd != 'wholeImage' && this.cmd != 'selectWholeGene') {
           // Extract <TR id='tr_ID'>...</TR> and update appropriate row in imgTbl;
           // this updates src in img_left_ID, img_center_ID and img_data_ID and map in map_data_ID
           var id = selectedMenuItem.id;
           var rec = trackDbJson[id];