From 55c0fea00f025ecf6a1920b5a0411afcac9bb96c Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Mon, 9 Jan 2017 18:52:20 +0100 Subject: [PATCH] Add ability to rotate the canvas (closes #32) --- app/src/main/AndroidManifest.xml | 2 +- .../com/simplemobiletools/draw/MyCanvas.java | 82 ++++++++++++++-- .../com/simplemobiletools/draw/MyPath.java | 98 +++++++++++++++++++ 3 files changed, 173 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/com/simplemobiletools/draw/MyPath.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8bb347f..d34228c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,7 @@ android:theme="@style/AppTheme"> + android:configChanges="orientation"> diff --git a/app/src/main/java/com/simplemobiletools/draw/MyCanvas.java b/app/src/main/java/com/simplemobiletools/draw/MyCanvas.java index ab32d8a..01714a4 100644 --- a/app/src/main/java/com/simplemobiletools/draw/MyCanvas.java +++ b/app/src/main/java/com/simplemobiletools/draw/MyCanvas.java @@ -5,7 +5,8 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; -import android.graphics.Path; +import android.os.Parcel; +import android.os.Parcelable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -15,8 +16,8 @@ import java.util.Map; public class MyCanvas extends View { private Paint mPaint; - private Path mPath; - private Map mPaths; + private MyPath mPath; + private Map mPaths; private PathsChangedListener mListener; private int mColor; @@ -28,7 +29,7 @@ public class MyCanvas extends View { public MyCanvas(Context context, AttributeSet attrs) { super(context, attrs); - mPath = new Path(); + mPath = new MyPath(); mPaint = new Paint(); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.STROKE); @@ -50,8 +51,8 @@ public class MyCanvas extends View { if (mPaths.size() <= 0) return; - Path lastKey = null; - for (Path key : mPaths.keySet()) { + MyPath lastKey = null; + for (MyPath key : mPaths.keySet()) { lastKey = key; } @@ -76,7 +77,7 @@ public class MyCanvas extends View { protected void onDraw(Canvas canvas) { super.onDraw(canvas); - for (Map.Entry entry : mPaths.entrySet()) { + for (Map.Entry entry : mPaths.entrySet()) { mPaint.setColor(entry.getValue()); canvas.drawPath(entry.getKey(), mPaint); } @@ -117,7 +118,7 @@ public class MyCanvas extends View { mPaths.put(mPath, mPaint.getColor()); pathsUpdated(); - mPath = new Path(); + mPath = new MyPath(); } private void pathsUpdated() { @@ -154,4 +155,69 @@ public class MyCanvas extends View { public interface PathsChangedListener { void pathsChanged(int cnt); } + + // Parcelable + + @Override + public Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + + ss.mPaths = mPaths; + return ss; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + if(!(state instanceof SavedState)) { + super.onRestoreInstanceState(state); + return; + } + SavedState ss = (SavedState)state; + super.onRestoreInstanceState(ss.getSuperState()); + + mPaths = ss.mPaths; + pathsUpdated(); // This doesn't seem to be necessary + } + + static class SavedState extends BaseSavedState { + // Members + Map mPaths; + + SavedState(Parcelable superState) { + super(superState); + } + + // Save + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeInt(mPaths.size()); + for (Map.Entry entry : mPaths.entrySet()) { + out.writeSerializable(entry.getKey()); + out.writeInt(entry.getValue()); + } + } + + // Load + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + + private SavedState(Parcel in) { + super(in); + int size = in.readInt(); + for (int i = 0; i < size; i++) { + MyPath key = (MyPath)in.readSerializable(); + int value = in.readInt(); + mPaths.put(key, value); + } + } + } } diff --git a/app/src/main/java/com/simplemobiletools/draw/MyPath.java b/app/src/main/java/com/simplemobiletools/draw/MyPath.java new file mode 100644 index 0000000..ec3fa6b --- /dev/null +++ b/app/src/main/java/com/simplemobiletools/draw/MyPath.java @@ -0,0 +1,98 @@ +package com.simplemobiletools.draw; + +import android.graphics.Path; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; + +// https://stackoverflow.com/a/8127953 +class MyPath extends Path implements Serializable { + + private List actions = new LinkedList<>(); + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + + for (Action action : actions) { + action.perform(this); + } + } + + @Override + public void reset() { + actions.clear(); + super.reset(); + } + + @Override + public void moveTo(float x, float y) { + actions.add(new Move(x, y)); + super.moveTo(x, y); + } + + @Override + public void lineTo(float x, float y) { + actions.add(new Line(x, y)); + super.lineTo(x, y); + } + + @Override + public void quadTo(float x1, float y1, float x2, float y2) { + actions.add(new Quad(x1, y1, x2, y2)); + super.quadTo(x1, y1, x2, y2); + } + + private interface Action extends Serializable { + void perform(Path path); + } + + private static final class Move implements Action { + + private final float x, y; + + Move(float x, float y) { + this.x = x; + this.y = y; + } + + @Override + public void perform(Path path) { + path.moveTo(x, y); + } + } + + private static final class Line implements Action { + + private final float x, y; + + Line(float x, float y) { + this.x = x; + this.y = y; + } + + @Override + public void perform(Path path) { + path.lineTo(x, y); + } + } + + private static final class Quad implements Action { + + private final float x1, y1, x2, y2; + + private Quad(float x1, float y1, float x2, float y2) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + } + + @Override + public void perform(Path path) { + path.quadTo(x1, y1, x2, y2); + } + } +}