package cn.edu.chd.graphics; import java.util.ArrayList; import java.util.List; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; import android.graphics.PointF; import android.graphics.RectF; import cn.edu.chd.domain.Tuyuan; import cn.edu.chd.domain.PaintStyle; import cn.edu.chd.utils.PaintUtils; import cn.edu.chd.values.ApplicationValues; /** * @author Rowand jj * *����� * * * */ public class Polygn implements Tuyuan { /** * ������ʼ������� */ private float mCurrentX = 0.0f; /** * ������ʼ�������� */ private float mCurrentY = 0.0f; /** * ���� */ private Paint mPenPaint = null; /** * ·�� */ private Path mPath = new Path(); /** * ת�۵Ļص��ӿ� */ private OnTurnListener mListener = null; private boolean mHasDraw = false; private Path oldPath = new Path(); /** * ͼԪ�Ƿ���� */ private boolean isFilled = false; /** * �������㵽�յ��һ��ֱ�� */ private Path endPath = new Path(); private float startX = 0.0f; private float startY = 0.0f; private float tempX = 0.0f; private float tempY = 0.0f; private boolean isTouchUp = false; /** * ����·�� */ private Path finalPath = new Path(); /** * �������·���ĵ㼯�� */ private List<PointF> points = new ArrayList<PointF>(); private int penSize; private int penColor; private PaintStyle paintStyle; private int alpha; public Polygn(int penSize, int penColor,int alpha,PaintStyle paintStyle) { mPenPaint = paintStyle.getPaintStyle(); mPenPaint.setStrokeWidth(penSize); mPenPaint.setColor(penColor); mPenPaint.setAlpha(255-alpha); this.penSize = penSize; this.penColor = penColor; this.alpha = alpha; this.paintStyle = paintStyle; } @Override public void draw(Canvas canvas) { if(canvas != null) { if(isTouchUp)//���������Ѿ����ɣ���ôֱ����finalpath��֮ǰ��oldpath��mpath������ { canvas.drawPath(finalPath, mPenPaint); return; } //���ƹ�ȥ��·�� canvas.drawPath(oldPath, mPenPaint); if(mHasDraw && !isTouchUp)//����ʼ�㵽�յ㻭һ���� { canvas.drawPath(mPath, mPenPaint); endPath.reset(); endPath.moveTo(startX, startY); endPath.lineTo(tempX, tempY); canvas.drawPath(endPath, mPenPaint); } } } @Override public void touchDown(float x, float y) { mPath.reset(); mPath.moveTo(x, y); savePoint(x, y); startX = x; startY = y; points.add(new PointF(x, y)); } @Override public void touchMove(float x, float y) { tempX = x; tempY = y; if(isMoved(x, y)) { if(mListener!=null && mListener.onTurn())//�����ǰ����ת�۵�ͼ�¼��ǰ��λ�ã�����Ϊ����ʼ�� { oldPath.addPath(mPath); savePoint(x, y); mPath = new Path(); points.add(new PointF(x, y)); } drawPolygnLine(x, y); mHasDraw = true; } } @Override public void touchUp(float x, float y) { drawPolygnLine(x, y); oldPath.addPath(endPath); oldPath.addPath(mPath); isTouchUp = true; points.add(new PointF(x, y)); //��touchup�¼������󣬴������λ�����ϣ���ʱ����֮ǰ�ĵ㼯����һ������˶���ε�path���Ժ�Զ���ε� //ƽ����ɫ�Ȳ������ڴ�path�Ͻ��� //��������·�� for(int i = 0; i < points.size(); i++) { if(i == 0)//��һ���� { finalPath.moveTo(points.get(i).x,points.get(i).y); } else { finalPath.lineTo(points.get(i).x, points.get(i).y); } } finalPath.close();//�պ�����·����������㵽�յ����һ���ߣ� } /** * ���浱ǰ�� */ private void savePoint(float x, float y) { mCurrentX = x; mCurrentY = y; } private boolean isMoved(float x, float y) { float dx = Math.abs(x - mCurrentX); float dy = Math.abs(y - mCurrentY); boolean isMoved = dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE; return isMoved; } @Override public boolean hasDraw() { return mHasDraw; } private void drawPolygnLine(float x,float y) { mPath.reset(); mPath.moveTo(mCurrentX, mCurrentY); mPath.lineTo(x, y); } /** * @param listener * ����ע��ص��¼� */ public void setOnTurnListener(OnTurnListener listener) { this.mListener = listener; } /** * @author Rowand jj *ת�ۻص��¼� */ public interface OnTurnListener { public boolean onTurn(); } @Override public boolean contains(float x, float y) { RectF bounds = new RectF(); finalPath.computeBounds(bounds, true); return bounds.contains(x, y); } @Override public void setHighLight(Canvas canvas) { checked(canvas, Color.YELLOW); } @Override public void checked(Canvas canvas) { checked(canvas,Color.BLACK); } private void checked(Canvas canvas,int color) { Paint p = PaintUtils.getDashedPaint(); p.setColor(color); RectF bounds = new RectF(); //����߽� finalPath.computeBounds(bounds, true); canvas.drawRect(bounds, p); //���ƹؼ��� Paint pTemp = new Paint(); pTemp.setStyle(Style.FILL); pTemp.setColor(color); canvas.drawCircle(bounds.left, bounds.top,ApplicationValues.Base.RADIUS,pTemp); canvas.drawCircle(bounds.left, bounds.bottom,ApplicationValues.Base.RADIUS,pTemp); canvas.drawCircle(bounds.right, bounds.top,ApplicationValues.Base.RADIUS,pTemp); canvas.drawCircle(bounds.right, bounds.bottom,ApplicationValues.Base.RADIUS,pTemp); } @Override public void translate(float offsetX, float offsetY) { Matrix matrix = new Matrix(); matrix.setTranslate(offsetX, offsetY); finalPath.transform(matrix); } @Override public void fill(int color) { mPenPaint.setColor(color); mPenPaint.setStyle(Style.FILL); isFilled = true; } @Override public boolean isFilled() { return isFilled; } private void setPath(Path mPath) { this.finalPath = mPath; } private void setTouchUp(boolean istouchup) { this.isTouchUp = istouchup; } @Override public void scale(float offsetX, float offsetY) { Matrix matrix = new Matrix(); RectF bounds = new RectF(); finalPath.computeBounds(bounds, true); matrix.setScale(offsetX, offsetY, (bounds.right+bounds.left)/2.0f,(bounds.top+bounds.bottom)/2.0f); finalPath.transform(matrix); } @Override public void rotate(float degrees) { Matrix matrix = new Matrix(); RectF bounds = new RectF(); finalPath.computeBounds(bounds, true); matrix.setRotate(degrees,(bounds.right+bounds.left)/2.0f,(bounds.top+bounds.bottom)/2.0f); finalPath.transform(matrix); } @Override public Tuyuan copy() { Polygn copedTuyuan = new Polygn(penSize, penColor, alpha, paintStyle.newInstance()); if(isFilled) { copedTuyuan.fill(mPenPaint.getColor()); } copedTuyuan.setPath(new Path(finalPath)); copedTuyuan.translate(40,40); copedTuyuan.setTouchUp(true); return copedTuyuan; } }