]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/commitdiff
Implement first and naive version of pdf viewer activity
authorMichal Horn <hornmich@fel.cvut.cz>
Mon, 16 Feb 2015 12:11:24 +0000 (13:11 +0100)
committerMichal Horn <hornmich@fel.cvut.cz>
Mon, 16 Feb 2015 12:11:24 +0000 (13:11 +0100)
QRScanner/glass/src/main/AndroidManifest.xml
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/PreviewActivity.java
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfPageView.java [new file with mode: 0644]
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfViewActivity.java [new file with mode: 0644]
QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/SceneView.java [new file with mode: 0644]
QRScanner/glass/src/main/res/layout/activity_pdf_view.xml [new file with mode: 0644]
QRScanner/glass/src/main/res/menu/menu_pdf_view.xml [new file with mode: 0644]
QRScanner/glass/src/main/res/values-w820dp/dimens.xml [new file with mode: 0644]
QRScanner/glass/src/main/res/values/dimens.xml [new file with mode: 0644]
QRScanner/glass/src/main/res/values/strings.xml

index e9ab2eeeea87897047ea8d2a42a9ccd0f44f86cb..7c6bcdf51fde0e31b0be0da87e0013047aeb4355 100644 (file)
@@ -4,22 +4,31 @@
     android:versionCode="1"
     android:versionName="1.0" >
 
-<uses-sdk
+    <uses-sdk
         android:minSdkVersion="19"
         android:targetSdkVersion="19" />
 
     <uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
 
+    <android:uses-permission
+        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
+        android:maxSdkVersion="18" />
+    <android:uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <android:uses-permission
+        android:name="android.permission.READ_EXTERNAL_STORAGE"
+        android:maxSdkVersion="18" />
+
     <application
         android:allowBackup="true"
         android:icon="@drawable/ic_glass_logo"
         android:label="@string/app_name" >
         <activity
-            android:name="cz.cvut.fel.dce.qrscanner.MainActivity"
+            android:name=".MainActivity"
             android:label="@string/title_activity_main" >
             <intent-filter>
                 <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
                 <action android:name="android.intent.action.MAIN" />
+
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
 
             android:name=".PreviewActivity"
             android:label="@string/title_activity_preview" >
         </activity>
+        <activity
+            android:name=".pdfviewer.PdfViewActivity"
+            android:label="@string/title_activity_pdf_view" >
+        </activity>
     </application>
 
 </manifest>
index dfd00c7afc1dcfedfdbba0d23ddca4ed2ed90c9e..7ba8fcd9b5d5c1e9c4b652488b1d8cce084ea632 100644 (file)
@@ -18,6 +18,7 @@ import android.widget.Toast;
 import java.io.File;
 
 import cz.cvut.fel.dce.qrscanner.mupdf.MuPDFCore;
+import cz.cvut.fel.dce.qrscanner.pdfviewer.PdfViewActivity;
 
 
 public class PreviewActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener{
@@ -41,11 +42,11 @@ public class PreviewActivity extends Activity implements ViewTreeObserver.OnGlob
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_preview);
                mPreviewImg = (ImageView) findViewById(R.id.imgComponent);
-               mPreviewImg.setMaxWidth(640);
-               mPreviewImg.setMaxHeight(360);
-               mPreviewImg.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 
                if (mPreviewImg != null) {
+                       mPreviewImg.setMaxWidth(640);
+                       mPreviewImg.setMaxHeight(360);
+                       mPreviewImg.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
                        mPreviewImgObserver = mPreviewImg.getViewTreeObserver();
                        Log.i(TAG, "Registering mPreviewImgObserver OnGlobalLayoutListener.");
                        mPreviewImgObserver.addOnGlobalLayoutListener(this);
@@ -104,7 +105,7 @@ public class PreviewActivity extends Activity implements ViewTreeObserver.OnGlob
                        Log.d(TAG, "page size: " + pageW + ", " + pageH);
                        Bitmap.Config conf = Bitmap.Config.ARGB_8888;
                        Bitmap previewBitmap = Bitmap.createBitmap(pageW, pageH, conf);
-                       core.drawPage(previewBitmap, 0, pageW, pageH,, 0, pageW, pageH, cookie);
+                       core.drawPage(previewBitmap, 0, pageW, pageH, 0, 0, pageW, pageH, cookie);
                        mPreviewImg.setImageBitmap(previewBitmap);
                        mPreviewImg.invalidate();
                } catch (Exception e) {
@@ -135,11 +136,9 @@ public class PreviewActivity extends Activity implements ViewTreeObserver.OnGlob
        }
 
        private void showPDF(String filePath) {
-               Uri uri = Uri.parse(filePath);
-               Intent pdfIntent = new Intent("com.artifex.mupdfdemo.VIEW");
-               //pdfIntent.setAction(Intent.ACTION_VIEW);
-               pdfIntent.setData(uri);
-               startActivity(pdfIntent);
+               Intent preview = new Intent(this, PdfViewActivity.class);
+               preview.putExtra("FILE_PATH", filePath);
+               startActivity(preview);
        }
 
        @Override
