aboutsummaryrefslogtreecommitdiff
path: root/sample/src/main/java/com/davemorrissey/labs/subscaleview/test/extension/views/FreehandView.java
diff options
context:
space:
mode:
Diffstat (limited to 'sample/src/main/java/com/davemorrissey/labs/subscaleview/test/extension/views/FreehandView.java')
-rw-r--r--sample/src/main/java/com/davemorrissey/labs/subscaleview/test/extension/views/FreehandView.java141
1 files changed, 141 insertions, 0 deletions
diff --git a/sample/src/main/java/com/davemorrissey/labs/subscaleview/test/extension/views/FreehandView.java b/sample/src/main/java/com/davemorrissey/labs/subscaleview/test/extension/views/FreehandView.java
new file mode 100644
index 0000000..f4f1403
--- /dev/null
+++ b/sample/src/main/java/com/davemorrissey/labs/subscaleview/test/extension/views/FreehandView.java
@@ -0,0 +1,141 @@
+package com.davemorrissey.labs.subscaleview.test.extension.views;
+
+import android.content.Context;
+import android.graphics.*;
+import android.graphics.Paint.Cap;
+import android.graphics.Paint.Style;
+import android.support.annotation.NonNull;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FreehandView extends SubsamplingScaleImageView implements OnTouchListener {
+
+ private final Paint paint = new Paint();
+ private final Path vPath = new Path();
+ private final PointF vPoint = new PointF();
+ private PointF vPrev = new PointF();
+ private PointF vPrevious;
+ private PointF vStart;
+ private boolean drawing = false;
+
+ private int strokeWidth;
+
+ private List<PointF> sPoints;
+
+ public FreehandView(Context context, AttributeSet attr) {
+ super(context, attr);
+ initialise();
+ }
+
+ public FreehandView(Context context) {
+ this(context, null);
+ }
+
+ private void initialise() {
+ setOnTouchListener(this);
+ float density = getResources().getDisplayMetrics().densityDpi;
+ strokeWidth = (int)(density/60f);
+ }
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(@NonNull MotionEvent event) {
+ if (sPoints != null && !drawing) {
+ return super.onTouchEvent(event);
+ }
+ boolean consumed = false;
+ int touchCount = event.getPointerCount();
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ if (event.getActionIndex() == 0) {
+ vStart = new PointF(event.getX(), event.getY());
+ vPrevious = new PointF(event.getX(), event.getY());
+ } else {
+ vStart = null;
+ vPrevious = null;
+ }
+ break;
+ case MotionEvent.ACTION_MOVE:
+ PointF sCurrentF = viewToSourceCoord(event.getX(), event.getY());
+ PointF sCurrent = new PointF(sCurrentF.x, sCurrentF.y);
+ PointF sStart = vStart == null ? null : new PointF(viewToSourceCoord(vStart).x, viewToSourceCoord(vStart).y);
+
+ if (touchCount == 1 && vStart != null) {
+ float vDX = Math.abs(event.getX() - vPrevious.x);
+ float vDY = Math.abs(event.getY() - vPrevious.y);
+ if (vDX >= strokeWidth * 5 || vDY >= strokeWidth * 5) {
+ if (sPoints == null) {
+ sPoints = new ArrayList<>();
+ sPoints.add(sStart);
+ }
+ sPoints.add(sCurrent);
+ vPrevious.x = event.getX();
+ vPrevious.y = event.getY();
+ drawing = true;
+ }
+ consumed = true;
+ invalidate();
+ } else if (touchCount == 1) {
+ // Consume all one touch drags to prevent odd panning effects handled by the superclass.
+ consumed = true;
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP:
+ invalidate();
+ drawing = false;
+ vPrevious = null;
+ vStart = null;
+ }
+ // Use parent to handle pinch and two-finger pan.
+ return consumed || super.onTouchEvent(event);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ // Don't draw anything before image is ready.
+ if (!isReady()) {
+ return;
+ }
+
+ paint.setAntiAlias(true);
+
+ if (sPoints != null && sPoints.size() >= 2) {
+ vPath.reset();
+ sourceToViewCoord(sPoints.get(0).x, sPoints.get(0).y, vPrev);
+ vPath.moveTo(vPrev.x, vPrev.y);
+ for (int i = 1; i < sPoints.size(); i++) {
+ sourceToViewCoord(sPoints.get(i).x, sPoints.get(i).y, vPoint);
+ vPath.quadTo(vPrev.x, vPrev.y, (vPoint.x + vPrev.x) / 2, (vPoint.y + vPrev.y) / 2);
+ vPrev = vPoint;
+ }
+ paint.setStyle(Style.STROKE);
+ paint.setStrokeCap(Cap.ROUND);
+ paint.setStrokeWidth(strokeWidth * 2);
+ paint.setColor(Color.BLACK);
+ canvas.drawPath(vPath, paint);
+ paint.setStrokeWidth(strokeWidth);
+ paint.setColor(Color.argb(255, 51, 181, 229));
+ canvas.drawPath(vPath, paint);
+ }
+
+ }
+
+ public void reset() {
+ this.sPoints = null;
+ invalidate();
+ }
+
+}