mobile/android/base/gfx/SubdocumentScrollHelper.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 package org.mozilla.gecko.gfx;
     8 import org.mozilla.gecko.GeckoAppShell;
     9 import org.mozilla.gecko.GeckoEvent;
    10 import org.mozilla.gecko.EventDispatcher;
    11 import org.mozilla.gecko.util.GeckoEventListener;
    13 import org.json.JSONException;
    14 import org.json.JSONObject;
    16 import android.graphics.PointF;
    17 import android.os.Handler;
    18 import android.util.Log;
    20 class SubdocumentScrollHelper implements GeckoEventListener {
    21     private static final String LOGTAG = "GeckoSubdocScroll";
    23     private static String MESSAGE_PANNING_OVERRIDE = "Panning:Override";
    24     private static String MESSAGE_CANCEL_OVERRIDE = "Panning:CancelOverride";
    25     private static String MESSAGE_SCROLL = "Gesture:Scroll";
    26     private static String MESSAGE_SCROLL_ACK = "Gesture:ScrollAck";
    28     private final Handler mUiHandler;
    29     private final EventDispatcher mEventDispatcher;
    31     /* This is the amount of displacement we have accepted but not yet sent to JS; this is
    32      * only valid when mOverrideScrollPending is true. */
    33     private final PointF mPendingDisplacement;
    35     /* When this is true, we're sending scroll events to JS to scroll the active subdocument. */
    36     private boolean mOverridePanning;
    38     /* When this is true, we have received an ack for the last scroll event we sent to JS, and
    39      * are ready to send the next scroll event. Note we only ever have one scroll event inflight
    40      * at a time. */
    41     private boolean mOverrideScrollAck;
    43     /* When this is true, we have a pending scroll that we need to send to JS; we were unable
    44      * to send it when it was initially requested because mOverrideScrollAck was not true. */
    45     private boolean mOverrideScrollPending;
    47     /* When this is true, the last scroll event we sent actually did some amount of scrolling on
    48      * the subdocument; we use this to decide when we have reached the end of the subdocument. */
    49     private boolean mScrollSucceeded;
    51     SubdocumentScrollHelper(EventDispatcher eventDispatcher) {
    52         // mUiHandler will be bound to the UI thread since that's where this constructor runs
    53         mUiHandler = new Handler();
    54         mPendingDisplacement = new PointF();
    56         mEventDispatcher = eventDispatcher;
    57         registerEventListener(MESSAGE_PANNING_OVERRIDE);
    58         registerEventListener(MESSAGE_CANCEL_OVERRIDE);
    59         registerEventListener(MESSAGE_SCROLL_ACK);
    60     }
    62     void destroy() {
    63         unregisterEventListener(MESSAGE_PANNING_OVERRIDE);
    64         unregisterEventListener(MESSAGE_CANCEL_OVERRIDE);
    65         unregisterEventListener(MESSAGE_SCROLL_ACK);
    66     }
    68     private void registerEventListener(String event) {
    69         mEventDispatcher.registerEventListener(event, this);
    70     }
    72     private void unregisterEventListener(String event) {
    73         mEventDispatcher.unregisterEventListener(event, this);
    74     }
    76     boolean scrollBy(PointF displacement) {
    77         if (! mOverridePanning) {
    78             return false;
    79         }
    81         if (! mOverrideScrollAck) {
    82             mOverrideScrollPending = true;
    83             mPendingDisplacement.x += displacement.x;
    84             mPendingDisplacement.y += displacement.y;
    85             return true;
    86         }
    88         JSONObject json = new JSONObject();
    89         try {
    90             json.put("x", displacement.x);
    91             json.put("y", displacement.y);
    92         } catch (JSONException e) {
    93             Log.e(LOGTAG, "Error forming subwindow scroll message: ", e);
    94         }
    95         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(MESSAGE_SCROLL, json.toString()));
    97         mOverrideScrollAck = false;
    98         mOverrideScrollPending = false;
    99         // clear the |mPendingDisplacement| after serializing |displacement| to
   100         // JSON because they might be the same object
   101         mPendingDisplacement.x = 0;
   102         mPendingDisplacement.y = 0;
   104         return true;
   105     }
   107     void cancel() {
   108         mOverridePanning = false;
   109     }
   111     boolean scrolling() {
   112         return mOverridePanning;
   113     }
   115     boolean lastScrollSucceeded() {
   116         return mScrollSucceeded;
   117     }
   119     // GeckoEventListener implementation
   121     @Override
   122     public void handleMessage(final String event, final JSONObject message) {
   123         // This comes in on the Gecko thread; hand off the handling to the UI thread.
   124         mUiHandler.post(new Runnable() {
   125             @Override
   126             public void run() {
   127                 try {
   128                     if (MESSAGE_PANNING_OVERRIDE.equals(event)) {
   129                         mOverridePanning = true;
   130                         mOverrideScrollAck = true;
   131                         mOverrideScrollPending = false;
   132                         mScrollSucceeded = true;
   133                     } else if (MESSAGE_CANCEL_OVERRIDE.equals(event)) {
   134                         mOverridePanning = false;
   135                     } else if (MESSAGE_SCROLL_ACK.equals(event)) {
   136                         mOverrideScrollAck = true;
   137                         mScrollSucceeded = message.getBoolean("scrolled");
   138                         if (mOverridePanning && mOverrideScrollPending) {
   139                             scrollBy(mPendingDisplacement);
   140                         }
   141                     }
   142                 } catch (Exception e) {
   143                     Log.e(LOGTAG, "Exception handling message", e);
   144                 }
   145             }
   146         });
   147     }
   148 }

mercurial