]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/commitdiff
Improve PDF viewer implementation make PDF loading asynchronous
authorMichal Horn <hornmich@fel.cvut.cz>
Mon, 16 Feb 2015 15:40:13 +0000 (16:40 +0100)
committerMichal Horn <hornmich@fel.cvut.cz>
Mon, 16 Feb 2015 15:40:13 +0000 (16:40 +0100)
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfPageView.java
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfViewActivity.java
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfViewerException.java [new file with mode: 0644]
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/SceneView.java [deleted file]
QRScanner/glass/src/main/res/layout/activity_pdf_view.xml
QRScanner/glass/src/main/res/values/strings.xml

index ffa8d1c2436fc5b02c6a61564ecea8ceb2aa13c4..66a99e62c4aa42ffeab6e5a5d88b5655cf2d3450 100644 (file)
@@ -4,32 +4,302 @@ import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.util.Log;
 import android.view.View;
 
+import java.io.File;
+import java.sql.Time;
+
+import cz.cvut.fel.dce.qrscanner.mupdf.MuPDFCore;
+
 /**
- * Created by michal on 16.2.15.
+ * Created by Michal Horn on 16.2.15.
  */
-public class PdfPageView  extends SceneView {
-       private Bitmap mPdfBitmap;
-       private Paint mBitmapPaint;
+public class PdfPageView  extends View {
+       /**
+        * Value with some allowed minimum and maximum.
+        * @author Michal Horn
+        *
+        * @param <T> some comparable numeric data type
+        */
+       class IntervalValue<T extends Number & Comparable<? super T>> {
+               /**
+                * Stored value
+                */
+               private T mValue;
+               /**
+                * The lowest allowed value. All values stored in the object are
+                * higher or equal this minimum.
+                */
+               private T mMinimum;
+               /**
+                * The highest allowed value. All values stored in the object are
+                * lower or equal this maximum.
+                */
+               private T mMaximum;
+
+               /**
+                * Class constructor.
+                * Creates object that represents a value in range <minimum; maximum>.
+                *
+                * @param defValue      Value to be stored in the object. Must be in the allowed range specified by other two parameters.
+                * @param minimum       The lowes allowed value to be stored in the object.
+                * @param maximum       The highest allowed value to be stored in the object.
+                * @throws Exception Throwed when minimal, maximal or inserted value were rejected.
+                */
+               public IntervalValue(T defValue, T minimum, T maximum) throws Exception {
+                       setMinimum(minimum);
+                       setMaximum(maximum);
+                       if (!setValue(defValue)) {
+                               throw new Exception("Provided value is not in the range.");
+                       }
+               }
+
+               /**
+                * Store value in the object. The value must lie between the minimum and maximum
+                * defined for the object.
+                * @param value value to be stored in the object
+                * @return true - vale was stored successfully,<br>false - value could not be inserted because it was out of range.
+                */
+               public boolean setValue(T value) {
+                       if (value.compareTo(mMinimum) >= 0 && value.compareTo(mMaximum) <= 0) {
+                               mValue = value;
+                               return true;
+                       }
+                       else {
+                               return false;
+                       }
+               }
+
+               /**
+                * Set minimum for values in the object.
+                * Last inserted value is not changed even if it is lower then the new minimum.
+                * @param min new allowed minimum for the values stored to the object.
+                * @throws Exception throwed when new minimum is higher than old maximum.
+                */
+               public void setMinimum(T min) throws Exception {
+                       if (mMaximum != null && mMinimum != null &&  mMinimum.compareTo(mMaximum) > 0) {
+                               throw new Exception("Minimum is higher then maximum.");
+                       }
+                       mMinimum = min;
+               }
+
+               /**
+                * Set maximum for values in the object.
+                * Last inserted value is not changed even if it is higher then the new maximum.
+                * @param max new allowed maximum for the values stored to the object.
+                * @throws Exception throwed when new maximum is lower than old minimum.
+                */
+               public void setMaximum(T max) throws Exception {
+                       if (mMinimum != null && mMaximum != null &&  mMaximum.compareTo(mMinimum) < 0) {
+                               throw new Exception("Maximum is lower then minimum.");
+                       }
+                       mMaximum = max;
+               }
+
+               /**
+                * Get value stored in the object
+                * @return value stored in the object.
+                */
+               public T getValue() {
+                       return mValue;
+               }
+
+               /**
+                * Get the lowest allowed value that can be stored in the object.
+                * @return minimal value
+                */
+               public T getMinimum() {
+                       return mMinimum;
+               }
+
+               /**
+                * Get the highest allowed value that can be stored in the object.
+                * @return maximal value
+                */
+               public T getMaximum() {
+                       return mMaximum;
+               }
+       }
+
+       /**
+        * Interface for events generated by the view
+        * @author Michal Horn
+        *
+        */
+       public interface SceneChange {
+               /**
+                * Invoked every time when the scene should be redrawed.
+                * @param source
+                */
+               public void onViewChanged(PdfPageView source);
+
+               /**
+                * Invoked once the PDF page is loaded and prepared as a bitmap to be shown
+                * @param source
+                */
+               public void onPageLoaded(PdfPageView source);
+       }
+
+       public static final String TAG = "PdfPageView";
+       protected Paint mPaint;
+       protected IntervalValue<Float> mZoom;
+       protected IntervalValue<Float> mXPosition;
+       protected IntervalValue<Float> mYPosition;
+       protected SceneChange mListener;
+       protected float mSceneHeight;
+       protected float mSceneWidth;
+       protected Bitmap mPdfBitmap;
+       protected File mPdfFile;
+       protected Boolean mPageLoaded;
+       private MuPDFCore mPdfCore;
+       private IntervalValue<Integer> mPage;
+       private MuPDFCore.Cookie mPdfCookie;
+
+       public PdfPageView(Context context, String filePath) throws Exception {
+               super(context);
+               mPageLoaded = false;
+               mPdfFile = new File(filePath);
+               if (!mPdfFile.exists()) {
+                       throw new PdfViewerException("File " + filePath + " does not exist.");
+               }
+               mPaint = new Paint();
+               mPdfCore = new MuPDFCore(context, mPdfFile.getAbsolutePath());
+               mPdfCookie = mPdfCore.new Cookie();
+               if (mPdfCore == null) {
+                       throw new PdfViewerException("The PDF file could not be loaded.");
+               }
+               mPage = new IntervalValue<>(0, 0, mPdfCore.countPages()-1);
+               Log.i(TAG, "Pages: " + mPage.toString());
+       }
+
+       public int getActualPage() {
+               return mPage.getValue();
+       }
+
+       public int getLastPage() {
+               return mPage.getMaximum();
+       }
+
+       public boolean setPage(int page) {
+               return mPage.setValue(page);
+       }
+
+       public void loadPage() {
+               long startTime = System.currentTimeMillis();
+               try {
+                       Log.i(TAG, "Loading PDF page " + getActualPage());
+                       mSceneWidth = mPdfCore.getPageSize(getActualPage()).x;
+                       mSceneHeight = mPdfCore.getPageSize(getActualPage()).y;
+                       Log.i(TAG, "Page size: " + mSceneWidth + "x" + mSceneHeight);
+                       Bitmap.Config mPdfBitmapConf = Bitmap.Config.ARGB_8888;
+                       mPdfBitmap = Bitmap.createBitmap((int)mSceneWidth, (int)mSceneHeight, mPdfBitmapConf);
+                       mPdfCore.drawPage(mPdfBitmap, 0, (int) mSceneWidth, (int) mSceneHeight, 0, 0, (int) mSceneWidth, (int) mSceneHeight, mPdfCookie);
+
+                       mXPosition = new IntervalValue<>(0.0f, -mSceneWidth, mSceneWidth);
+                       mYPosition = new IntervalValue<>(0.0f, -mSceneHeight, mSceneHeight);
+                       mZoom = new IntervalValue<>(0.2f, 0.2f, 10.0f);
+               } catch (Exception e) {
+                       Log.e(TAG, "Error in setting page dimensions.");
+                       e.printStackTrace();
+               }
+               long endTime = System.currentTimeMillis();
+               mPageLoaded = true;
+               Log.i(TAG, "PDF page loaded in " + Long.toString(endTime - startTime) + "ms.");
+               if (mListener != null) {
+                       mListener.onPageLoaded(this);
+               }
+       }
+
+       /**
+        * Set a listener of the events
+        * @param listener listener of the events
+        */
+       public void setListener(SceneChange listener) {
+               mListener = listener;
+       }
+
+       public void clearListener() {
+               mListener = null;
+       }
+
+       /**
+        * Zoom scene function. The scene can be zoomed in or out only in limits
+        * defined in constructor.
+        * @param deltaRatio when > 0 - zoom in,<br> when < 0 - zoom out
+        */
+       public  void zoom(float deltaRatio) {
+               if (!mPageLoaded) return;
+               float ratio = mZoom.getValue();
+               ratio += deltaRatio;
+               if (mZoom.setValue(ratio) == true && mListener != null) {
+                       mListener.onViewChanged(this);
+               }
+       }
+
+       /**
+        * Move scene function. The scene can be moved only in the rectangle specified
+        * by limits defined in constructor.
+        * @param x change of the x coordinate relatively to the actual position
+        * @param y change of the y coordinate relatively to the actual position
+        */
+       public void move(float x, float y) {
+               if (!mPageLoaded) return;
+               boolean xWasSet = mXPosition.setValue(mXPosition.getValue() + x/mZoom.getValue()*2.2f);
+               boolean yWasSet = mYPosition.setValue(mYPosition.getValue() + y/mZoom.getValue()*2.2f);
+
+               if ((xWasSet || yWasSet) && mListener != null) {
+                       mListener.onViewChanged(this);
+               }
+       }
+       /**
+        * @return actual scene zoom ratio
+        */
+       public float getZoomRatio() {
+               return mZoom.getValue();
+       }
+
+       /**
+        * @return actual scene position on X axis
+        */
+       public float getXPosition() {
+               return mXPosition.getValue();
+       }
+
+       /**
+        * @return actual scene positoin on Y axis
+        */
+       public float getYPosition() {
+               return mYPosition.getValue();
+       }
+
+       /**
+        * @return how tall the scene is
+        */
+       public float getSceneHeight() {
+               return mSceneHeight;
+       }
 
-       public PdfPageView(Context context, Bitmap pdfBitmap, float defZoom, float minZoom, float maxZoom, float defXCenter, float minX, float maxX, float defYCenter, float minY, float maxY) throws Exception {
-               super(context, defZoom, minZoom, maxZoom, defXCenter, minX, maxX, defYCenter, minY, maxY);
-               mPdfBitmap = Bitmap.createBitmap(pdfBitmap);
-               mBitmapPaint = new Paint();
+       /**
+        * @return how wide the scene is
+        */
+       public float getSceneWidth() {
+               return mSceneWidth;
        }
 
        @Override
-       protected void computeSceneDimmensions() {
-               mSceneWidth = mPdfBitmap.getWidth();
-               mSceneHeight = mPdfBitmap.getHeight();
+       protected void onDraw(Canvas c) {
+               if (!mPageLoaded) return;
+               draw(c);
+               super.onDraw(c);
        }
 
        @Override
        public void draw(Canvas c) {
+               if (!mPageLoaded) return;
                c.translate(c.getWidth()/2, c.getHeight()/2);
                c.scale(mZoom.getValue(), mZoom.getValue());
                c.translate(-mXPosition.getValue(), -mYPosition.getValue());
-               c.drawBitmap(mPdfBitmap, 0, 0, mBitmapPaint);
+               c.drawBitmap(mPdfBitmap, 0, 0, mPaint);
        }
 }
index 1ad54ae310926d6bed55dd4b62d5240e13cb8d06..2ff961a9dd3da408aeede1647ef25f2b05807468 100644 (file)
@@ -3,42 +3,54 @@ package cz.cvut.fel.dce.qrscanner.pdfviewer;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
-import android.graphics.Bitmap;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.os.AsyncTask;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
 import android.widget.Toast;
 
 import java.io.File;
 
 import cz.cvut.fel.dce.qrscanner.R;
-import cz.cvut.fel.dce.qrscanner.mupdf.MuPDFCore;
 
-public class PdfViewActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener, SceneView.SceneChange, SensorEventListener {
+public class PdfViewActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener, PdfPageView.SceneChange, SensorEventListener {
+
+       enum ViewStates {
+               SCROLLING,
+               VIEWING
+       };
+
        public static final String TAG = "PdfViewActivity";
 
        private FrameLayout mPdfImageContainer;
+       private TextView mCurrentPageNumber;
+       private TextView mLastPageNumber;
+       private TextView mViewerStateText;
        private ViewTreeObserver mPreviewImgObserver;
        private String mFilePath;
        private PdfPageView mPdfView;
        private Boolean mPdfLoaded = false;
        private SensorManager mSensorManager;
+       private ViewStates mViewStates;
+       private RelativeLayout mProgressContainer;
 
        /**
         * Start position of the gesture on touchpad
         */
        private float startX;
 
-
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
@@ -46,6 +58,12 @@ public class PdfViewActivity extends Activity implements ViewTreeObserver.OnGlob
                mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
                setContentView(R.layout.activity_pdf_view);
                mPdfImageContainer = (FrameLayout) findViewById(R.id.pdf_view_container);
+               mCurrentPageNumber = (TextView) findViewById(R.id.page_number);
+               mLastPageNumber = (TextView) findViewById(R.id.total_pages_num);
+               mViewerStateText = (TextView) findViewById(R.id.pdf_viewer_state);
+               mViewStates = ViewStates.SCROLLING;
+               mProgressContainer = (RelativeLayout) findViewById(R.id.progress_container);
+
                if (mPdfImageContainer != null) {
                        mPreviewImgObserver = mPdfImageContainer.getViewTreeObserver();
                        Log.i(TAG, "Registering mPreviewImgObserver OnGlobalLayoutListener.");
@@ -127,22 +145,15 @@ public class PdfViewActivity extends Activity implements ViewTreeObserver.OnGlob
                try {
                        String picturePath = mFilePath;
                        Log.i(TAG, "Path to component files: " + picturePath);
-
-                       MuPDFCore core = new MuPDFCore(getApplicationContext(), picturePath);
-                       Log.d(TAG, "numpages: "+ core.countPages());
-                       MuPDFCore.Cookie cookie = core.new Cookie();
-                       int pageW = (int)core.getPageSize(0).x;
-                       int pageH = (int)core.getPageSize(0).y;
-                       Log.d(TAG, "page size: " + pageW + ", " + pageH);
-                       Bitmap.Config mPdfBitmapConf = Bitmap.Config.ARGB_8888;
-                       Bitmap mPdfBitmap = Bitmap.createBitmap(pageW, pageH, mPdfBitmapConf);
-                       core.drawPage(mPdfBitmap, 0, pageW, pageH,0 , 0, pageW, pageH, cookie);
-                       mPdfView = new PdfPageView(getApplicationContext(), mPdfBitmap, 0, 0, 100, (float) mPdfBitmap.getWidth()/2, 0, (float) mPdfBitmap.getWidth(), (float) mPdfBitmap.getHeight()/2, 0, (float) mPdfBitmap.getHeight());
+                       mPdfView = new PdfPageView(getApplicationContext(), picturePath);
+                       mCurrentPageNumber.setText(Integer.toString(mPdfView.getActualPage()+1));
+                       mLastPageNumber.setText(Integer.toString(mPdfView.getLastPage()+1));
                        mPdfView.setListener(this);
-                       mPdfView.setDefaultValues(0, 0, 0);
+                       mPdfView.setPage(0);
+                       new LoadPageTask().execute();
+
+
                        if (mPdfImageContainer != null) {
-                               mPdfImageContainer.addView(mPdfView);
-                               mPdfImageContainer.invalidate();
                                mPdfLoaded = true;
                        }
                        else {
@@ -176,13 +187,6 @@ public class PdfViewActivity extends Activity implements ViewTreeObserver.OnGlob
                return super.onGenericMotionEvent(event);
        }
 
-       @Override
-       public void onSceneChanged(SceneView source) {
-               if (mPdfView != null) {
-                       mPdfView.invalidate();
-               }
-       }
-
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
 
@@ -198,4 +202,40 @@ public class PdfViewActivity extends Activity implements ViewTreeObserver.OnGlob
                        }
                }
        }
+
+       @Override
+       public void onViewChanged(PdfPageView source) {
+               if (mPdfView != null) {
+                       mPdfView.invalidate();
+               }
+       }
+
+       @Override
+       public void onPageLoaded(PdfPageView source) {
+
+       }
+
+       private class LoadPageTask extends AsyncTask<Void, Void, Void> {
+
+               @Override
+               protected Void doInBackground(Void[] objects) {
+                       mPdfView.loadPage();
+                       return null;
+               }
+
+               @Override
+               protected void onPreExecute() {
+                       super.onPreExecute();
+                       Log.d(TAG, "Starting loading of the PDF page asynchronously.");
+                       mProgressContainer.setVisibility(View.VISIBLE);
+               }
+
+               @Override
+               protected void onPostExecute(Void aVoid) {
+                       super.onPostExecute(aVoid);
+                       mProgressContainer.setVisibility(View.INVISIBLE);
+                       mPdfImageContainer.addView(mPdfView);
+                       Log.d(TAG, "PDF page loaded.");
+               }
+       }
 }
diff --git a/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfViewerException.java b/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfViewerException.java
new file mode 100644 (file)
index 0000000..36cf105
--- /dev/null
@@ -0,0 +1,10 @@
+package cz.cvut.fel.dce.qrscanner.pdfviewer;
+
+/**
+ * Created by michal on 16.2.15.
+ */
+public class PdfViewerException extends Exception {
+       PdfViewerException(String s){
+               super(s);
+       }
+}
diff --git a/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/SceneView.java b/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/SceneView.java
deleted file mode 100644 (file)
index f974cad..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-package cz.cvut.fel.dce.qrscanner.pdfviewer;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.view.View;
-
-/**
- * Parent class for all views for drawing some graphic on canvas.
- * The scenes can be zoomed and moved by an application.
- * @author Michal Horn
- *
- */
-public abstract class SceneView extends View {
-       /**
-        * Value with some allowed minimum and maximum.
-        * @author Michal Horn
-        *
-        * @param <T> some comparable numeric data type
-        */
-       class IntervalValue<T extends Number & Comparable<? super T>> {
-               /**
-                * Stored value
-                */
-               private T mValue;
-               /**
-                * The lowest allowed value. All values stored in the object are
-                * higher or equal this minimum.
-                */
-               private T mMinimum;
-               /**
-                * The highest allowed value. All values stored in the object are
-                * lower or equal this maximum.
-                */
-               private T mMaximum;
-               
-               /**
-                * Class constructor.
-                * Creates object that represents a value in range <minimum; maximum>.
-                * 
-                * @param defValue      Value to be stored in the object. Must be in the allowed range specified by other two parameters.
-                * @param minimum       The lowes allowed value to be stored in the object.
-                * @param maximum       The highest allowed value to be stored in the object.
-                * @throws Exception Throwed when minimal, maximal or inserted value were rejected.
-                */
-               public IntervalValue(T defValue, T minimum, T maximum) throws Exception {
-                       setMinimum(minimum);
-                       setMaximum(maximum);
-                       if (!setValue(defValue)) {
-                               throw new Exception("Provided value is not in the range.");
-                       }
-               }
-               
-               /**
-                * Store value in the object. The value must lie between the minimum and maximum
-                * defined for the object.
-                * @param value value to be stored in the object
-                * @return true - vale was stored successfully,<br>false - value could not be inserted because it was out of range. 
-                */
-               public boolean setValue(T value) {
-                       if (value.compareTo(mMinimum) >= 0 && value.compareTo(mMaximum) <= 0) {
-                               mValue = value;
-                               return true;
-                       }
-                       else {
-                               return false;
-                       }
-               }
-               
-               /**
-                * Set minimum for values in the object.
-                * Last inserted value is not changed even if it is lower then the new minimum.
-                * @param min new allowed minimum for the values stored to the object.
-                * @throws Exception throwed when new minimum is higher than old maximum.
-                */
-               public void setMinimum(T min) throws Exception {
-                       if (mMaximum != null && mMinimum != null &&  mMinimum.compareTo(mMaximum) > 0) {
-                                       throw new Exception("Minimum is higher then maximum.");
-                       }
-                       mMinimum = min;
-               }
-               
-               /**
-                * Set maximum for values in the object.
-                * Last inserted value is not changed even if it is higher then the new maximum.
-                * @param max new allowed maximum for the values stored to the object.
-                * @throws Exception throwed when new maximum is lower than old minimum.
-                */
-               public void setMaximum(T max) throws Exception {
-                       if (mMinimum != null && mMaximum != null &&  mMaximum.compareTo(mMinimum) < 0) {
-                               throw new Exception("Maximum is lower then minimum.");
-                       }
-                       mMaximum = max;
-               }
-               
-               /**
-                * Get value stored in the object
-                * @return value stored in the object.
-                */
-               public T getValue() {
-                       return mValue;
-               }
-               
-               /**
-                * Get the lowest allowed value that can be stored in the object.
-                * @return minimal value
-                */
-               public T getMinimum() {
-                       return mMinimum;
-               }
-               
-               /**
-                * Get the highest allowed value that can be stored in the object.
-                * @return maximal value
-                */
-               public T getMaximum() {
-                       return mMaximum;
-               }
-       }
-       
-       /**
-        * Interface for events generated by the view
-        * @author Michal Horn
-        *
-        */
-       public interface SceneChange {
-               /**
-                * Invoked every time when the scene should be redrawed.
-                * @param source
-                */
-               public void onSceneChanged(SceneView source);
-       }
-       
-       protected Paint mPaint;
-       protected IntervalValue<Float> mZoom;
-       protected IntervalValue<Float> mXPosition;
-       protected IntervalValue<Float> mYPosition;
-       protected SceneChange mListener;
-       protected float mSceneHeight;
-       protected float mSceneWidth;
-       protected float mDefaultZoomRatio;
-       protected float mDefaultXPos;
-       protected float mDefaultYPos;
-       
-       /**
-        * Class constructor.
-        * @param context the context of the application to provide the canvas
-        * @param defZoom initial zoom ratio
-        * @param minZoom maximal allowed zoom out
-        * @param maxZoom maximal allowed zoom in
-        * @param defXCenter initial position of the scene
-        * @param minX minimal scene position on X axis
-        * @param maxX maximal scene position on X axis
-        * @param defYCenter initial position of the scene
-        * @param minY minimal scene position on Y axis
-        * @param maxY maximal scene position on Y axis
-        * @throws Exception
-        */
-       public SceneView(Context context,
-                                        float defZoom, float minZoom, float maxZoom,
-                                        float defXCenter, float minX, float maxX,
-                                        float defYCenter, float minY, float maxY) throws Exception {
-               super(context);
-               mDefaultZoomRatio = defZoom;
-               mDefaultXPos = defXCenter;
-               mDefaultYPos = defYCenter;
-               mZoom = new IntervalValue<Float>(defZoom, minZoom, maxZoom);
-               mXPosition = new IntervalValue<Float>(defXCenter, minX, maxX);
-               mYPosition = new IntervalValue<Float>(defYCenter, minY, maxY);
-               mListener = null;
-               mPaint = new Paint();
-       }
-
-       /**
-        * Default class constructor, all default values are set to zeros.
-        * @param context the context of the application to provide the canvas
-        * @throws Exception
-        */
-       public SceneView(Context context) throws Exception {
-               this(context, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
-       }
-       
-       /**
-        * Set a listener of the events
-        * @param listener listener of the events
-        */
-       public void setListener(SceneChange listener) {
-               mListener = listener;
-       }
-       
-       /**
-        * Set new default values. Default values are loaded when reset function is called.
-        * Values are stored only, not applied.
-        * @param zoom default zoom ratio
-        * @param x default x position
-        * @param y default y position
-        */
-       public void setDefaultValues(float zoom, float x, float y) {
-               mDefaultXPos = x;
-               mDefaultYPos = y;
-               mDefaultZoomRatio = zoom;
-       }
-       
-       /**
-        * Zoom scene function. The scene can be zoomed in or out only in limits
-        * defined in constructor.
-        * @param deltaRatio when > 0 - zoom in,<br> when < 0 - zoom out
-        */
-       public  void zoom(float deltaRatio) {
-               float ratio = mZoom.getValue();
-               ratio += deltaRatio;
-               if (mZoom.setValue(ratio) == true && mListener != null) {
-                       mListener.onSceneChanged(this);
-               }
-       }
-       
-       /**
-        * Move scene function. The scene can be moved only in the rectangle specified
-        * by limits defined in constructor.
-        * @param x change of the x coordinate relatively to the actual position
-        * @param y change of the y coordinate relatively to the actual position
-        */
-       public void move(float x, float y) {
-               boolean xWasSet = mXPosition.setValue(mXPosition.getValue() + x/mZoom.getValue()*2.2f);
-               boolean yWasSet = mYPosition.setValue(mYPosition.getValue() + y/mZoom.getValue()*2.2f);
-               
-               if ((xWasSet || yWasSet) && mListener != null) {
-                       mListener.onSceneChanged(this);
-               }
-       }
-       
-       /**
-        * Reset the zoom ratio and scene position to default values.
-        */
-       public void reset() {
-               boolean xWasSet = mXPosition.setValue(mDefaultXPos);
-               boolean yWasSet = mYPosition.setValue(mDefaultYPos);
-               boolean zoomWasSet = mZoom.setValue(mDefaultZoomRatio);
-               if ((xWasSet || yWasSet || zoomWasSet) &&       mListener != null) {
-                       mListener.onSceneChanged(this);
-               }               
-       }
-       
-       /**
-        * Abstract function for scene dimensions calculation to be implemented. 
-        */
-       protected abstract void computeSceneDimmensions();
-
-       /**
-        * Abstract function with the drawing process to be implemented
-        */
-       public abstract void draw(Canvas c);
-       
-       /**
-        * @return actual scene zoom ratio
-        */
-       public float getZoomRatio() {
-               return mZoom.getValue();
-       }
-       
-       /**
-        * @return actual scene position on X axis
-        */
-       public float getXPosition() {
-               return mXPosition.getValue();
-       }
-       
-       /**
-        * @return actual scene positoin on Y axis
-        */
-       public float getYPosition() {
-               return mYPosition.getValue();
-       }
-       
-       /**
-        * @return how tall the scene is
-        */
-       public float getSceneHeight() {
-               return mSceneHeight;
-       }
-       
-       /**
-        * @return how wide the scene is
-        */
-       public float getSceneWidth() {
-               return mSceneWidth;
-       }
-       
-       @Override
-       protected void onDraw(Canvas c) {
-               draw(c);
-               super.onDraw(c);
-       }       
-}
index cc0b6e76c6f68c76f0782aa842bb81b3ed0f520e..159c5ae29f3227edf4ca80ac033c01057e345aea 100644 (file)
@@ -22,7 +22,7 @@
         android:layout_height="wrap_content"
         android:textAppearance="?android:attr/textAppearanceSmall"
         android:text="@string/page_state_scrolling"
-        android:id="@+id/textView2"
+        android:id="@+id/pdf_viewer_state"
         android:layout_alignParentEnd="true"/>
 
     <TextView
@@ -40,7 +40,7 @@
         android:text="@string/pdf_viewer_state_label"
         android:id="@+id/textView4"
         android:layout_alignParentTop="true"
-        android:layout_toStartOf="@+id/textView2"/>
+        android:layout_toStartOf="@+id/pdf_viewer_state"/>
 
     <TextView
         android:layout_width="wrap_content"
         android:layout_below="@+id/textView"
         android:layout_alignParentStart="true"
         android:id="@+id/pdf_view_container">
+
+        <RelativeLayout
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:layout_gravity="center"
+            android:id="@+id/progress_container">
+
+            <ProgressBar
+                style="?android:attr/progressBarStyleLarge"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/progressBar"
+                android:layout_centerVertical="true"
+                android:layout_centerHorizontal="true"/>
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:text="@string/loading_page"
+                android:id="@+id/textView2"
+                android:layout_below="@+id/progressBar"
+                android:layout_centerHorizontal="true"/>
+        </RelativeLayout>
     </FrameLayout>
 
 </RelativeLayout>
index bb8c7c2710fdfd21663d90b2241d676f10f06ec1..80645da5e9ed186d0cd5a6383d692aa8cd05afcd 100644 (file)
@@ -34,4 +34,5 @@ limitations under the License.
     <string name="page_number_label">Page:</string>
     <string name="pdf_viewer_state_label">State:</string>
     <string name="page_state_scrolling">scrolling</string>
+    <string name="loading_page">Loading...</string>
 </resources>