pinch to zoom sort of works
authorBenjamin Stover <bstover@mozilla.com>
Tue, 07 Sep 2010 15:58:55 -0700
changeset 1995 f06aeb49340688d3122f5e1c94af5d6281e1b953
parent 1994 d625c178138fa01dc6722344b095239df7deec98
child 1996 ee1337f0134d05dad59b9c3af5d87c3b936891cb
push id1714
push userdougt@mozilla.com
push dateThu, 16 Sep 2010 02:04:21 +0000
pinch to zoom sort of works
app/mobile.js
chrome/content/AnimatedZoom.js
chrome/content/InputHandler.js
chrome/content/bindings/browser.js
chrome/content/bindings/browser.xml
chrome/content/browser.js
--- a/app/mobile.js
+++ b/app/mobile.js
@@ -32,17 +32,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #filter substitution
 
 // for browser.xml binding
-pref("toolkit.browser.cachePixelX", 500);
+pref("toolkit.browser.cachePixelX", 800);
 pref("toolkit.browser.cachePixelY", 2000);
 pref("toolkit.browser.recacheRatio", 50);
 
 pref("toolkit.defaultChromeURI", "chrome://browser/content/browser.xul");
 pref("general.useragent.compatMode.firefox", true);
 pref("browser.chromeURL", "chrome://browser/content/");
 
 pref("browser.tabs.warnOnClose", true);
