diff options
Diffstat (limited to 'android/source/src')
8 files changed, 198 insertions, 2 deletions
diff --git a/android/source/src/java/org/libreoffice/InvalidationHandler.java b/android/source/src/java/org/libreoffice/InvalidationHandler.java index c8d3a5123c11..af42cb131ff7 100644 --- a/android/source/src/java/org/libreoffice/InvalidationHandler.java +++ b/android/source/src/java/org/libreoffice/InvalidationHandler.java @@ -29,6 +29,8 @@ public class InvalidationHandler implements Document.MessageCallback { private boolean mKeyEvent = false; private LibreOfficeMainActivity mContext; + private int currentTotalPageNumber = 0; // total page number of the current document + public InvalidationHandler(LibreOfficeMainActivity context) { mContext = context; mDocumentOverlay = mContext.getDocumentOverlay(); @@ -196,6 +198,15 @@ public class InvalidationHandler implements Document.MessageCallback { mContext.getFormattingController().onToggleStateChanged(Document.BULLET_LIST, pressed); } else if (parts[0].equals(".uno:DefaultNumbering")) { mContext.getFormattingController().onToggleStateChanged(Document.NUMBERED_LIST, pressed); + } else if (parts[0].equals(".uno:StatePageNumber")) { + // get the total page number and compare to the current value and update accordingly + String[] splitStrings = parts[1].split(" "); + int totalPageNumber = Integer.valueOf(splitStrings[splitStrings.length - 1]); + if (totalPageNumber != currentTotalPageNumber) { + currentTotalPageNumber = totalPageNumber; + // update part page rectangles stored in DocumentOverlayView object + LOKitShell.sendEvent(new LOEvent(LOEvent.UPDATE_PART_PAGE_RECT)); + } } else { Log.d(LOGTAG, "LOK_CALLBACK_STATE_CHANGED type uncatched: " + payload); } @@ -207,7 +218,7 @@ public class InvalidationHandler implements Document.MessageCallback { * @param payload - invalidation message payload text * @return rectangle in pixel coordinates */ - private RectF convertPayloadToRectangle(String payload) { + public RectF convertPayloadToRectangle(String payload) { String payloadWithoutWhitespace = payload.replaceAll("\\s", ""); // remove all whitespace from the string if (payloadWithoutWhitespace.isEmpty() || payloadWithoutWhitespace.equals("EMPTY")) { @@ -241,7 +252,7 @@ public class InvalidationHandler implements Document.MessageCallback { * @param payload - invalidation message payload text * @return list of rectangles */ - private List<RectF> convertPayloadToRectangles(String payload) { + public List<RectF> convertPayloadToRectangles(String payload) { List<RectF> rectangles = new ArrayList<RectF>(); String[] rectangleArray = payload.split(";"); diff --git a/android/source/src/java/org/libreoffice/LOEvent.java b/android/source/src/java/org/libreoffice/LOEvent.java index 3e058c8c035e..f5579aea087a 100644 --- a/android/source/src/java/org/libreoffice/LOEvent.java +++ b/android/source/src/java/org/libreoffice/LOEvent.java @@ -36,6 +36,7 @@ public class LOEvent implements Comparable<LOEvent> { public static final int RESUME = 15; public static final int LOAD_NEW = 16; public static final int SAVE_AS = 17; + public static final int UPDATE_PART_PAGE_RECT= 18; public final int mType; public int mPriority = 0; diff --git a/android/source/src/java/org/libreoffice/LOKitThread.java b/android/source/src/java/org/libreoffice/LOKitThread.java index 4dd403dd2d0c..52a7c6c2f43a 100644 --- a/android/source/src/java/org/libreoffice/LOKitThread.java +++ b/android/source/src/java/org/libreoffice/LOKitThread.java @@ -155,6 +155,17 @@ class LOKitThread extends Thread { private void refresh() { mLayerClient.clearAndResetlayers(); redraw(); + updatePartPageRectangles(); + } + + /** + * Update part page rectangles which hold positions of each document page. + * Result is stored in DocumentOverlayView class. + */ + private void updatePartPageRectangles() { + String partPageRectString = ((LOKitTileProvider) mTileProvider).getPartPageRectangles(); + List<RectF> partPageRectangles = mInvalidationHandler.convertPayloadToRectangles(partPageRectString); + mContext.getDocumentOverlay().setPartPageRectangles(partPageRectangles); } @@ -319,6 +330,9 @@ class LOKitThread extends Thread { case LOEvent.UNO_COMMAND: mTileProvider.postUnoCommand(event.mString, event.mValue); break; + case LOEvent.UPDATE_PART_PAGE_RECT: + updatePartPageRectangles(); + break; } } diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java index 6ed73ee32805..1996a1b5bedd 100644 --- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java +++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java @@ -200,6 +200,13 @@ class LOKitTileProvider implements TileProvider { } /** + * Wrapper for getPartPageRectangles() JNI function. + */ + public String getPartPageRectangles() { + return mDocument.getPartPageRectangles(); + } + + /** * @see TileProvider#onSwipeLeft() */ @Override diff --git a/android/source/src/java/org/libreoffice/canvas/PageNumberRect.java b/android/source/src/java/org/libreoffice/canvas/PageNumberRect.java new file mode 100644 index 000000000000..62de88ea5441 --- /dev/null +++ b/android/source/src/java/org/libreoffice/canvas/PageNumberRect.java @@ -0,0 +1,64 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.libreoffice.canvas; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.text.TextPaint; + +/* + * A canvas element on DocumentOverlayView. Shows a rectangle with current page + * number and total page number inside of it. + */ +public class PageNumberRect extends CommonCanvasElement { + private String mPageNumberString; + private TextPaint mPageNumberRectPaint = new TextPaint(); + private Paint mBgPaint = new Paint(); + private Rect mTextBounds = new Rect(); + private float mBgMargin = 5f; + + public PageNumberRect() { + mBgPaint.setColor(Color.BLACK); + mBgPaint.setAlpha(100); + mPageNumberRectPaint.setColor(Color.WHITE); + } + + /** + * Implement hit test here + * + * @param x - x coordinate of the + * @param y - y coordinate of the + */ + @Override + public boolean onHitTest(float x, float y) { + return false; + } + + /** + * Called inside draw if the element is visible. Override this method to + * draw the element on the canvas. + * + * @param canvas - the canvas + */ + @Override + public void onDraw(Canvas canvas) { + canvas.drawRect(canvas.getWidth()*0.1f - mBgMargin, + canvas.getHeight()*0.1f - mTextBounds.height() - mBgMargin, + mTextBounds.width() + canvas.getWidth()*0.1f + mBgMargin, + canvas.getHeight()*0.1f + mBgMargin, + mBgPaint); + canvas.drawText(mPageNumberString, canvas.getWidth()*0.1f, canvas.getHeight()*0.1f, mPageNumberRectPaint); + } + + public void setPageNumberString (String pageNumberString) { + mPageNumberString = pageNumberString; + mPageNumberRectPaint.getTextBounds(mPageNumberString, 0, mPageNumberString.length(), mTextBounds); + } +} diff --git a/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java b/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java index 8d90ef09fa4a..d9d2b372b714 100644 --- a/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java +++ b/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java @@ -32,6 +32,8 @@ public class DocumentOverlay { private final DocumentOverlayView mDocumentOverlayView; private final DocumentOverlayLayer mDocumentOverlayLayer; + private final long hidePageNumberRectDelayInMilliseconds = 500; + /** * DocumentOverlayLayer responsibility is to get the changes to the viewport * and report them to DocumentOverlayView. @@ -74,6 +76,10 @@ public class DocumentOverlay { mDocumentOverlayView.initialize(layerView); } + public void setPartPageRectangles(List<RectF> rectangles) { + mDocumentOverlayView.setPartPageRectangles(rectangles); + } + /** * Show the cursor at the defined cursor position on the overlay. */ @@ -97,6 +103,28 @@ public class DocumentOverlay { } /** + * Show the page number rectangle on the overlay. + */ + public void showPageNumberRect() { + LOKitShell.getMainHandler().post(new Runnable() { + public void run() { + mDocumentOverlayView.showPageNumberRect(); + } + }); + } + + /** + * Hide the page number rectangle on the overlay. + */ + public void hidePageNumberRect() { + LOKitShell.getMainHandler().postDelayed(new Runnable() { + public void run() { + mDocumentOverlayView.hidePageNumberRect(); + } + }, hidePageNumberRectDelayInMilliseconds); + } + + /** * Position the cursor to the input position on the overlay. */ public void positionCursor(final RectF position) { diff --git a/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java b/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java index 48b98b4e7ca5..6afd71309d1d 100644 --- a/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java +++ b/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java @@ -21,6 +21,7 @@ import android.view.View; import org.libreoffice.LibreOfficeMainActivity; import org.libreoffice.canvas.Cursor; import org.libreoffice.canvas.GraphicSelection; +import org.libreoffice.canvas.PageNumberRect; import org.libreoffice.canvas.SelectionHandle; import org.libreoffice.canvas.SelectionHandleEnd; import org.libreoffice.canvas.SelectionHandleMiddle; @@ -62,6 +63,11 @@ public class DocumentOverlayView extends View implements View.OnTouchListener { private SelectionHandle mDragHandle = null; + private List<RectF> mPartPageRectangles; + private PageNumberRect mPageNumberRect; + private boolean mPageNumberAvailable = false; + private int previousIndex = 0; // previous page number, used to compare with the current + public DocumentOverlayView(Context context) { super(context); } @@ -177,6 +183,16 @@ public class DocumentOverlayView extends View implements View.OnTouchListener { } /** + * Set part page rectangles and initialize a page number rectangle object + * (canvas element). + */ + public void setPartPageRectangles (List<RectF> rectangles) { + mPartPageRectangles = rectangles; + mPageNumberRect = new PageNumberRect(); + mPageNumberAvailable = true; + } + + /** * Drawing on canvas. */ @Override @@ -185,6 +201,10 @@ public class DocumentOverlayView extends View implements View.OnTouchListener { mCursor.draw(canvas); + if (mPageNumberAvailable) { + mPageNumberRect.draw(canvas); + } + mHandleMiddle.draw(canvas); mHandleStart.draw(canvas); mHandleEnd.draw(canvas); @@ -233,6 +253,47 @@ public class DocumentOverlayView extends View implements View.OnTouchListener { } /** + * Calculate and show page number according to current viewport position. + * In particular, this function compares the middle point of the + * view port with page rectangles and finds out which page the user + * is currently on. It does not update the associated canvas element + * unless there is a change of page number. + */ + public void showPageNumberRect() { + PointF midPoint = mLayerView.getLayerClient().convertViewPointToLayerPoint(new PointF(getWidth()/2f, getHeight()/2f)); + int index = previousIndex; + // search which page the user in currently on. can enhance the search algorithm to binary search if necessary + for (RectF page : mPartPageRectangles) { + if (page.top < midPoint.y && midPoint.y < page.bottom) { + index = mPartPageRectangles.indexOf(page) + 1; + break; + } + } + // index == 0 applies to non-text document, i.e. don't show page info on non-text docs + if (index == 0) { + return; + } + // if page rectangle canvas element is not visible or the page number is changed, show + if (!mPageNumberRect.isVisible() || index != previousIndex) { + previousIndex = index; + String pageNumberString = "Page " + index + " of " + mPartPageRectangles.size(); + mPageNumberRect.setPageNumberString(pageNumberString); + mPageNumberRect.setVisible(true); + invalidate(); + } + } + + /** + * Hide page number rectangle canvas element. + */ + public void hidePageNumberRect() { + if (mPageNumberRect.isVisible()) { + mPageNumberRect.setVisible(false); + invalidate(); + } + } + + /** * Show text selection rectangles. */ public void showSelections() { diff --git a/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java index 7d7474eae0b4..ce6f4e9b99f7 100644 --- a/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java +++ b/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java @@ -498,6 +498,7 @@ class JavaPanZoomController ImmutableViewportMetrics bounceStartMetrics = getMetrics(); if (bounceStartMetrics.fuzzyEquals(metrics)) { setState(PanZoomState.NOTHING); + finishAnimation(); return; } @@ -689,6 +690,7 @@ class JavaPanZoomController */ float threshold = (overscrolled && !mSubscroller.scrolling() ? STOPPED_THRESHOLD : FLING_STOPPED_THRESHOLD); if (getVelocity() >= threshold) { + mContext.getDocumentOverlay().showPageNumberRect(); // we're still flinging return; } @@ -712,6 +714,8 @@ class JavaPanZoomController stopAnimationTimer(); + mContext.getDocumentOverlay().hidePageNumberRect(); + // Force a viewport synchronisation mTarget.forceRedraw(); } @@ -950,6 +954,12 @@ class JavaPanZoomController } @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + mContext.getDocumentOverlay().showPageNumberRect(); + return super.onScroll(e1, e2, distanceX, distanceY); + } + + @Override public boolean onSingleTapUp(MotionEvent motionEvent) { // When double-tapping is allowed, we have to wait to see if this is // going to be a double-tap. |