diff --git a/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfPageView.java b/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfPageView.java
new file mode 100644 (file)
index 0000000..ffa8d1c
--- /dev/null
@@ -0,0 +1,35 @@
+package cz.cvut.fel.dce.qrscanner.pdfviewer;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.view.View;
+
+/**
+ * Created by michal on 16.2.15.
+ */
+public class PdfPageView  extends SceneView {
+       private Bitmap mPdfBitmap;
+       private Paint mBitmapPaint;
+
+       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();
+       }
+
+       @Override
+       protected void computeSceneDimmensions() {
+               mSceneWidth = mPdfBitmap.getWidth();
+               mSceneHeight = mPdfBitmap.getHeight();
+       }
+
+       @Override
+       public void draw(Canvas c) {
+               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);
+       }
+}
diff --git a/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfViewActivity.java b/QRScanner/glass/src/main/java/cz/cvut/fel/dce/qrscanner/pdfviewer/PdfViewActivity.java
new file mode 100644 (file)
index 0000000..1ad54ae
--- /dev/null
@@ -0,0 +1,201 @@
+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.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+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 static final String TAG = "PdfViewActivity";
+
+       private FrameLayout mPdfImageContainer;
+       private ViewTreeObserver mPreviewImgObserver;
+       private String mFilePath;
+       private PdfPageView mPdfView;
+       private Boolean mPdfLoaded = false;
+       private SensorManager mSensorManager;
+
+       /**
+        * Start position of the gesture on touchpad
+        */
+       private float startX;
+
+
+       @Override
+       protected void onCreate(Bundle savedInstanceState) {
+               super.onCreate(savedInstanceState);
+               getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+               mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+               setContentView(R.layout.activity_pdf_view);
+               mPdfImageContainer = (FrameLayout) findViewById(R.id.pdf_view_container);
+               if (mPdfImageContainer != null) {
+                       mPreviewImgObserver = mPdfImageContainer.getViewTreeObserver();
+                       Log.i(TAG, "Registering mPreviewImgObserver OnGlobalLayoutListener.");
+                       mPreviewImgObserver.addOnGlobalLayoutListener(this);
+               }
+               else {
+                       Log.e(TAG, "ImageView for preview image could not be found in the resources.");
+                       mPreviewImgObserver = null;
+               }
+
+               Intent intent = getIntent();
+               mFilePath = intent.getStringExtra("FILE_PATH");
+
+               if (mFilePath != null) {
+                       Log.i(TAG, "File path: " + mFilePath);
+                       File rootPath = new File(mFilePath);
+                       if (!rootPath.exists()) {
+                               Toast toast = Toast.makeText(getApplicationContext(), "Document not found", Toast.LENGTH_LONG);
+                               toast.show();
+                               finish();
+                       }
+               }
+               else {
+                       Log.i(TAG, "No file path received");
+                       finish();
+               }
+       }
+
+       public void onResume() {
+               mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);
+               super.onResume();
+       }
+
+       @Override
+       protected void onPause() {
+               super.onPause();
+               mSensorManager.unregisterListener(this);
+       }
+
+       @Override
+       protected void onDestroy() {
+               super.onDestroy();
+               if (mPreviewImgObserver != null && mPreviewImgObserver.isAlive()) {
+                       mPreviewImgObserver.removeOnGlobalLayoutListener(this);
+               }
+               getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+       }
+
+
+
+       @Override
+       public boolean onCreateOptionsMenu(Menu menu) {
+               // Inflate the menu; this adds items to the action bar if it is present.
+               getMenuInflater().inflate(R.menu.menu_pdf_view, menu);
+               return true;
+       }
+
+       @Override
+       public boolean onOptionsItemSelected(MenuItem item) {
+               // Handle action bar item clicks here. The action bar will
+               // automatically handle clicks on the Home/Up button, so long
+               // as you specify a parent activity in AndroidManifest.xml.
+               int id = item.getItemId();
+
+               //noinspection SimplifiableIfStatement
+               if (id == R.id.action_settings) {
+                       return true;
+               }
+
+               return super.onOptionsItemSelected(item);
+       }
+
+       @Override
+       public void onGlobalLayout() {
+               if (mPdfLoaded) {
+                       Log.d(TAG, "PDF file already loaded.");
+                       return;
+               }
+               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.setListener(this);
+                       mPdfView.setDefaultValues(0, 0, 0);
+                       if (mPdfImageContainer != null) {
+                               mPdfImageContainer.addView(mPdfView);
+                               mPdfImageContainer.invalidate();
+                               mPdfLoaded = true;
+                       }
+                       else {
+                               Log.e(TAG, "Could not find container for PdfPageView.");
+                               finish();
+                       }
+               } catch (Exception e) {
+                       Toast toast = Toast.makeText(getApplicationContext(), "Component preview could not be loaded.", Toast.LENGTH_LONG);
+                       toast.show();
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public boolean onGenericMotionEvent(MotionEvent event) {
+               /*
+         Zoom ratio gained during one gesture on touchpad
+        */
+               float dzoom;
+               if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                       startX = event.getRawX();
+                       return false;
+               }
+               if (event.getAction() == MotionEvent.ACTION_MOVE) {
+                       dzoom = event.getRawX() - startX;
+                       Log.d(TAG,"move_action, dzoom: " + dzoom);
+                       mPdfView.zoom(dzoom /1000f);
+                       startX = event.getRawX();
+                       return false;
+               }
+               return super.onGenericMotionEvent(event);
+       }
+
+       @Override
+       public void onSceneChanged(SceneView source) {
+               if (mPdfView != null) {
+                       mPdfView.invalidate();
+               }
+       }
+
+       @Override
+       public void onAccuracyChanged(Sensor sensor, int accuracy) {
+
+       }
+
+       @Override
+       public void onSensorChanged(SensorEvent event) {
+               if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
+                       float dx = event.values[1]*12;
+                       float dy = event.values[0]*12;
+                       if (mPdfView != null) {
+                               mPdfView.move(-dx, -dy);
+                       }
+               }
+       }
+}
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
new file mode 100644 (file)
index 0000000..f974cad
--- /dev/null
@@ -0,0 +1,294 @@
+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);
+       }       
+}
diff --git a/QRScanner/glass/src/main/res/layout/activity_pdf_view.xml b/QRScanner/glass/src/main/res/layout/activity_pdf_view.xml
new file mode 100644 (file)
index 0000000..cc0b6e7
--- /dev/null
@@ -0,0 +1,70 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                xmlns:tools="http://schemas.android.com/tools"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:paddingLeft="@dimen/activity_horizontal_margin"
+                android:paddingRight="@dimen/activity_horizontal_margin"
+                android:paddingTop="@dimen/activity_vertical_margin"
+                android:paddingBottom="@dimen/activity_vertical_margin"
+                tools:context="cz.cvut.fel.dce.qrscanner.pdfviewer.PdfViewActivity">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:text="@string/page_number_label"
+        android:id="@+id/textView"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentStart="true"/>
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:text="@string/page_state_scrolling"
+        android:id="@+id/textView2"
+        android:layout_alignParentEnd="true"/>
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:text="1"
+        android:id="@+id/page_number"
+        android:layout_toEndOf="@+id/textView"/>
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:text="@string/pdf_viewer_state_label"
+        android:id="@+id/textView4"
+        android:layout_alignParentTop="true"
+        android:layout_toStartOf="@+id/textView2"/>
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:text="/"
+        android:id="@+id/textView3"
+        android:layout_toEndOf="@+id/page_number"/>
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:text="1"
+        android:id="@+id/total_pages_num"
+        android:layout_alignParentTop="true"
+        android:layout_toEndOf="@+id/textView3"/>
+
+    <FrameLayout
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layout_below="@+id/textView"
+        android:layout_alignParentStart="true"
+        android:id="@+id/pdf_view_container">
+    </FrameLayout>
+
+</RelativeLayout>
diff --git a/QRScanner/glass/src/main/res/menu/menu_pdf_view.xml b/QRScanner/glass/src/main/res/menu/menu_pdf_view.xml
new file mode 100644 (file)
index 0000000..a4851c9
--- /dev/null
@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:tools="http://schemas.android.com/tools"
+      tools:context="cz.cvut.fel.dce.qrscanner.pdfviewer.PdfViewActivity">
+    <item android:id="@+id/action_settings"
+          android:title="@string/action_settings"
+          android:orderInCategory="100"
+          android:showAsAction="never"/>
+</menu>
diff --git a/QRScanner/glass/src/main/res/values-w820dp/dimens.xml b/QRScanner/glass/src/main/res/values-w820dp/dimens.xml
new file mode 100644 (file)
index 0000000..63fc816
--- /dev/null
@@ -0,0 +1,6 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/QRScanner/glass/src/main/res/values/dimens.xml b/QRScanner/glass/src/main/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..47c8224
--- /dev/null
@@ -0,0 +1,5 @@
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
index 09435042265485dcc46e8d9858cb3f8f22db234d..bb8c7c2710fdfd21663d90b2241d676f10f06ec1 100644 (file)
@@ -29,4 +29,9 @@ limitations under the License.
     <string name="show_pictured_manufacturing">Pictured manuf</string>
     <string name="show_workshop">Workshow guide</string>
     <string name="glass_voice_trigger">Skoda Manufacturer Helper</string>
+    <string name="title_activity_pdf_view">PdfViewActivity</string>
+    <string name="action_settings">Settings</string>
+    <string name="page_number_label">Page:</string>
+    <string name="pdf_viewer_state_label">State:</string>
+    <string name="page_state_scrolling">scrolling</string>
 </resources>