summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2012-10-17 13:18:40 +0400
committerAndrew Dolgov <[email protected]>2012-10-17 13:18:40 +0400
commit8ef5f5aa357aac7d3be22604c95ebed1597c6d55 (patch)
tree54ab3cc0c7fabc4490797d6eba383ffbe8b29340 /src
parentc7405e7b18d2fe49a118c676a67400b3b4e66b26 (diff)
revert webview
Diffstat (limited to 'src')
-rw-r--r--src/org/fox/ttcomics/ComicFragment.java136
-rw-r--r--src/org/fox/ttcomics/TouchImageView.java269
2 files changed, 314 insertions, 91 deletions
diff --git a/src/org/fox/ttcomics/ComicFragment.java b/src/org/fox/ttcomics/ComicFragment.java
index aed247b..4acd732 100644
--- a/src/org/fox/ttcomics/ComicFragment.java
+++ b/src/org/fox/ttcomics/ComicFragment.java
@@ -1,29 +1,20 @@
package org.fox.ttcomics;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
-import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.webkit.WebSettings;
-import android.webkit.WebSettings.ZoomDensity;
-import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.TextView;
@@ -43,13 +34,39 @@ public class ComicFragment extends Fragment {
m_page = page;
}
- @SuppressLint("NewApi")
+ public Bitmap loadImage(ComicArchive archive, int page) {
+ CommonActivity activity = (CommonActivity) getActivity();
+
+ try {
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeStream(archive.getItem(page), null, options);
+
+ options.inSampleSize = CommonActivity.calculateInSampleSize(options, 512, 512);
+ options.inJustDecodeBounds = false;
+
+ return BitmapFactory.decodeStream(archive.getItem(page), null, options);
+ } catch (OutOfMemoryError e) {
+ if (activity != null) {
+ activity.toast(R.string.error_out_of_memory);
+ }
+ e.printStackTrace();
+ } catch (IOException e) {
+ if (activity != null) {
+ activity.toast(R.string.error_loading_image);
+ }
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_comic, container, false);
- final WebView web = (WebView) view.findViewById(R.id.comic);
+ TouchImageView image = (TouchImageView) view.findViewById(R.id.comic_image);
if (savedInstanceState != null) {
m_page = savedInstanceState.getInt("page");
@@ -59,85 +76,27 @@ public class ComicFragment extends Fragment {
if (pager != null) {
if (CommonActivity.isCompatMode() && m_prefs.getBoolean("use_dark_theme", false)) {
- web.setBackgroundColor(0xff000000);
+ image.setBackgroundColor(0xff000000);
}
- WebSettings ws = web.getSettings();
- ws.setSupportZoom(true);
- ws.setBuiltInZoomControls(false); // http://code.google.com/p/android/issues/detail?id=36713
- //ws.setCacheMode(WebSettings.LOAD_NO_CACHE);
- //ws.setDefaultZoom(ZoomDensity.FAR);
- ws.setUseWideViewPort(true);
- ws.setLoadWithOverviewMode(true);
- // prevent flicker in ics
- if (android.os.Build.VERSION.SDK_INT >= 11) {
- web.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
- }
-
- AsyncTask<InputStream, Void, ByteArrayOutputStream> loadTask = new AsyncTask<InputStream, Void, ByteArrayOutputStream>() {
+ image.setImageBitmap(loadImage(pager.getArchive(), m_page));
+ image.setMaxZoom(4f);
+ image.setOnScaleChangedListener(new TouchImageView.OnScaleChangedListener() {
@Override
- protected ByteArrayOutputStream doInBackground(InputStream... params) {
- try {
- InputStream in = params[0];
- ByteArrayOutputStream out = new ByteArrayOutputStream();
-
- int c;
- while ((c = in.read()) != -1) {
- out.write(c);
- }
-
- out.flush();
- in.close();
-
- return out;
-
- } catch (IOException e) {
- e.printStackTrace();
- } catch (OutOfMemoryError e ) {
- e.printStackTrace();
- }
+ public void onScaleChanged(float scale) {
+ ViewPager pager = (ViewPager) getActivity().findViewById(R.id.comics_pager);
- return null;
- }
-
- @Override
- protected void onPostExecute(ByteArrayOutputStream result) {
- if (getActivity() != null && isAdded()) {
- if (result != null) {
- String url = "data:image/jpeg;base64," + Base64.encodeToString(result.toByteArray(), Base64.DEFAULT | Base64.NO_WRAP);
-
- String content = "<html>" +
- "<head>" +
- "<meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\">" +
- "<style type=\"text/css\">" +
- "body { padding : 0px; margin : 0px; background : transparent; }" +
- "img { max-height: 100%; max-width : 100%; }" +
- "</style>" +
- "</head>" +
- "<body>" +
- "<table width='100%' height='100%'><tr><td><img src=\""+ url +"\"></td></tr></table>" +
- "</body></html>";
-
- web.loadDataWithBaseURL(null, content, "text/html", "utf-8", null);
- } else {
- ((CommonActivity) getActivity()).toast(R.string.error_loading_image);
- }
+ if (pager != null) {
+ pager.setPagingEnabled(scale - 1.0f < 0.01);
}
}
-
- };
-
- try {
- loadTask.execute(pager.getArchive().getItem(m_page));
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- web.setOnTouchListener(new View.OnTouchListener() {
+ });
+
+ image.setCustomOnTouchListener(new View.OnTouchListener() {
int m_x;
int m_y;
-
+
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
@@ -164,12 +123,12 @@ public class ComicFragment extends Fragment {
}
});
- TextView page = (TextView) view.findViewById(R.id.comic_page);
-
- if (page != null) {
- page.setText(String.valueOf(m_page+1));
- }
+ }
+
+ TextView page = (TextView) view.findViewById(R.id.comic_page);
+ if (page != null) {
+ page.setText(String.valueOf(m_page+1));
}
return view;
@@ -183,11 +142,6 @@ public class ComicFragment extends Fragment {
private void onRightSideTapped() {
m_activity.selectNextComic();
}
-
- @Override
- public void onPause() {
- super.onPause();
- }
@Override
public void onAttach(Activity activity) {
diff --git a/src/org/fox/ttcomics/TouchImageView.java b/src/org/fox/ttcomics/TouchImageView.java
new file mode 100644
index 0000000..9a9efe6
--- /dev/null
+++ b/src/org/fox/ttcomics/TouchImageView.java
@@ -0,0 +1,269 @@
+/*
+ * TouchImageView.java
+ * By: Michael Ortiz
+ * Updated By: Patrick Lackemacher
+ * -------------------
+ * Extends Android ImageView to include pinch zooming and panning.
+ */
+
+package org.fox.ttcomics;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Matrix;
+import android.graphics.PointF;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.View;
+import android.widget.ImageView;
+
+public class TouchImageView extends ImageView {
+
+ public interface OnScaleChangedListener {
+ public void onScaleChanged(float scale);
+ }
+
+ OnScaleChangedListener mScaleChangedListener;
+ View.OnTouchListener mCustomOnTouchListener;
+
+ Matrix matrix = new Matrix();
+
+ // We can be in one of these 3 states
+ static final int NONE = 0;
+ static final int DRAG = 1;
+ static final int ZOOM = 2;
+ int mode = NONE;
+
+ // Remember some things for zooming
+ PointF last = new PointF();
+ PointF start = new PointF();
+ float minScale = 1f;
+ float maxScale = 3f;
+ float[] m;
+
+ float redundantXSpace, redundantYSpace;
+
+ float width, height;
+ static final int CLICK = 3;
+ float saveScale = 1f;
+ float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
+
+ ScaleGestureDetector mScaleDetector;
+
+ Context context;
+
+ public TouchImageView(Context context) {
+ super(context);
+ sharedConstructing(context);
+ }
+
+ public TouchImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ sharedConstructing(context);
+ }
+
+ private void sharedConstructing(Context context) {
+ super.setClickable(true);
+ this.context = context;
+ mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
+ matrix.setTranslate(1f, 1f);
+ m = new float[9];
+ setImageMatrix(matrix);
+ setScaleType(ScaleType.MATRIX);
+
+ setOnTouchListener(new OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ mScaleDetector.onTouchEvent(event);
+
+ matrix.getValues(m);
+ float x = m[Matrix.MTRANS_X];
+ float y = m[Matrix.MTRANS_Y];
+ PointF curr = new PointF(event.getX(), event.getY());
+
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ last.set(event.getX(), event.getY());
+ start.set(last);
+ mode = DRAG;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (mode == DRAG) {
+ float deltaX = curr.x - last.x;
+ float deltaY = curr.y - last.y;
+ float scaleWidth = Math.round(origWidth * saveScale);
+ float scaleHeight = Math.round(origHeight * saveScale);
+ if (scaleWidth < width) {
+ deltaX = 0;
+ if (y + deltaY > 0)
+ deltaY = -y;
+ else if (y + deltaY < -bottom)
+ deltaY = -(y + bottom);
+ } else if (scaleHeight < height) {
+ deltaY = 0;
+ if (x + deltaX > 0)
+ deltaX = -x;
+ else if (x + deltaX < -right)
+ deltaX = -(x + right);
+ } else {
+ if (x + deltaX > 0)
+ deltaX = -x;
+ else if (x + deltaX < -right)
+ deltaX = -(x + right);
+
+ if (y + deltaY > 0)
+ deltaY = -y;
+ else if (y + deltaY < -bottom)
+ deltaY = -(y + bottom);
+ }
+ matrix.postTranslate(deltaX, deltaY);
+ last.set(curr.x, curr.y);
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ mode = NONE;
+ int xDiff = (int) Math.abs(curr.x - start.x);
+ int yDiff = (int) Math.abs(curr.y - start.y);
+ if (xDiff < CLICK && yDiff < CLICK)
+ performClick();
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ mode = NONE;
+ break;
+ }
+ setImageMatrix(matrix);
+ invalidate();
+
+ if (mCustomOnTouchListener != null) {
+ mCustomOnTouchListener.onTouch(v, event);
+ }
+
+ return true; // indicate event was handled
+ }
+
+ });
+ }
+
+ @Override
+ public void setImageBitmap(Bitmap bm) {
+ super.setImageBitmap(bm);
+ if(bm != null) {
+ bmWidth = bm.getWidth();
+ bmHeight = bm.getHeight();
+ }
+ }
+
+ public void setMaxZoom(float x)
+ {
+ maxScale = x;
+ }
+
+ private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+ @Override
+ public boolean onScaleBegin(ScaleGestureDetector detector) {
+ mode = ZOOM;
+ return true;
+ }
+
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ float mScaleFactor = detector.getScaleFactor();
+ float origScale = saveScale;
+ saveScale *= mScaleFactor;
+ if (saveScale > maxScale) {
+ saveScale = maxScale;
+ mScaleFactor = maxScale / origScale;
+ } else if (saveScale < minScale) {
+ saveScale = minScale;
+ mScaleFactor = minScale / origScale;
+ }
+ right = width * saveScale - width - (2 * redundantXSpace * saveScale);
+ bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
+ if (origWidth * saveScale <= width || origHeight * saveScale <= height) {
+ matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
+ if (mScaleFactor < 1) {
+ matrix.getValues(m);
+ float x = m[Matrix.MTRANS_X];
+ float y = m[Matrix.MTRANS_Y];
+ if (mScaleFactor < 1) {
+ if (Math.round(origWidth * saveScale) < width) {
+ if (y < -bottom)
+ matrix.postTranslate(0, -(y + bottom));
+ else if (y > 0)
+ matrix.postTranslate(0, -y);
+ } else {
+ if (x < -right)
+ matrix.postTranslate(-(x + right), 0);
+ else if (x > 0)
+ matrix.postTranslate(-x, 0);
+ }
+ }
+ }
+ } else {
+ matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
+ matrix.getValues(m);
+ float x = m[Matrix.MTRANS_X];
+ float y = m[Matrix.MTRANS_Y];
+ if (mScaleFactor < 1) {
+ if (x < -right)
+ matrix.postTranslate(-(x + right), 0);
+ else if (x > 0)
+ matrix.postTranslate(-x, 0);
+ if (y < -bottom)
+ matrix.postTranslate(0, -(y + bottom));
+ else if (y > 0)
+ matrix.postTranslate(0, -y);
+ }
+ }
+
+ if (mScaleChangedListener != null) {
+ mScaleChangedListener.onScaleChanged(saveScale);
+ }
+
+ return true;
+
+ }
+ }
+
+ @Override
+ protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
+ {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ width = MeasureSpec.getSize(widthMeasureSpec);
+ height = MeasureSpec.getSize(heightMeasureSpec);
+ //Fit to screen.
+ float scale;
+ float scaleX = (float)width / (float)bmWidth;
+ float scaleY = (float)height / (float)bmHeight;
+ scale = Math.min(scaleX, scaleY);
+ matrix.setScale(scale, scale);
+ setImageMatrix(matrix);
+ saveScale = 1f;
+
+ // Center the image
+ redundantYSpace = (float)height - (scale * (float)bmHeight) ;
+ redundantXSpace = (float)width - (scale * (float)bmWidth);
+ redundantYSpace /= (float)2;
+ redundantXSpace /= (float)2;
+
+ matrix.postTranslate(redundantXSpace, redundantYSpace);
+
+ origWidth = width - 2 * redundantXSpace;
+ origHeight = height - 2 * redundantYSpace;
+ right = width * saveScale - width - (2 * redundantXSpace * saveScale);
+ bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
+ setImageMatrix(matrix);
+ }
+
+ public void setOnScaleChangedListener(OnScaleChangedListener listener) {
+ mScaleChangedListener = listener;
+ }
+
+ public void setCustomOnTouchListener(View.OnTouchListener listener) {
+ mCustomOnTouchListener = listener;
+ }
+}