--- a/chrome/content/AnimatedZoom.js
+++ b/chrome/content/AnimatedZoom.js
@@ -59,17 +59,17 @@ const animatedZoom = {
 
     Browser.hideSidebars();
     Browser.hideTitlebar();
     Browser.forceChromeReflow();
 
     this.beginTime = Date.now();
 
     // Check if zooming animations were occuring before.
-    if (this.zoomFrom) {
+    if (this.zoomRect) {
       this.zoomFrom = this.zoomRect;
     }
     else {
       let browserRect = Rect.fromRect(getBrowser().getBoundingClientRect());
       let scrollX = {}, scrollY = {};
       getBrowser().getPosition(scrollX, scrollY);
       this.zoomFrom = browserRect.translate(scrollX.value, scrollY.value);
       this.updateTo(this.zoomFrom);
@@ -91,17 +91,17 @@ const animatedZoom = {
     getBrowser()._frameLoader.setViewportScale(zoomLevel, zoomLevel);
     getBrowser()._frameLoader.scrollViewportTo(nextRect.left * zoomRatio, nextRect.top * zoomRatio);
     this.zoomRect = nextRect;
   },
 
   /** Stop animation, zoom to point, and clean up. */
   finish: function() {
     window.removeEventListener("MozBeforePaint", this, false);
-    Browser.setVisibleRect(this.zoomTo);
+    Browser.setVisibleRect(this.zoomTo || this.zoomRect);
     this.beginTime = null;
     this.zoomTo = null;
     this.zoomFrom = null;
     this.zoomRect = null;
   },
 
   handleEvent: function(aEvent) {
     try {
--- a/chrome/content/InputHandler.js
+++ b/chrome/content/InputHandler.js
@@ -1287,62 +1287,72 @@ GestureModule.prototype = {
     // terminate pinch zoom if ongoing
     if (this._pinchZoom) {
       this._pinchZoom.finish();
       this._pinchZoom = null;
     }
   },
 
   _pinchStart: function _pinchStart(aEvent) {
-    let bv = Browser._browserView;
     // start gesture if it's not taking place already, or over a XUL element
-    if (this._pinchZoom || (aEvent.target instanceof XULElement) || !bv.allowZoom)
+    if (this._pinchZoom || (aEvent.target instanceof XULElement) || !Browser.selectedTab.allowZoom)
       return;
 
     // grab events during pinch
     this._owner.grab(this);
 
     // hide element highlight
-    document.getElementById("tile-container").customClicker.panBegin();
+    // XXX ugh, this is awful. None of this code should be in InputHandler.
+    document.getElementById("inputhandler-overlay").customClicker.panBegin();
 
     // create the AnimatedZoom object for fast arbitrary zooming
-    this._pinchZoom = new AnimatedZoom(bv);
+    this._pinchZoom = animatedZoom;
 
     // start from current zoom level
-    this._pinchZoomLevel = bv.getZoomLevel();
+    this._pinchZoomLevel = getBrowser().scale;
     this._pinchDelta = 0;
     this._ignoreNextUpdate = true; // first update gives useless, huge delta
 
     // cache gesture limit values
     this._maxGrowth = Services.prefs.getIntPref("browser.ui.pinch.maxGrowth");
     this._maxShrink = Services.prefs.getIntPref("browser.ui.pinch.maxShrink");
     this._scalingFactor = Services.prefs.getIntPref("browser.ui.pinch.scalingFactor");
 
     // save the initial gesture start point as reference
     [this._pinchStartX, this._pinchStartY] =
         Browser.transformClientToBrowser(aEvent.clientX, aEvent.clientY);
+
+    let scrollX = {}, scrollY = {};
+    getBrowser().getPosition(scrollX, scrollY);
+    this._pinchStartX += scrollX.value;
+    this._pinchStartY += scrollY.value;
   },
 
   _pinchUpdate: function _pinchUpdate(aEvent) {
     if (!this._pinchZoom || !aEvent.delta)
       return;
 
     // Accumulate pinch delta. Changes smaller than 1 are just jitter.
     this._pinchDelta += aEvent.delta;
 
     // decrease the pinchDelta min/max values to limit zooming out/in speed
     let delta = Math.max(-this._maxShrink, Math.min(this._maxGrowth, this._pinchDelta));
     this._pinchZoomLevel *= (1 + delta / this._scalingFactor);
-    this._pinchZoomLevel = Browser._browserView.clampZoomLevel(this._pinchZoomLevel);
+    this._pinchZoomLevel = Browser.selectedTab.clampZoomLevel(this._pinchZoomLevel);
     this._pinchDelta = 0;
 
     // get current pinch position to calculate opposite vector for zoom point
     let [pX, pY] =
         Browser.transformClientToBrowser(aEvent.clientX, aEvent.clientY);
 
+    let scrollX = {}, scrollY = {};
+    getBrowser().getPosition(scrollX, scrollY);
+    pX += scrollX.value;
+    pY += scrollY.value;
+
     // redraw zoom canvas according to new zoom rect
     let rect = Browser._getZoomRectForPoint(2 * this._pinchStartX - pX,
                                             2 * this._pinchStartY - pY,
                                             this._pinchZoomLevel);
     this._pinchZoom.updateTo(rect);
   },
 
   _pinchEnd: function _pinchEnd(aEvent) {
--- a/chrome/content/bindings/browser.js
+++ b/chrome/content/bindings/browser.js
@@ -362,18 +362,18 @@ let ContentScroll =  {
         break;
 
       case "Content:SetCacheViewport": {
         let displayport = new Rect(json.x, json.y, json.w, json.h);
         if (displayport.isEmpty())
           break;
 
         let cwu = Util.getWindowUtils(content);
+        cwu.setResolution(json.zoomLevel, json.zoomLevel);
         cwu.setDisplayPort(displayport.x, displayport.y, displayport.width, displayport.height);
-        cwu.setResolution(json.zoomLevel, json.zoomLevel);
         break;
       }
 
       case "Content:SetCssViewportSize": {
         let cwu = Util.getWindowUtils(content);
         cwu.setCSSViewport(json.width, json.height);
         break;
       }
--- a/chrome/content/bindings/browser.xml
+++ b/chrome/content/bindings/browser.xml
@@ -430,25 +430,26 @@
            view. -->
       <field name="_recacheRatio">0</field>
 
       <!-- The cache viewport is what parts of content is cached in the parent process for
            fast scrolling. This syncs that up with the current projection viewport. -->
       <method name="_updateCacheViewport">
         <body>
           <![CDATA[
-            let offscreenX = this._pendingThresholdX / this._recacheRatio;
-            let offscreenY = this._pendingThresholdY / this._recacheRatio;
+            let cacheX = this._pendingThresholdX / this._recacheRatio;
+            let cacheY = this._pendingThresholdY / this._recacheRatio;
+            let bcr = this.getBoundingClientRect();
 
             let frameLoader = this._frameLoader;
             this.messageManager.sendAsyncMessage("Content:SetCacheViewport", {
-              x: (frameLoader.viewportScrollX - offscreenX) / this._zoomLevel,
-              y: (frameLoader.viewportScrollY - offscreenY) / this._zoomLevel,
-              w: (this._viewportWidthInCSSPx + offscreenX * 2) / this._zoomLevel,
-              h: (this._viewportHeightInCSSPx + offscreenY * 2) / this._zoomLevel,
+              x: (frameLoader.viewportScrollX + bcr.width  / 2 - cacheX) / this._zoomLevel,
+              y: (frameLoader.viewportScrollY + bcr.height / 2 - cacheY) / this._zoomLevel,
+              w: (cacheX * 2) / this._zoomLevel,
+              h: (cacheY * 2) / this._zoomLevel,
               zoomLevel: this._zoomLevel
             });
 
             this._pendingPixelsX = 0;
             this._pendingPixelsY = 0;
           ]]>
         </body>
       </method>
--- a/chrome/content/browser.js
+++ b/chrome/content/browser.js
@@ -444,16 +444,22 @@ var Browser = {
   get browsers() {
     return this._tabs.map(function(tab) { return tab.browser; });
   },
 
   scrollContentToTop: function scrollContentToTop() {
     this.contentScrollboxScroller.scrollTo(0, 0);
     this.pageScrollboxScroller.scrollTo(0, 0);
   },
+  
+  // cmd_scrollBottom does not work in Fennec (Bug 590535).
+  scrollContentToBottom: function scrollContentToBottom() {
+    this.contentScrollboxScroller.scrollTo(0, Number.MAX_VALUE);
+    this.pageScrollboxScroller.scrollTo(0, Number.MAX_VALUE);
+  },
 
   hideSidebars: function scrollSidebarsOffscreen() {
     let container = document.getElementById("browsers");
     let rect = container.getBoundingClientRect();
     this.controlsScrollboxScroller.scrollBy(Math.round(rect.left), 0);
   },
 
   hideTitlebar: function hideTitlebar() {