Kaydet (Commit) 5ccb510e authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

LOAndroid3: (partially) render page with LOKitTileProvider

+ TileProvider & TileIterator interfaces
+ Clean-up obsolete mozilla stuff

Change-Id: Ief56f11bf7f8fd6da383ffc7be3461b765bf0157
üst 9948d956
...@@ -16,16 +16,10 @@ import java.nio.ByteBuffer; ...@@ -16,16 +16,10 @@ import java.nio.ByteBuffer;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import org.libreoffice.kit.LibreOfficeKit;
import org.libreoffice.kit.Office;
import org.libreoffice.kit.Document;
public class LOKitThread extends Thread { public class LOKitThread extends Thread {
private static final String LOGTAG = "GeckoThread"; private static final String LOGTAG = "GeckoThread";
private static final int TILE_SIZE = 256; private static final int TILE_SIZE = 256;
private TileProvider mTileProvider;
public Office mOffice;
public Document mDocument;
public ConcurrentLinkedQueue<LOEvent> gEvents = new ConcurrentLinkedQueue<LOEvent>(); public ConcurrentLinkedQueue<LOEvent> gEvents = new ConcurrentLinkedQueue<LOEvent>();
private ViewportMetrics mViewportMetrics; private ViewportMetrics mViewportMetrics;
...@@ -33,55 +27,40 @@ public class LOKitThread extends Thread { ...@@ -33,55 +27,40 @@ public class LOKitThread extends Thread {
LOKitThread() { LOKitThread() {
} }
private void openDocument() { private boolean draw() throws InterruptedException {
// enable debugging messages as the first thing
LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO-INFO.legacy.osl-INFO.i18nlangtag");
LibreOfficeKit.init(LibreOfficeMainActivity.mAppContext);
mOffice = new Office(LibreOfficeKit.getLibreOfficeKitHandle());
String input = "/assets/test1.odt";
mDocument = mOffice.documentLoad(input);
}
private synchronized boolean draw() throws InterruptedException {
final LibreOfficeMainActivity application = LibreOfficeMainActivity.mAppContext; final LibreOfficeMainActivity application = LibreOfficeMainActivity.mAppContext;
openDocument(); if (mTileProvider == null)
mTileProvider = new LOKitTileProvider(application.getLayerController());
long height = mDocument.getDocumentHeight();
long width = mDocument.getDocumentWidth();
Log.e(LOGTAG, "Document Size: " + width + " " + height); int pageWidth = mTileProvider.getPageWidth();
int pageHeight = mTileProvider.getPageHeight();
int pageWidth = 1024; String metadata = createJson(0, 0, pageWidth, pageHeight, pageWidth, pageHeight, 0, 0, 1.0);
int pageHeight = 1024; mViewportMetrics = new ViewportMetrics();
String metadata = createJson(0, 0, 256, 256, pageWidth, pageHeight, 0, 0, 1.0); boolean shouldContinue = application.getLayerClient().beginDrawing(pageWidth, pageHeight, TILE_SIZE, TILE_SIZE, metadata);
Rect bufferRect = application.getLayerClient().beginDrawing(256, 256, TILE_SIZE, TILE_SIZE, metadata); if (!shouldContinue) {
/*if (bufferRect == null) {
Log.e(LOGTAG, "beginDrawing - false");
return false; return false;
}*/ }
Log.e(LOGTAG, "Filling tiles..");
ByteBuffer buffer = ByteBuffer.allocateDirect(TILE_SIZE * TILE_SIZE * 4);
Log.e(LOGTAG, "PaintTile..");
mDocument.paintTile(buffer, 256, 256, 1024, 1024, 4096, 4096);
Log.e(LOGTAG, "EndPaintTile.."); Log.i(LOGTAG, "Filling tiles..");
Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Bitmap.Config.ARGB_8888); int x = 0;
bitmap.copyPixelsFromBuffer(buffer); int y = 0;
for (Bitmap bitmap : mTileProvider.getTileIterator()) {
application.getLayerClient().addTile(bitmap, x, y);
x += TILE_SIZE;
if (x > pageWidth) {
x = 0;
y += TILE_SIZE;
}
}
application.getLayerClient().addTile(bitmap, 0, 0); Log.i(LOGTAG, "End Draw");
Log.e(LOGTAG, "EndDrawing.."); application.getLayerClient().endDrawing(0, 0, pageWidth, pageHeight);
application.getLayerClient().endDrawing(0, 0, 256, 256);
return true; return true;
} }
...@@ -143,22 +122,20 @@ public class LOKitThread extends Thread { ...@@ -143,22 +122,20 @@ public class LOKitThread extends Thread {
try { try {
boolean drawn = false; boolean drawn = false;
while (true) { while (true) {
if (!gEvents.isEmpty()) { if (!gEvents.isEmpty()) {
processEvent(gEvents.poll()); processEvent(gEvents.poll());
} else { } else {
if (!drawn) { if (!drawn) {
drawn = draw(); drawn = draw();
} }
Thread.sleep(2000L); Thread.sleep(100L);
} }
} }
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
} }
} }
private synchronized void processEvent(LOEvent event) throws InterruptedException { private void processEvent(LOEvent event) throws InterruptedException {
switch (event.mType) { switch (event.mType) {
case LOEvent.VIEWPORT: case LOEvent.VIEWPORT:
mViewportMetrics = event.getViewport(); mViewportMetrics = event.getViewport();
......
package org.libreoffice;
import android.graphics.Bitmap;
import android.util.Log;
import org.mozilla.gecko.gfx.LayerController;
import java.nio.ByteBuffer;
import java.util.Iterator;
import org.libreoffice.kit.LibreOfficeKit;
import org.libreoffice.kit.Office;
import org.libreoffice.kit.Document;
public class LOKitTileProvider implements TileProvider {
private final LayerController mLayerController;
public static int TILE_SIZE = 256;
public final Office mOffice;
public final Document mDocument;
public LOKitTileProvider(LayerController layerController) {
this.mLayerController = layerController;
LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO-INFO.legacy.osl-INFO.i18nlangtag");
LibreOfficeKit.init(LibreOfficeMainActivity.mAppContext);
mOffice = new Office(LibreOfficeKit.getLibreOfficeKitHandle());
String input = "/assets/test1.odt";
mDocument = mOffice.documentLoad(input);
}
@Override
public int getPageWidth() {
return (int) (mDocument.getDocumentWidth() / 1440.0 * LOKitShell.getDpi());
}
@Override
public int getPageHeight() {
return (int) (mDocument.getDocumentHeight() / 1440.0 * LOKitShell.getDpi());
}
public TileIterator getTileIterator() {
return new LoKitTileIterator();
}
public class LoKitTileIterator implements TileIterator, Iterator<Bitmap> {
private final double mTileWidth;
private final double mTileHeight;
private boolean mShouldContinue = true;
private double mPositionWidth = 0;
private double mPositionHeight = 0;
private double mPageWidth;
private double mPageHeight;
public LoKitTileIterator() {
mTileWidth = (TILE_SIZE / (double) LOKitShell.getDpi()) * 1440.0;
mTileHeight = (TILE_SIZE / (double) LOKitShell.getDpi()) * 1440.0;
mPageWidth = mDocument.getDocumentWidth();
mPageHeight = mDocument.getDocumentHeight();
}
@Override
public boolean hasNext() {
return mShouldContinue;
}
@Override
public Bitmap next() {
ByteBuffer buffer = ByteBuffer.allocateDirect(TILE_SIZE * TILE_SIZE * 4);
Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Bitmap.Config.ARGB_8888);
mDocument.paintTile(buffer, TILE_SIZE, TILE_SIZE, (int) mPositionWidth, (int) mPositionHeight, (int) mTileWidth, (int) mTileHeight);
mPositionWidth += mTileWidth;
if (mPositionWidth > mPageWidth) {
mPositionHeight += mTileHeight;
mPositionWidth = 0;
}
if (mPositionHeight > mPageHeight || mPositionHeight > 20000) {
mShouldContinue = false;
}
bitmap.copyPixelsFromBuffer(buffer);
return bitmap;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public Iterator<Bitmap> iterator() {
return this;
}
}
}
...@@ -11,8 +11,6 @@ import android.view.MotionEvent; ...@@ -11,8 +11,6 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.os.Environment;
import java.io.File;
import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient; import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
import org.mozilla.gecko.gfx.LayerController; import org.mozilla.gecko.gfx.LayerController;
...@@ -63,10 +61,12 @@ public class LibreOfficeMainActivity extends Activity { ...@@ -63,10 +61,12 @@ public class LibreOfficeMainActivity extends Activity {
mAppContext = this; mAppContext = this;
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate"); Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate");
setContentView(R.layout.activity_main);
// setup gecko layout // setup gecko layout
mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout); mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
mMainLayout = (LinearLayout) findViewById(R.id.main_layout); mMainLayout = (LinearLayout) findViewById(R.id.main_layout);
......
package org.libreoffice;
import android.graphics.Bitmap;
import org.apache.http.MethodNotSupportedException;
import org.mozilla.gecko.gfx.LayerController;
import java.util.Iterator;
import java.util.List;
public class MockTileProvider implements TileProvider {
private final LayerController layerController;
public MockTileProvider(LayerController layerController) {
this.layerController = layerController;
}
@Override
public int getPageWidth() {
return 549;
}
@Override
public int getPageHeight() {
return 630;
}
public TileIterator getTileIterator() {
return new MockTileIterator(layerController);
}
public class MockTileIterator implements TileIterator, Iterator<Bitmap> {
private final LayerController layerController;
private int tileNumber = 1;
public MockTileIterator(LayerController layerController) {
this.layerController = layerController;
}
@Override
public boolean hasNext() {
return tileNumber <= 9;
}
@Override
public Bitmap next() {
String imageName = "d" + tileNumber;
tileNumber++;
Bitmap bitmap = layerController.getDrawable(imageName);
return bitmap;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public Iterator<Bitmap> iterator() {
return this;
}
}
}
package org.libreoffice;
import android.graphics.Bitmap;
public interface TileIterator extends Iterable<Bitmap> {
}
package org.libreoffice;
import android.graphics.Bitmap;
import java.util.List;
public interface TileProvider {
int getPageWidth();
int getPageHeight();
TileIterator getTileIterator();
}
...@@ -41,7 +41,7 @@ package org.mozilla.gecko.gfx; ...@@ -41,7 +41,7 @@ package org.mozilla.gecko.gfx;
import org.libreoffice.LOKitShell; import org.libreoffice.LOKitShell;
import org.mozilla.gecko.gfx.CairoImage; import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.IntSize; import org.mozilla.gecko.gfx.IntSize;
import org.mozilla.gecko.gfx.LayerClient; import org.mozilla.gecko.gfx.GeckoLayerClient;
import org.mozilla.gecko.gfx.LayerController; import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.LayerRenderer; import org.mozilla.gecko.gfx.LayerRenderer;
import org.mozilla.gecko.gfx.MultiTileLayer; import org.mozilla.gecko.gfx.MultiTileLayer;
...@@ -77,20 +77,11 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient { ...@@ -77,20 +77,11 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
mFormat = CairoImage.FORMAT_ARGB32; mFormat = CairoImage.FORMAT_ARGB32;
} }
/*protected void finalize() throws Throwable {
try {
if (mBuffer != null)
LOKitShell.freeDirectBuffer(mBuffer);
mBuffer = null;
} finally {
super.finalize();
}
}*/
public void setLayerController(LayerController layerController) { public void setLayerController(LayerController layerController) {
super.setLayerController(layerController); super.setLayerController(layerController);
layerController.setRoot(mTileLayer); layerController.setRoot(mTileLayer);
if (mGeckoViewport != null) { if (mGeckoViewport != null) {
layerController.setViewportMetrics(mGeckoViewport); layerController.setViewportMetrics(mGeckoViewport);
} }
...@@ -104,7 +95,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient { ...@@ -104,7 +95,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
if(mTileLayer == null) if(mTileLayer == null)
mTileLayer = new MultiTileLayer(TILE_SIZE); mTileLayer = new MultiTileLayer(TILE_SIZE);
getLayerController().setRoot(mTileLayer); mLayerController.setRoot(mTileLayer);
// Force a resize event to be sent because the results of this // Force a resize event to be sent because the results of this
// are different depending on what tile system we're using // are different depending on what tile system we're using
...@@ -114,22 +105,11 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient { ...@@ -114,22 +105,11 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
} }
@Override @Override
protected boolean shouldDrawProceed(int tileWidth, int tileHeight) { public boolean beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
// Make sure the tile-size matches. If it doesn't, we could crash trying boolean shouldContinue = super.beginDrawing(width, height, tileWidth, tileHeight, metadata);
// to access invalid memory.
if (tileWidth != TILE_SIZE.width || tileHeight != TILE_SIZE.height) {
Log.e(LOGTAG, "Aborting draw, incorrect tile size of " + tileWidth + "x" + tileHeight);
return false;
}
return true;
}
@Override
public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) {
Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight, metadata);
if (bufferRect == null) { if (!shouldContinue) {
return bufferRect; return shouldContinue;
} }
// If the window size has changed, reallocate the buffer to match. // If the window size has changed, reallocate the buffer to match.
...@@ -137,7 +117,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient { ...@@ -137,7 +117,7 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
mBufferSize = new IntSize(width, height); mBufferSize = new IntSize(width, height);
} }
return bufferRect; return shouldContinue;
} }
@Override @Override
...@@ -147,76 +127,6 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient { ...@@ -147,76 +127,6 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
} }
} }
/*private void copyPixelsFromMultiTileLayer(Bitmap target) {
Canvas c = new Canvas(target);
ByteBuffer tileBuffer = mBuffer.slice();
int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8;
for (int y = 0; y < mBufferSize.height; y += TILE_SIZE.height) {
for (int x = 0; x < mBufferSize.width; x += TILE_SIZE.width) {
// Calculate tile size
IntSize tileSize = new IntSize(Math.min(mBufferSize.width - x, TILE_SIZE.width),
Math.min(mBufferSize.height - y, TILE_SIZE.height));
// Create a Bitmap from this tile
Bitmap tile = Bitmap.createBitmap(tileSize.width, tileSize.height,
CairoUtils.cairoFormatTobitmapConfig(mFormat));
tile.copyPixelsFromBuffer(tileBuffer.asIntBuffer());
// Copy the tile to the master Bitmap and recycle it
c.drawBitmap(tile, x, y, null);
tile.recycle();
// Progress the buffer to the next tile
tileBuffer.position(tileSize.getArea() * bpp);
tileBuffer = tileBuffer.slice();
}
}
}*/
@Override
protected void tileLayerUpdated() {
/* No-op. */
}
@Override
public Bitmap getBitmap() {
if (mTileLayer == null)
return null;
// Begin a tile transaction, otherwise the buffer can be destroyed while
// we're reading from it.
/*beginTransaction(mTileLayer);
try {
if (mBuffer == null || mBufferSize.width <= 0 || mBufferSize.height <= 0)
return null;
try {
Bitmap b = null;
if (mTileLayer instanceof MultiTileLayer) {
b = Bitmap.createBitmap(mBufferSize.width, mBufferSize.height,CairoUtils.cairoFormatTobitmapConfig(mFormat));
copyPixelsFromMultiTileLayer(b);
} else {
Log.w(LOGTAG, "getBitmap() called on a layer (" + mTileLayer + ") we don't know how to get a bitmap from");
}
return b;
} catch (OutOfMemoryError oom) {
Log.w(LOGTAG, "Unable to create bitmap", oom);
return null;
}
} finally {
endTransaction(mTileLayer);
}*/
return null;
}
@Override
public int getType() {
return LAYER_CLIENT_TYPE_SOFTWARE;
}
@Override @Override
protected IntSize getBufferSize() { protected IntSize getBufferSize() {
return new IntSize( return new IntSize(
...@@ -235,3 +145,4 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient { ...@@ -235,3 +145,4 @@ public class GeckoSoftwareLayerClient extends GeckoLayerClient {
} }
} }
} }
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Android code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009-2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Walton <pcwalton@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* 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 ***** */
package org.mozilla.gecko.gfx;
/**
* A layer client provides tiles and manages other information used by the layer controller.
*/
public abstract class LayerClient {
private LayerController mLayerController;
public abstract void geometryChanged();
public abstract void viewportSizeChanged();
protected abstract void render();
public LayerController getLayerController() {
return mLayerController;
}
public void setLayerController(LayerController layerController) {
mLayerController = layerController;
}
/**
* A utility function for calling Layer.beginTransaction with the
* appropriate LayerView.
*/
public void beginTransaction(Layer aLayer) {
if (mLayerController != null) {
LayerView view = mLayerController.getView();
if (view != null) {
aLayer.beginTransaction(view);
return;
}
}
aLayer.beginTransaction();
}
// Included for symmetry.
public void endTransaction(Layer aLayer) {
aLayer.endTransaction();
}
}
...@@ -88,7 +88,7 @@ public class LayerController { ...@@ -88,7 +88,7 @@ public class LayerController {
private boolean mWaitForTouchListeners; private boolean mWaitForTouchListeners;
private PanZoomController mPanZoomController; private PanZoomController mPanZoomController;
private OnTouchListener mOnTouchListener; /* The touch listener. */ private OnTouchListener mOnTouchListener; /* The touch listener. */
private LayerClient mLayerClient; /* The layer client. */ private GeckoLayerClient mLayerClient; /* The layer client. */
/* The new color for the checkerboard. */ /* The new color for the checkerboard. */
private int mCheckerboardColor; private int mCheckerboardColor;
private boolean mCheckerboardShouldShowChecks; private boolean mCheckerboardShouldShowChecks;
...@@ -111,11 +111,11 @@ public class LayerController { ...@@ -111,11 +111,11 @@ public class LayerController {
mForceRedraw = true; mForceRedraw = true;
} }
public LayerClient getLayerClient() { public GeckoLayerClient getLayerClient() {
return mLayerClient; return mLayerClient;
} }
public void setLayerClient(LayerClient layerClient) { public void setLayerClient(GeckoLayerClient layerClient) {
mLayerClient = layerClient; mLayerClient = layerClient;
layerClient.setLayerController(this); layerClient.setLayerController(this);
} }
......
...@@ -88,7 +88,7 @@ abstract class Axis { ...@@ -88,7 +88,7 @@ abstract class Axis {
private float mTouchPos; /* Position of the most recent touch event on the current drag. */ private float mTouchPos; /* Position of the most recent touch event on the current drag. */
private float mLastTouchPos; /* Position of the touch event before touchPos. */ private float mLastTouchPos; /* Position of the touch event before touchPos. */
private float mVelocity; /* Velocity in this direction; pixels per animation frame. */ private float mVelocity; /* Velocity in this direction; pixels per animation frame. */
public boolean mScrollingDisabled; /* Whether movement on this axis is locked. */ private boolean mScrollingDisabled; /* Whether movement on this axis is locked. */
private boolean mDisableSnap; /* Whether overscroll snapping is disabled. */ private boolean mDisableSnap; /* Whether overscroll snapping is disabled. */
private float mDisplacement; private float mDisplacement;
...@@ -147,7 +147,7 @@ abstract class Axis { ...@@ -147,7 +147,7 @@ abstract class Axis {
} }
private Overscroll getOverscroll() { private Overscroll getOverscroll() {
boolean minus = (getOrigin() < 0.0f); boolean minus = getOrigin() < 0.0f;
boolean plus = (getViewportEnd() > getPageLength()); boolean plus = (getViewportEnd() > getPageLength());
if (minus && plus) { if (minus && plus) {
return Overscroll.BOTH; return Overscroll.BOTH;
...@@ -164,10 +164,14 @@ abstract class Axis { ...@@ -164,10 +164,14 @@ abstract class Axis {
// overscrolled on this axis, returns 0. // overscrolled on this axis, returns 0.
private float getExcess() { private float getExcess() {
switch (getOverscroll()) { switch (getOverscroll()) {
case MINUS: return -getOrigin(); case MINUS:
case PLUS: return getViewportEnd() - getPageLength(); return -getOrigin();
case BOTH: return getViewportEnd() - getPageLength() - getOrigin(); case PLUS:
default: return 0.0f; return getViewportEnd() - getPageLength();
case BOTH:
return getViewportEnd() - getPageLength() - getOrigin();
default:
return 0.0f;
} }
} }
...@@ -176,8 +180,7 @@ abstract class Axis { ...@@ -176,8 +180,7 @@ abstract class Axis {
* possible and this axis has not been scroll locked while panning. Otherwise, returns false. * possible and this axis has not been scroll locked while panning. Otherwise, returns false.
*/ */
private boolean scrollable() { private boolean scrollable() {
return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE && return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE && !mScrollingDisabled;
!mScrollingDisabled;
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment