/*
* Copyright (C) 2007 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.zyq.main;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.view.View;
// This class is used by CropImage to display a highlighted cropping rectangle
// overlayed with the image. There are two coordinate spaces in use. One is
// image, another is screen. computeLayout() uses mMatrix to map from image
// space to screen space.
class HighlightView {
@SuppressWarnings("unused")
private static final String TAG = "HighlightView";
View mContext; // The View displaying the image.
public static final int GROW_NONE = (1 << 0);
public static final int GROW_LEFT_EDGE = (1 << 1);
public static final int GROW_RIGHT_EDGE = (1 << 2);
public static final int GROW_TOP_EDGE = (1 << 3);
public static final int GROW_BOTTOM_EDGE = (1 << 4);
public static final int MOVE = (1 << 5);
public HighlightView(View ctx) {
mContext = ctx;
}
private void init() {
android.content.res.Resources resources = mContext.getResources();
mResizeDrawableWidth = resources.getDrawable(R.drawable.camera_crop_width);
mResizeDrawableHeight = resources.getDrawable(R.drawable.camera_crop_height);
mResizeDrawableDiagonal = resources.getDrawable(R.drawable.indicator_autocrop);
}
boolean mIsFocused;
boolean mHidden;
public boolean hasFocus() {
return mIsFocused;
}
public void setFocus(boolean f) {
mIsFocused = f;
}
public void setHidden(boolean hidden) {
mHidden = hidden;
}
protected void draw(Canvas canvas) {
if (mHidden) {
return;
}
canvas.save();
Path path = new Path();
if (!hasFocus()) {
mOutlinePaint.setColor(0xFF000000);
canvas.drawRect(mDrawRect, mOutlinePaint);
} else {
Rect viewDrawingRect = new Rect();
mContext.getDrawingRect(viewDrawingRect);
if (mCircle) {
float width = mDrawRect.width();
float height = mDrawRect.height();
path.addCircle(mDrawRect.left + (width / 2), mDrawRect.top + (height / 2), width / 2, Path.Direction.CW);
mOutlinePaint.setColor(0xFFEF04D6);
} else {
path.addRect(new RectF(mDrawRect), Path.Direction.CW);
mOutlinePaint.setColor(0xFFFF8A00);
}
canvas.clipPath(path, Region.Op.DIFFERENCE);
canvas.drawRect(viewDrawingRect, hasFocus() ? mFocusPaint : mNoFocusPaint);
canvas.restore();
canvas.drawPath(path, mOutlinePaint);
if (mMode == ModifyMode.Grow) {
if (mCircle) {
int width = mResizeDrawableDiagonal.getIntrinsicWidth();
int height = mResizeDrawableDiagonal.getIntrinsicHeight();
int d = (int) Math.round(Math.cos(/* 45deg */Math.PI / 4D) * (mDrawRect.width() / 2D));
int x = mDrawRect.left + (mDrawRect.width() / 2) + d - width / 2;
int y = mDrawRect.top + (mDrawRect.height() / 2) - d - height / 2;
mResizeDrawableDiagonal.setBounds(x, y, x + mResizeDrawableDiagonal.getIntrinsicWidth(), y
+ mResizeDrawableDiagonal.getIntrinsicHeight());
mResizeDrawableDiagonal.draw(canvas);
} else {
int left = mDrawRect.left + 1;
int right = mDrawRect.right + 1;
int top = mDrawRect.top + 4;
int bottom = mDrawRect.bottom + 3;
int widthWidth = mResizeDrawableWidth.getIntrinsicWidth() / 2;
int widthHeight = mResizeDrawableWidth.getIntrinsicHeight() / 2;
int heightHeight = mResizeDrawableHeight.getIntrinsicHeight() / 2;
int heightWidth = mResizeDrawableHeight.getIntrinsicWidth() / 2;
int xMiddle = mDrawRect.left + ((mDrawRect.right - mDrawRect.left) / 2);
int yMiddle = mDrawRect.top + ((mDrawRect.bottom - mDrawRect.top) / 2);
mResizeDrawableWidth.setBounds(left - widthWidth, yMiddle - widthHeight, left + widthWidth, yMiddle
+ widthHeight);
mResizeDrawableWidth.draw(canvas);
mResizeDrawableWidth.setBounds(right - widthWidth, yMiddle - widthHeight, right + widthWidth, yMiddle
+ widthHeight);
mResizeDrawableWidth.draw(canvas);
mResizeDrawableHeight.setBounds(xMiddle - heightWidth, top - heightHeight, xMiddle + heightWidth, top
+ heightHeight);
mResizeDrawableHeight.draw(canvas);
mResizeDrawableHeight.setBounds(xMiddle - heightWidth, bottom - heightHeight, xMiddle + heightWidth, bottom
+ heightHeight);
mResizeDrawableHeight.draw(canvas);
}
}
}
}
public void setMode(ModifyMode mode) {
if (mode != mMode) {
mMode = mode;
mContext.invalidate();
}
}
// Determines which edges are hit by touching at (x, y).
public int getHit(float x, float y) {
Rect r = computeLayout();
final float hysteresis = 20F;
int retval = GROW_NONE;
if (mCircle) {
float distX = x - r.centerX();
float distY = y - r.centerY();
int distanceFromCenter = (int) Math.sqrt(distX * distX + distY * distY);
int radius = mDrawRect.width() / 2;
int delta = distanceFromCenter - radius;
if (Math.abs(delta) <= hysteresis) {
if (Math.abs(distY) > Math.abs(distX)) {
if (distY < 0) {
retval = GROW_TOP_EDGE;
} else {
retval = GROW_BOTTOM_EDGE;
}
} else {
if (distX < 0) {
retval = GROW_LEFT_EDGE;
} else {
retval = GROW_RIGHT_EDGE;
}
}
} else if (distanceFromCenter < radius) {
retval = MOVE;
} else {
retval = GROW_NONE;
}
} else {
// verticalCheck makes sure the position is between the top and
// the bottom edge (with some tolerance). Similar for horizCheck.
boolean verticalCheck = (y >= r.top - hysteresis) && (y < r.bottom + hysteresis);
boolean horizCheck = (x >= r.left - hysteresis) && (x < r.right + hysteresis);
// Check whether the position is near some edge(s).
if ((Math.abs(r.left - x) < hysteresis) && verticalCheck) {
retval |= GROW_LEFT_EDGE;
}
if ((Math.abs(r.right - x) < hysteresis) && verticalCheck) {
retval |= GROW_RIGHT_EDGE;
}
if ((Math.abs(r.top - y) < hysteresis) && horizCheck) {