8ed2d68b3774dcfe96b43cb0d60ed36ca84009bd
tdreszer
  Fri Jul 29 14:59:06 2011 -0700
Integrate my dragScroll with Larry's new json hash code.
diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 7d1c735..bfa9e9d 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -1,25 +1,24 @@
 // Javascript for use in hgTracks CGI
 
 var debug = false;
 var originalPosition;
 var originalSize;
 var originalCursor;
 var originalMouseOffset = {x:0, y:0};
 var startDragZoom = null;
 var imageV2 = false;
-var imgBoxPortal = false;
 var blockUseMap = false;
 var mapItems;
 var trackImg;               // jQuery element for the track image
 var trackImgTbl;            // jQuery element used for image table under imageV2
 var imgAreaSelect;          // jQuery element used for imgAreaSelect
 var originalImgTitle;
 var autoHideSetting = true; // Current state of imgAreaSelect autoHide setting
 var selectedMenuItem;       // currently choosen context menu item (via context menu).
 var browser;                // browser ("msie", "safari" etc.)
 var mapIsUpdateable = true;
 var currentMapItem;
 var floatingMenuItem;
 var visibilityStrsOrder = new Array("hide", "dense", "full", "pack", "squish");     // map browser numeric visibility codes to strings
 var supportZoomCodon = false;  // turn on experimental zoom-to-codon functionality (currently only on in larrym's tree).
 var inPlaceUpdate = false;     // modified based on value of hgTracks.inPlaceUpdate
