Merge pull request #38 from XyLoNaMiyX/master
Add ability to rotate the canvas (closes #32)
This commit is contained in:
commit
b0b1becf88
|
@ -13,7 +13,7 @@
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.MainActivity"
|
android:name=".activities.MainActivity"
|
||||||
android:screenOrientation="portrait">
|
android:configChanges="orientation">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -15,8 +16,8 @@ import java.util.Map;
|
||||||
|
|
||||||
public class MyCanvas extends View {
|
public class MyCanvas extends View {
|
||||||
private Paint mPaint;
|
private Paint mPaint;
|
||||||
private Path mPath;
|
private MyPath mPath;
|
||||||
private Map<Path, Integer> mPaths;
|
private Map<MyPath, Integer> mPaths;
|
||||||
private PathsChangedListener mListener;
|
private PathsChangedListener mListener;
|
||||||
|
|
||||||
private int mColor;
|
private int mColor;
|
||||||
|
@ -28,7 +29,7 @@ public class MyCanvas extends View {
|
||||||
public MyCanvas(Context context, AttributeSet attrs) {
|
public MyCanvas(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
|
||||||
mPath = new Path();
|
mPath = new MyPath();
|
||||||
mPaint = new Paint();
|
mPaint = new Paint();
|
||||||
mPaint.setColor(Color.BLACK);
|
mPaint.setColor(Color.BLACK);
|
||||||
mPaint.setStyle(Paint.Style.STROKE);
|
mPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
@ -50,8 +51,8 @@ public class MyCanvas extends View {
|
||||||
if (mPaths.size() <= 0)
|
if (mPaths.size() <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Path lastKey = null;
|
MyPath lastKey = null;
|
||||||
for (Path key : mPaths.keySet()) {
|
for (MyPath key : mPaths.keySet()) {
|
||||||
lastKey = key;
|
lastKey = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ public class MyCanvas extends View {
|
||||||
protected void onDraw(Canvas canvas) {
|
protected void onDraw(Canvas canvas) {
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
|
|
||||||
for (Map.Entry<Path, Integer> entry : mPaths.entrySet()) {
|
for (Map.Entry<MyPath, Integer> entry : mPaths.entrySet()) {
|
||||||
mPaint.setColor(entry.getValue());
|
mPaint.setColor(entry.getValue());
|
||||||
canvas.drawPath(entry.getKey(), mPaint);
|
canvas.drawPath(entry.getKey(), mPaint);
|
||||||
}
|
}
|
||||||
|
@ -117,7 +118,7 @@ public class MyCanvas extends View {
|
||||||
|
|
||||||
mPaths.put(mPath, mPaint.getColor());
|
mPaths.put(mPath, mPaint.getColor());
|
||||||
pathsUpdated();
|
pathsUpdated();
|
||||||
mPath = new Path();
|
mPath = new MyPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pathsUpdated() {
|
private void pathsUpdated() {
|
||||||
|
@ -154,4 +155,69 @@ public class MyCanvas extends View {
|
||||||
public interface PathsChangedListener {
|
public interface PathsChangedListener {
|
||||||
void pathsChanged(int cnt);
|
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<MyPath, Integer> 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<MyPath, Integer> entry : mPaths.entrySet()) {
|
||||||
|
out.writeSerializable(entry.getKey());
|
||||||
|
out.writeInt(entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load
|
||||||
|
public static final Parcelable.Creator<SavedState> CREATOR =
|
||||||
|
new Parcelable.Creator<SavedState>() {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<Action> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue