Home | History | Annotate | Download | only in imageshow
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.gallery3d.filtershow.imageshow;
     18 
     19 import android.content.Context;
     20 import android.content.res.Resources;
     21 import android.graphics.Canvas;
     22 import android.graphics.Color;
     23 import android.graphics.DashPathEffect;
     24 import android.graphics.Matrix;
     25 import android.graphics.Paint;
     26 import android.graphics.RadialGradient;
     27 import android.graphics.Rect;
     28 import android.graphics.Shader;
     29 
     30 import com.android.gallery3d.R;
     31 
     32 public class GradControl {
     33     private float mPoint1X = Float.NaN; // used to flag parameters have not been set
     34     private float mPoint1Y = 0;
     35     private float mPoint2X = 200;
     36     private float mPoint2Y = 300;
     37     private int mMinTouchDist = 80;// should be a resource & in dips
     38 
     39     private float[] handlex = new float[3];
     40     private float[] handley = new float[3];
     41     private int mSliderColor;
     42     private int mCenterDotSize;
     43     private float mDownX;
     44     private float mDownY;
     45     private float mDownPoint1X;
     46     private float mDownPoint1Y;
     47     private float mDownPoint2X;
     48     private float mDownPoint2Y;
     49     Rect mImageBounds;
     50     int mImageHeight;
     51     private Matrix mScrToImg;
     52     Paint mPaint = new Paint();
     53     DashPathEffect mDash = new DashPathEffect(new float[]{30, 30}, 0);
     54     private boolean mShowReshapeHandles = true;
     55     public final static int HAN_CENTER = 0;
     56     public final static int HAN_NORTH = 2;
     57     public final static int HAN_SOUTH = 1;
     58     private int[] mPointColorPatern;
     59     private int[] mGrayPointColorPatern;
     60     private float[] mPointRadialPos = new float[]{0, .3f, .31f, 1};
     61     private int mLineColor;
     62     private int mlineShadowColor;
     63 
     64     public GradControl(Context context) {
     65 
     66         Resources res = context.getResources();
     67         mCenterDotSize = (int) res.getDimension(R.dimen.gradcontrol_dot_size);
     68         mMinTouchDist = (int) res.getDimension(R.dimen.gradcontrol_min_touch_dist);
     69         int grayPointCenterColor = res.getColor(R.color.gradcontrol_graypoint_center);
     70         int grayPointEdgeColor = res.getColor(R.color.gradcontrol_graypoint_edge);
     71         int pointCenterColor = res.getColor(R.color.gradcontrol_point_center);
     72         int pointEdgeColor = res.getColor(R.color.gradcontrol_point_edge);
     73         int pointShadowStartColor = res.getColor(R.color.gradcontrol_point_shadow_start);
     74         int pointShadowEndColor = res.getColor(R.color.gradcontrol_point_shadow_end);
     75         mPointColorPatern = new int[]{
     76                 pointCenterColor, pointEdgeColor, pointShadowStartColor, pointShadowEndColor};
     77         mGrayPointColorPatern = new int[]{
     78                 grayPointCenterColor, grayPointEdgeColor, pointShadowStartColor, pointShadowEndColor};
     79         mSliderColor = Color.WHITE;
     80         mLineColor = res.getColor(R.color.gradcontrol_line_color);
     81         mlineShadowColor = res.getColor(R.color.gradcontrol_line_shadow);
     82     }
     83 
     84     public void setPoint2(float x, float y) {
     85         mPoint2X = x;
     86         mPoint2Y = y;
     87     }
     88 
     89     public void setPoint1(float x, float y) {
     90         mPoint1X = x;
     91         mPoint1Y = y;
     92     }
     93 
     94     public int getCloseHandle(float x, float y) {
     95         float min = Float.MAX_VALUE;
     96         int handle = -1;
     97         for (int i = 0; i < handlex.length; i++) {
     98             float dx = handlex[i] - x;
     99             float dy = handley[i] - y;
    100             float dist = dx * dx + dy * dy;
    101             if (dist < min) {
    102                 min = dist;
    103                 handle = i;
    104             }
    105         }
    106 
    107         if (min < mMinTouchDist * mMinTouchDist) {
    108             return handle;
    109         }
    110         for (int i = 0; i < handlex.length; i++) {
    111             float dx = handlex[i] - x;
    112             float dy = handley[i] - y;
    113             float dist = (float) Math.hypot(dx, dy);
    114         }
    115 
    116         return -1;
    117     }
    118 
    119     public void setScrImageInfo(Matrix scrToImg, Rect imageBounds) {
    120         mScrToImg = scrToImg;
    121         mImageBounds = new Rect(imageBounds);
    122     }
    123 
    124     private boolean centerIsOutside(float x1, float y1, float x2, float y2) {
    125         return (!mImageBounds.contains((int) ((x1 + x2) / 2), (int) ((y1 + y2) / 2)));
    126     }
    127 
    128     public void actionDown(float x, float y, Line line) {
    129         float[] point = new float[]{
    130                 x, y};
    131         mScrToImg.mapPoints(point);
    132         mDownX = point[0];
    133         mDownY = point[1];
    134         mDownPoint1X = line.getPoint1X();
    135         mDownPoint1Y = line.getPoint1Y();
    136         mDownPoint2X = line.getPoint2X();
    137         mDownPoint2Y = line.getPoint2Y();
    138     }
    139 
    140     public void actionMove(int handle, float x, float y, Line line) {
    141         float[] point = new float[]{
    142                 x, y};
    143         mScrToImg.mapPoints(point);
    144         x = point[0];
    145         y = point[1];
    146 
    147         // Test if the matrix is swapping x and y
    148         point[0] = 0;
    149         point[1] = 1;
    150         mScrToImg.mapVectors(point);
    151         boolean swapxy = (point[0] > 0.0f);
    152 
    153         int sign = 1;
    154 
    155         float dx = x - mDownX;
    156         float dy = y - mDownY;
    157         switch (handle) {
    158             case HAN_CENTER:
    159                 if (centerIsOutside(mDownPoint1X + dx, mDownPoint1Y + dy,
    160                         mDownPoint2X + dx, mDownPoint2Y + dy)) {
    161                     break;
    162                 }
    163                 line.setPoint1(mDownPoint1X + dx, mDownPoint1Y + dy);
    164                 line.setPoint2(mDownPoint2X + dx, mDownPoint2Y + dy);
    165                 break;
    166             case HAN_SOUTH:
    167                 if (centerIsOutside(mDownPoint1X + dx, mDownPoint1Y + dy,
    168                         mDownPoint2X, mDownPoint2Y)) {
    169                     break;
    170                 }
    171                 line.setPoint1(mDownPoint1X + dx, mDownPoint1Y + dy);
    172                 break;
    173             case HAN_NORTH:
    174                 if (centerIsOutside(mDownPoint1X, mDownPoint1Y,
    175                         mDownPoint2X + dx, mDownPoint2Y + dy)) {
    176                     break;
    177                 }
    178                 line.setPoint2(mDownPoint2X + dx, mDownPoint2Y + dy);
    179                 break;
    180         }
    181     }
    182 
    183     public void paintGrayPoint(Canvas canvas, float x, float y) {
    184         if (isUndefined()) {
    185             return;
    186         }
    187 
    188         Paint paint = new Paint();
    189         paint.setStyle(Paint.Style.FILL);
    190         RadialGradient g = new RadialGradient(x, y, mCenterDotSize, mGrayPointColorPatern,
    191                 mPointRadialPos, Shader.TileMode.CLAMP);
    192         paint.setShader(g);
    193         canvas.drawCircle(x, y, mCenterDotSize, paint);
    194     }
    195 
    196     public void paintPoint(Canvas canvas, float x, float y) {
    197         if (isUndefined()) {
    198             return;
    199         }
    200 
    201         Paint paint = new Paint();
    202         paint.setStyle(Paint.Style.FILL);
    203         RadialGradient g = new RadialGradient(x, y, mCenterDotSize, mPointColorPatern,
    204                 mPointRadialPos, Shader.TileMode.CLAMP);
    205         paint.setShader(g);
    206         canvas.drawCircle(x, y, mCenterDotSize, paint);
    207     }
    208 
    209     void paintLines(Canvas canvas, float p1x, float p1y, float p2x, float p2y) {
    210         if (isUndefined()) {
    211             return;
    212         }
    213 
    214         mPaint.setAntiAlias(true);
    215         mPaint.setStyle(Paint.Style.STROKE);
    216 
    217         mPaint.setStrokeWidth(6);
    218         mPaint.setColor(mlineShadowColor);
    219         mPaint.setPathEffect(mDash);
    220         paintOvallines(canvas, mPaint, p1x, p1y, p2x, p2y);
    221 
    222         mPaint.setStrokeWidth(3);
    223         mPaint.setColor(mLineColor);
    224         mPaint.setPathEffect(mDash);
    225         paintOvallines(canvas, mPaint, p1x, p1y, p2x, p2y);
    226     }
    227 
    228     public void paintOvallines(
    229             Canvas canvas, Paint paint, float p1x, float p1y, float p2x, float p2y) {
    230 
    231 
    232 
    233         canvas.drawLine(p1x, p1y, p2x, p2y, paint);
    234 
    235         float cx = (p1x + p2x) / 2;
    236         float cy = (p1y + p2y) / 2;
    237         float dx = p1x - p2x;
    238         float dy = p1y - p2y;
    239         float len = (float) Math.hypot(dx, dy);
    240         dx *= 2048 / len;
    241         dy *= 2048 / len;
    242 
    243         canvas.drawLine(p1x + dy, p1y - dx, p1x - dy, p1y + dx, paint);
    244         canvas.drawLine(p2x + dy, p2y - dx, p2x - dy, p2y + dx, paint);
    245     }
    246 
    247     public void fillHandles(Canvas canvas, float p1x, float p1y, float p2x, float p2y) {
    248         float cx = (p1x + p2x) / 2;
    249         float cy = (p1y + p2y) / 2;
    250         handlex[0] = cx;
    251         handley[0] = cy;
    252         handlex[1] = p1x;
    253         handley[1] = p1y;
    254         handlex[2] = p2x;
    255         handley[2] = p2y;
    256 
    257     }
    258 
    259     public void draw(Canvas canvas) {
    260         paintLines(canvas, mPoint1X, mPoint1Y, mPoint2X, mPoint2Y);
    261         fillHandles(canvas, mPoint1X, mPoint1Y, mPoint2X, mPoint2Y);
    262         paintPoint(canvas, mPoint2X, mPoint2Y);
    263         paintPoint(canvas, mPoint1X, mPoint1Y);
    264         paintPoint(canvas, (mPoint1X + mPoint2X) / 2, (mPoint1Y + mPoint2Y) / 2);
    265     }
    266 
    267     public boolean isUndefined() {
    268         return Float.isNaN(mPoint1X);
    269     }
    270 
    271     public void setShowReshapeHandles(boolean showReshapeHandles) {
    272         this.mShowReshapeHandles = showReshapeHandles;
    273     }
    274 }
    275