@@ -272,31 +271,31 @@
     if(trackImg && jQuery.fn.contextMenu) {
         $('#hgTrackUiDialog').hide();
         if(imageV2) {
             $("map[name!=ideoMap]").each( function(t) { parseMap($(this,false));});
         } else {
             // XXXX still under debate whether we have to remove the map
             parseMap($('#map'),true);
             $('#map').empty();
         }
 
         originalImgTitle = trackImg.attr("title");
         if(imageV2) {
             loadContextMenu(trackImgTbl);
             //$(".trDraggable,.nodrop").each( function(t) { loadContextMenu($(this)); });
             // FIXME: why isn't rightClick for sideLabel working??? Probably because there is no link!
-            if(inPlaceUpdate) {
+            if(inPlaceUpdate && !hgTracks.imgBoxPortal) {
                 // Larry's experimental version of 1x panning (aka cheap panning).
                 var originalLeft;
                 var originalClientX;
                 var withinTrackImgTbl;
                 var last;
                 trackImgTbl.mousedown(
                     function (e) {
                         originalClientX = e.clientX;
                         withinTrackImgTbl = true;
                         last = new Date();
                         jQuery('body').css('cursor', 'w-resize');
                         $("img.dataImg").each( function(index, ele) {
                                                    var left = $(ele).css('left');
                                                    originalLeft = left.substring(0, left.length - 2)
                                                    // we only need to look at one element, so bail out now.
@@ -995,31 +994,32 @@
     $( btns ).removeClass('btnBlue');
     $( btns ).addClass('btnGrey');
     if (jQuery.tableDnD != undefined) {
         var rows = imgTblContiguousRowSet($(this).parents('tr.trDraggable')[0]);
         if (rows)
            $( rows ).removeClass("trDrag");
     }
 }
 
 
 /////////////////////////////////////////////////////
 // Drag Scroll code
 jQuery.fn.panImages = function(imgOffset,imgBoxLeftOffset){
     // globals across all panImages
     var leftLimit   = imgBoxLeftOffset*-1;
-    var rightLimit  = (imgBoxPortalWidth - imgBoxWidth + leftLimit);
+    var rightLimit  = (hgTracks.imgBoxPortalWidth - hgTracks.imgBoxWidth + leftLimit);
+    var only1xScrolling = (hgTracks.imgBoxPortalOffsetX == 0);
     var prevX       = (imgOffset + imgBoxLeftOffset)*-1;
     var portalWidth = 0;
     panAdjustHeight(prevX);
 
 this.each(function(){
 
     var pic;
     var pan;
 
     if ( $(this).is("img") ) {
         pan = $(this).parent("div");
         pic = $(this);
     }
     else if ( $(this).is("div.scroller")  ) {
         pan = $(this);
@@ -1080,84 +1080,81 @@
                 } 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 = rightLimit;
 
                 } 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 } );
+                if (!only1xScrolling)
+                    panAdjustHeight(newX);  // NOTE: This will dynamically resize image while scrolling.  Do we want to?
                 panUpdatePosition(newX,false);
             }
         }
     }
     function panMouseUp(e) {  // Must be a separate function instead of pan.mouseup event.
         //if(!e) e = window.event;
         if(mouseIsDown) {
 
             $(document).unbind('mousemove',panner);
             $(document).unbind('mouseup',panMouseUp);
             mouseIsDown = false;
 
             // Talk to tim about this.
             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 });
+                if(inPlaceUpdate) {
+                    var pos = parsePosition(getPosition());
+                    navigateInPlace("position=" + encodeURIComponent(pos.chrom + ":" + pos.start + "-" + pos.end));
+                } else {
                 document.TrackHeaderForm.submit();
+                }
                 return true; // Make sure the setTimeout below is not called.
             }
             if(prevX != newX) {
-                panAdjustHeight(newX);
+                //if (!only1xScrolling)
+                //    panAdjustHeight(newX); // NOTE: This will resize image after scrolling.  Do we want to while scrolling?
                 prevX = newX;
             }
             setTimeout('blockUseMap=false;',50); // Necessary incase the selectEnd was over a map item. select takes precedence.
         }
     }
-});
+    });  // end of this.each(function(){
 
     function panUpdatePosition(newOffsetX,bounded)
     {
         // Updates the 'position/search" display with change due to panning
-        var portalWidthBases = imgBoxPortalEnd - imgBoxPortalStart;
-        var portalScrolledX  = (imgBoxPortalOffsetX+imgBoxLeftLabel) + newOffsetX;
+        var portalWidthBases = hgTracks.imgBoxPortalEnd - hgTracks.imgBoxPortalStart;
+        var portalScrolledX  = (hgTracks.imgBoxPortalOffsetX+hgTracks.imgBoxLeftLabel) + newOffsetX;
 
-        var newPortalStart = imgBoxPortalStart - Math.round(portalScrolledX*imgBoxBasesPerPixel); // As offset goes down, bases seen goes up!
-        if( newPortalStart < imgBoxChromStart && bounded)     // Stay within bounds
-            newPortalStart = imgBoxChromStart;
+        var newPortalStart = hgTracks.imgBoxPortalStart - Math.round(portalScrolledX*hgTracks.imgBoxBasesPerPixel); // As offset goes down, bases seen goes up!
+        if( newPortalStart < hgTracks.imgBoxChromStart && bounded)     // Stay within bounds
+            newPortalStart = hgTracks.imgBoxChromStart;
         var newPortalEnd = newPortalStart + portalWidthBases;
-        if( newPortalEnd > imgBoxChromEnd && bounded) {
-            newPortalEnd = imgBoxChromEnd;
+        if( newPortalEnd > hgTracks.imgBoxChromEnd && bounded) {
+            newPortalEnd = hgTracks.imgBoxChromEnd;
             newPortalStart = newPortalEnd - portalWidthBases;
         }
         if(newPortalStart > 0) {
-            // XXXX ? imgBoxPortalStart = newPortalStart;
-            // XXXX ? imgBoxPortalEnd = newPortalEnd;
+            // XXXX ? hgTracks.imgBoxPortalStart = newPortalStart;
+            // XXXX ? hgTracks.imgBoxPortalEnd = newPortalEnd;
             var newPos = hgTracks.chromName + ":" + commify(newPortalStart) + "-" + commify(newPortalEnd);
             setPosition(newPos, (newPortalEnd - newPortalStart + 1));
         }
         return true;
     }
     function mapTopAndBottom(mapName,left,right)
     {
     // Find the top and bottom px given left and right boundaries
         var span = { top: -10, bottom: -10 };
         var items = $("map[name='"+mapName+"']").children();
         if($(items).length>0) {
             $(items).each(function(t) {
                 var loc = this.coords.split(",");
                 var aleft   = parseInt(loc[0]);
                 var aright  = parseInt(loc[2]);
@@ -1168,30 +1165,35 @@
                         span.top    = atop;
                         span.bottom = abottom;
                     } else if(span.top > atop) {
                             span.top = atop;
                     } else if(span.bottom < abottom) {
                             span.bottom = abottom;
                     }
                 }
             });
         }
         return span;
     }
     function panAdjustHeight(newOffsetX) {
         // Adjust the height of the track data images so that bed items scrolled off screen
         // do not waste vertical real estate
+
+        // Is the > 1x?
+        if (only1xScrolling)
+            return;
+
         var left = newOffsetX * -1;
         var right = left + portalWidth;
         $(".panImg").each(function(t) {
             var mapid  = "map_" + this.id.substring(4);
             var hDiv   = $(this).parent();
             var top    = parseInt($(this).css("top")) * -1;
             var bottom = top + $(hDiv).height();
 
             var span = mapTopAndBottom(mapid,left,right);
             if(span.top > 0) {
                 var topdif = Math.abs(span.top - top);
                 var botdif = Math.abs(span.bottom - bottom);
                 if(topdif > 2 || botdif > 2) {
                     $(hDiv).height( span.bottom - span.top );
                     top = span.top * -1;
@@ -1419,35 +1421,33 @@
                     if (compositeSet && compositeSet.length > 0)
                         $( compositeSet ).find('p.btn').removeClass('blueButtons');  // blue persists
                     if($(row).attr('rowIndex') != dragStartIndex) {
                         // NOTE Even if dragging a contiguous set of rows,
                         // still only need to check the one under the cursor.
                         if(imgTblSetOrder) {
                             imgTblSetOrder(table);
                         }
                         imgTblZipButtons( table );
                     }
                     $(document).unbind('mousemove',blockTheMapOnMouseMove);
                     setTimeout('blockUseMap=false;',50); // Necessary incase the onDrop was over a map item. onDrop takes precedence.
                 }
             });
         }
-        if(imgBoxPortal) {
-            //warn("imgBox("+imgBoxChromStart+"-"+imgBoxChromEnd+","+imgBoxWidth+") bases/pix:"+imgBoxBasesPerPixel+"\nportal("+imgBoxPortalStart+"-"+imgBoxPortalEnd+","+imgBoxPortalWidth+") offset:"+imgBoxPortalOffsetX);
-
+        if(hgTracks.imgBoxPortal) {
             // Turn on drag scrolling.
-            $("div.scroller").panImages(imgBoxPortalOffsetX,imgBoxLeftLabel);
+            $("div.scroller").panImages(hgTracks.imgBoxPortalOffsetX,hgTracks.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!');
         }
 
         // Retrieve tracks via AJAX that may take too long to draw initialliy (i.e. a remote bigWig)
         var retrievables = $('#imgTbl').find("tr.mustRetrieve")
         if($(retrievables).length > 0) {
             $(retrievables).each( function (i) {
                 var trackName = $(this).attr('id').substring(3);
                 updateTrackImg(trackName,"","");
             });
@@ -2491,30 +2491,33 @@
     }
 }
 
 function afterImgTblReload()
 {
 // Reload various UI widgets after updating imgTbl map.
     parseMap(null, true);
     $("map[name!=ideoMap]").each( function(t) { parseMap($(this, false));});
     initImgTblButtons();
     loadImgAreaSelect(false);
     // Do NOT reload context menu (otherwise we get the "context menu sticks" problem).
     // loadContextMenu($('#tr_' + id));
     if(trackImgTbl.tableDnDUpdate)
         trackImgTbl.tableDnDUpdate();
     reloadFloatingItem();
+    // Turn on drag scrolling.
+    if(hgTracks.imgBoxPortal) {
+        $("div.scroller").panImages(hgTracks.imgBoxPortalOffsetX,hgTracks.imgBoxLeftLabel);
 }
 
 function updateTrackImgForId(html, id)
 {
 // update row in imgTbl for given id.
 // return true if we successfully pull slice for id and update it in imgTrack.
     var str = "<TR id='tr_" + id + "'[^>]*>([\\s\\S]+?)</TR>";
     var reg = new RegExp(str);
     var a = reg.exec(html);
     if(a && a[1]) {
         $('#tr_' + id).html(a[1]);
         // NOTE: Want to examine the png? Uncomment:
         //var img = $('#tr_' + id).find("img[id^='img_data_']").attr('src');
         //warn("Just parsed image:<BR>"+img);
         return true;