summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java')
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java302
1 files changed, 302 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java b/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
new file mode 100644
index 000000000..8ceb37599
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.filtershow.imageshow;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.RectF;
+import android.graphics.Shader;
+
+import com.android.gallery3d.R;
+
+public class EclipseControl {
+ private float mCenterX = Float.NaN;
+ private float mCenterY = 0;
+ private float mRadiusX = 200;
+ private float mRadiusY = 300;
+ private static int MIN_TOUCH_DIST = 80;// should be a resource & in dips
+
+ private float[] handlex = new float[9];
+ private float[] handley = new float[9];
+ private int mSliderColor;
+ private int mCenterDotSize = 40;
+ private float mDownX;
+ private float mDownY;
+ private float mDownCenterX;
+ private float mDownCenterY;
+ private float mDownRadiusX;
+ private float mDownRadiusY;
+ private Matrix mScrToImg;
+
+ private boolean mShowReshapeHandles = true;
+ public final static int HAN_CENTER = 0;
+ public final static int HAN_NORTH = 7;
+ public final static int HAN_NE = 8;
+ public final static int HAN_EAST = 1;
+ public final static int HAN_SE = 2;
+ public final static int HAN_SOUTH = 3;
+ public final static int HAN_SW = 4;
+ public final static int HAN_WEST = 5;
+ public final static int HAN_NW = 6;
+
+ public EclipseControl(Context context) {
+ mSliderColor = Color.WHITE;
+ }
+
+ public void setRadius(float x, float y) {
+ mRadiusX = x;
+ mRadiusY = y;
+ }
+
+ public void setCenter(float x, float y) {
+ mCenterX = x;
+ mCenterY = y;
+ }
+
+ public int getCloseHandle(float x, float y) {
+ float min = Float.MAX_VALUE;
+ int handle = -1;
+ for (int i = 0; i < handlex.length; i++) {
+ float dx = handlex[i] - x;
+ float dy = handley[i] - y;
+ float dist = dx * dx + dy * dy;
+ if (dist < min) {
+ min = dist;
+ handle = i;
+ }
+ }
+
+ if (min < MIN_TOUCH_DIST * MIN_TOUCH_DIST) {
+ return handle;
+ }
+ for (int i = 0; i < handlex.length; i++) {
+ float dx = handlex[i] - x;
+ float dy = handley[i] - y;
+ float dist = (float) Math.sqrt(dx * dx + dy * dy);
+ }
+
+ return -1;
+ }
+
+ public void setScrToImageMatrix(Matrix scrToImg) {
+ mScrToImg = scrToImg;
+ }
+
+ public void actionDown(float x, float y, Oval oval) {
+ float[] point = new float[] {
+ x, y };
+ mScrToImg.mapPoints(point);
+ mDownX = point[0];
+ mDownY = point[1];
+ mDownCenterX = oval.getCenterX();
+ mDownCenterY = oval.getCenterY();
+ mDownRadiusX = oval.getRadiusX();
+ mDownRadiusY = oval.getRadiusY();
+ }
+
+ public void actionMove(int handle, float x, float y, Oval oval) {
+ float[] point = new float[] {
+ x, y };
+ mScrToImg.mapPoints(point);
+ x = point[0];
+ y = point[1];
+
+ // Test if the matrix is swapping x and y
+ point[0] = 0;
+ point[1] = 1;
+ mScrToImg.mapVectors(point);
+ boolean swapxy = (point[0] > 0.0f);
+
+ int sign = 1;
+ switch (handle) {
+ case HAN_CENTER:
+ float ctrdx = mDownX - mDownCenterX;
+ float ctrdy = mDownY - mDownCenterY;
+ oval.setCenter(x - ctrdx, y - ctrdy);
+ // setRepresentation(mVignetteRep);
+ break;
+ case HAN_NORTH:
+ sign = -1;
+ case HAN_SOUTH:
+ if (swapxy) {
+ float raddx = mDownRadiusY - Math.abs(mDownX - mDownCenterY);
+ oval.setRadiusY(Math.abs(x - oval.getCenterY() + sign * raddx));
+ } else {
+ float raddy = mDownRadiusY - Math.abs(mDownY - mDownCenterY);
+ oval.setRadiusY(Math.abs(y - oval.getCenterY() + sign * raddy));
+ }
+ break;
+ case HAN_EAST:
+ sign = -1;
+ case HAN_WEST:
+ if (swapxy) {
+ float raddy = mDownRadiusX - Math.abs(mDownY - mDownCenterX);
+ oval.setRadiusX(Math.abs(y - oval.getCenterX() + sign * raddy));
+ } else {
+ float raddx = mDownRadiusX - Math.abs(mDownX - mDownCenterX);
+ oval.setRadiusX(Math.abs(x - oval.getCenterX() - sign * raddx));
+ }
+ break;
+ case HAN_SE:
+ case HAN_NE:
+ case HAN_SW:
+ case HAN_NW:
+ float sin45 = (float) Math.sin(45);
+ float dr = (mDownRadiusX + mDownRadiusY) * sin45;
+ float ctr_dx = mDownX - mDownCenterX;
+ float ctr_dy = mDownY - mDownCenterY;
+ float downRad = Math.abs(ctr_dx) + Math.abs(ctr_dy) - dr;
+ float rx = oval.getRadiusX();
+ float ry = oval.getRadiusY();
+ float r = (Math.abs(rx) + Math.abs(ry)) * sin45;
+ float dx = x - oval.getCenterX();
+ float dy = y - oval.getCenterY();
+ float nr = Math.abs(Math.abs(dx) + Math.abs(dy) - downRad);
+ oval.setRadius(rx * nr / r, ry * nr / r);
+
+ break;
+ }
+ }
+
+ public void paintGrayPoint(Canvas canvas, float x, float y) {
+ if (x == Float.NaN) {
+ return;
+ }
+
+ Paint paint = new Paint();
+
+ paint.setStyle(Paint.Style.FILL);
+ paint.setColor(Color.BLUE);
+ int[] colors3 = new int[] {
+ Color.GRAY, Color.LTGRAY, 0x66000000, 0 };
+ RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[] {
+ 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP);
+ paint.setShader(g);
+ canvas.drawCircle(x, y, mCenterDotSize, paint);
+ }
+
+ public void paintPoint(Canvas canvas, float x, float y) {
+ if (x == Float.NaN) {
+ return;
+ }
+
+ Paint paint = new Paint();
+
+ paint.setStyle(Paint.Style.FILL);
+ paint.setColor(Color.BLUE);
+ int[] colors3 = new int[] {
+ mSliderColor, mSliderColor, 0x66000000, 0 };
+ RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[] {
+ 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP);
+ paint.setShader(g);
+ canvas.drawCircle(x, y, mCenterDotSize, paint);
+ }
+
+ void paintRadius(Canvas canvas, float cx, float cy, float rx, float ry) {
+ if (cx == Float.NaN) {
+ return;
+ }
+ int mSliderColor = 0xFF33B5E5;
+ Paint paint = new Paint();
+ RectF rect = new RectF(cx - rx, cy - ry, cx + rx, cy + ry);
+ paint.setAntiAlias(true);
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setStrokeWidth(6);
+ paint.setColor(Color.BLACK);
+ paintOvallines(canvas, rect, paint, cx, cy, rx, ry);
+
+ paint.setStrokeWidth(3);
+ paint.setColor(Color.WHITE);
+ paintOvallines(canvas, rect, paint, cx, cy, rx, ry);
+ }
+
+ public void paintOvallines(
+ Canvas canvas, RectF rect, Paint paint, float cx, float cy, float rx, float ry) {
+ canvas.drawOval(rect, paint);
+ float da = 4;
+ float arclen = da + da;
+ if (mShowReshapeHandles) {
+ paint.setStyle(Paint.Style.STROKE);
+
+ for (int i = 0; i < 361; i += 90) {
+ float dx = rx + 10;
+ float dy = ry + 10;
+ rect.left = cx - dx;
+ rect.top = cy - dy;
+ rect.right = cx + dx;
+ rect.bottom = cy + dy;
+ canvas.drawArc(rect, i - da, arclen, false, paint);
+ dx = rx - 10;
+ dy = ry - 10;
+ rect.left = cx - dx;
+ rect.top = cy - dy;
+ rect.right = cx + dx;
+ rect.bottom = cy + dy;
+ canvas.drawArc(rect, i - da, arclen, false, paint);
+ }
+ }
+ da *= 2;
+ paint.setStyle(Paint.Style.FILL);
+
+ for (int i = 45; i < 361; i += 90) {
+ double angle = Math.PI * i / 180.;
+ float x = cx + (float) (rx * Math.cos(angle));
+ float y = cy + (float) (ry * Math.sin(angle));
+ canvas.drawRect(x - da, y - da, x + da, y + da, paint);
+ }
+ paint.setStyle(Paint.Style.STROKE);
+ rect.left = cx - rx;
+ rect.top = cy - ry;
+ rect.right = cx + rx;
+ rect.bottom = cy + ry;
+ }
+
+ public void fillHandles(Canvas canvas, float cx, float cy, float rx, float ry) {
+ handlex[0] = cx;
+ handley[0] = cy;
+ int k = 1;
+
+ for (int i = 0; i < 360; i += 45) {
+ double angle = Math.PI * i / 180.;
+
+ float x = cx + (float) (rx * Math.cos(angle));
+ float y = cy + (float) (ry * Math.sin(angle));
+ handlex[k] = x;
+ handley[k] = y;
+
+ k++;
+ }
+ }
+
+ public void draw(Canvas canvas) {
+ paintRadius(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
+ fillHandles(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
+ paintPoint(canvas, mCenterX, mCenterY);
+ }
+
+ public boolean isUndefined() {
+ return Float.isNaN(mCenterX);
+ }
+
+ public void setShowReshapeHandles(boolean showReshapeHandles) {
+ this.mShowReshapeHandles = showReshapeHandles;
+ }
+}