Dialog的使用(四)

package com.example.androidtest;

import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.EmbossMaskFilter;
import android.graphics.MaskFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class MainActivity extends GraphicsActivity implements ColorPickerDialog.OnColorChangedListener {
	
	private Paint mPaint;
	private MaskFilter mEmboss;
	private MaskFilter mBlur;
	
	public void colorChanged(int color)
	{
		mPaint.setColor(color);
	}
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setDither(true);
		mPaint.setColor(0xFFFF0000);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeJoin(Paint.Join.ROUND);
		mPaint.setStrokeCap(Paint.Cap.ROUND);
		mPaint.setStrokeWidth(12);
		
		mEmboss = new EmbossMaskFilter(new float[]{1, 1, 1}, 0.4f, 6, 3.5f);
		mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
	}	
	
	public class MyView extends View
	{
		private static final float MINP = 0.25f;
		private static final float MAXP = 0.75f;
		
		private Bitmap mBitmap;
		private Canvas mCanvas;
		private Path mPath;
		private Paint mBitmapPaint;
		
		public MyView(Context c)
		{
			super(c);
			mPath = new Path();
			mBitmapPaint = new Paint(Paint.DITHER_FLAG);
		}
		
		protected void onSizeChanged(int w, int h, int oldw, int oldh)
		{
			super.onSizeChanged(w, h, oldw, oldh);
			mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
			mCanvas = new Canvas(mBitmap);
		}
		
		protected void onDraw(Canvas canvas)
		{
			canvas.drawColor(0xffaaaaaa);
			canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
			canvas.drawPath(mPath, mPaint);
		}
		
		private float mX, mY;
		private static final float TOUCH_TOLERANCE = 4;
		
		private void touch_start(float x, float y)
		{
			mPath.reset();
			mPath.moveTo(x,  y);
			mX = x;
			mY = y;
		}
		
		private void touch_move(float x, float y)
		{
			float dx = Math.abs(x - mX);
			float dy = Math.abs(y - mY);
			
			if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
				mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
				mX = x;
				mY = y;
			}
		}
		
		private void touch_up()
		{
			mPath.lineTo(mX, mY);
			mCanvas.drawPath(mPath, mPaint);
			mPath.reset();
		}
		
		public boolean onTouchEvent(MotionEvent event)
		{
			float x = event.getX();
			float y = event.getY();
			
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				touch_start(x, y);
				invalidate();
				break;
			case MotionEvent.ACTION_MOVE:
				touch_move(x, y);
				invalidate();
				break;
			case MotionEvent.ACTION_UP:
				touch_up();
				invalidate();
				break;
			}
			
			return true;
		}
	}
	
	private static final int COLOR_MENU_ID = Menu.FIRST;
	private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
	private static final int BLUR_MENU_ID = Menu.FIRST + 2;
	private static final int ERASE_MENU_ID = Menu.FIRST + 3;
	private static final int SRCATOP_MENU_ID = Menu.FIRST + 4;
	
	public boolean onCreateOptionsMenu(Menu menu)
	{
		super.onCreateOptionsMenu(menu);
		
		menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
		menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
		menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
		menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z');
		menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('z', 'z');
		
		return true;
	}
	
	public boolean onPrepareOptionsMenu(Menu menu)
	{
		super.onPrepareOptionsMenu(menu);
		return true;
	}
	
	public boolean onOptionsItemSelected(MenuItem item)
	{
		mPaint.setXfermode(null);
		mPaint.setAlpha(0xff);
		
		switch (item.getItemId()) {
		case COLOR_MENU_ID:
			new ColorPickerDialog(this, this, mPaint.getColor()).show();
			return true;
		case EMBOSS_MENU_ID:
			if (mPaint.getMaskFilter() != mEmboss) {
				mPaint.setMaskFilter(mEmboss);
			} else {
				mPaint.setMaskFilter(null);
			}
			return true;
		case BLUR_MENU_ID:
			if (mPaint.getMaskFilter() != mBlur) {
				mPaint.setMaskFilter(mBlur);
			} else {
				mPaint.setMaskFilter(null);
			}
			return true;
		case ERASE_MENU_ID:
			mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
			return true;
		case SRCATOP_MENU_ID:
			mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
			mPaint.setAlpha(0x80);
			return true;
		}
		
		return super.onOptionsItemSelected(item);
	}
}

class ColorPickerDialog extends Dialog
{
	public interface OnColorChangedListener {
		void colorChanged(int color);
	}
	
	private OnColorChangedListener mListener;
	private int mInitialColor;
	
	private static class ColorPickerView extends View
	{
		private Paint mPaint;
		private Paint mCenterPaint;
		private final int[] mColors;
		private OnColorChangedListener mListener;
		
		private static final int CENTER_X = 100;
		private static final int CENTER_Y = 100;
		private static final int CENTER_RADIUS = 32;
		
		ColorPickerView(Context c, OnColorChangedListener l, int color)
		{
			super(c);
			mListener = l;
			mColors = new int[]{0xFFFF0000, 0xFFFF00FF, 0xFF0000FF,
			          0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000};
			
			Shader s = new SweepGradient(0, 0, mColors, null);
			
			mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
			mPaint.setShader(s);
			mPaint.setStyle(Paint.Style.STROKE);
			mPaint.setStrokeWidth(32);
			
			mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
			mCenterPaint.setColor(color);
			mCenterPaint.setStrokeWidth(5);
		}
		
		private boolean mTrackingCenter;
		private boolean mHighlightCenter;
		
		protected void onDraw(Canvas canvas)
		{
			float r = CENTER_X - mPaint.getStrokeWidth() * 0.5f;
			
			canvas.translate(CENTER_X, CENTER_Y);
			
			canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
			canvas.drawCircle(0,  0, CENTER_RADIUS, mCenterPaint);
			
			if (mTrackingCenter) {
				int c = mCenterPaint.getColor();
				mCenterPaint.setStyle(Paint.Style.STROKE);
				
				if (mHighlightCenter) {
					mCenterPaint.setAlpha(0xFF);
				} else {
					mCenterPaint.setAlpha(0x80);
				}
				
				canvas.drawCircle(0,  0, CENTER_RADIUS + mCenterPaint.getStrokeWidth(), mCenterPaint);
				mCenterPaint.setStyle(Paint.Style.FILL);
				mCenterPaint.setColor(c);
			}
		}
		
		protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
		{
			setMeasuredDimension(CENTER_X * 2, CENTER_Y * 2);
		}
		
		private int floatToByte(float x)
		{
			int n = java.lang.Math.round(x);
			return n;
		}
		
		private int pinToByte(int n)
		{
			if (n < 0) {
				n = 0;
			} else if (n > 255) {
				n = 255;
			}
			
			return n;
		}
		
		private int ave(int s, int d, float p)
		{
			return s + java.lang.Math.round(p * (d - s));
		}
		
		private int interpColor(int colors[], float unit)
		{
			if (unit <= 0) {
				return colors[0];
			}
			
			if (unit >= 1) {
				return colors[colors.length - 1];
			}
			
			float p = unit * (colors.length - 1);
			int i = (int)p;
			p -= i;
			
			int c0 = colors[i];
			int c1 = colors[i + 1];
			int a = ave(Color.alpha(c0), Color.alpha(c1), p);
			int r = ave(Color.red(c0), Color.red(c1), p);
			int g = ave(Color.green(c0), Color.green(c1), p);
			int b = ave(Color.blue(c0), Color.blue(c1), p);
			
			return Color.argb(a, r, g, b);
		}
		
		private int rotateColor(int color, float rad)
		{
			float deg = rad * 180 / 3.1415927f;
			int r = Color.red(color);
			int g = Color.green(color);
			int b = Color.blue(color);
			
			ColorMatrix cm = new ColorMatrix();
			ColorMatrix tmp = new ColorMatrix();
			
			cm.setRGB2YUV();
			tmp.setRotate(0, deg);
			cm.postConcat(tmp);
			tmp.setYUV2RGB();
			cm.postConcat(tmp);
			
			final float[] a = cm.getArray();
			
			int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);
			int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);
			int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
			
			return Color.argb(Color.alpha(color), pinToByte(ir), pinToByte(ig), pinToByte(ib));
		}
		
		private static final float PI = 3.1415926f;
		
		public boolean onTouchEvent(MotionEvent event)
		{
			float x = event.getX() - CENTER_X;
			float y = event.getY() - CENTER_Y;
			boolean inCenter = java.lang.Math.sqrt(x * x + y * y) <= CENTER_RADIUS;
			
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				mTrackingCenter = inCenter;
				if (inCenter) {
					mHighlightCenter = true;
					invalidate();
					break;
				}
			case MotionEvent.ACTION_MOVE:
				if (mTrackingCenter) {
					if (mHighlightCenter != inCenter) {
						mHighlightCenter = inCenter;
						invalidate();
					}
				} else {
					float angle = (float)java.lang.Math.atan2(y, x);
					float unit = angle / (2 * PI);
					if (unit < 0) {
						unit += 1;
					}
					mCenterPaint.setColor(interpColor(mColors, unit));
					invalidate();
				}
				break;
			case MotionEvent.ACTION_UP:
				if (mTrackingCenter) {
					if (inCenter) {
						mListener.colorChanged(mCenterPaint.getColor());
					}
					mTrackingCenter = false;
					invalidate();
				}
				break;
			}
			return true;
		}
	}
	
	public ColorPickerDialog(Context context, OnColorChangedListener listener, int initialColor)
	{
		super(context);
		
		mListener = listener;
		mInitialColor = initialColor;
	}
	
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		OnColorChangedListener l = new OnColorChangedListener() {
			public void colorChanged(int color) {
				mListener.colorChanged(color);
				dismiss();
			}
		};
		
		setContentView(new ColorPickerView(getContext(), l, mInitialColor));
		setTitle("Pick a Color");
	}
}

class GraphicsActivity extends Activity
{
	private static final boolean TEST_PICTURE = false;
	
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
	}
	
	public void setContentView(View view)
	{
		if (TEST_PICTURE) {
			ViewGroup vg = new PictureLayout(this);
			vg.addView(view);
			view = vg;
		}
		
		super.setContentView(view);
	}
}

class PictureLayout extends ViewGroup
{
	private final Picture mPicture = new Picture();
	
	public PictureLayout(Context context)
	{
		super(context);
	}
	
	public void addView(View child)
	{
		if (getChildCount() > 1) {
			throw new IllegalStateException("PictureLayout can host only one direct child");
		}
		
		super.addView(child);
	}
	
	public void addView(View child, int index)
	{
		if (getChildCount() > 1) {
			throw new IllegalStateException("PictureLayout can host only one direct child");
		}
		
		super.addView(child, index);
	}
	
	public void addView(View child, int index, LayoutParams params)
	{
		if (getChildCount() > 1) {
			throw new IllegalStateException("PictureLayout can host only one direct child");
		}
		
		super.addView(child, index, params);
	}
	
	protected LayoutParams generateDefaultLayoutParams()
	{
		return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
	}
	
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
	{
		final int count = getChildCount();
		
		int maxHeight = 0;
		int maxWidth = 0;
		
		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);
			if (child.getVisibility() != GONE) {
				measureChild(child, widthMeasureSpec, heightMeasureSpec);
			}
		}
		
		maxWidth += getPaddingLeft() + getPaddingRight();
		maxHeight += getPaddingTop() + getPaddingBottom();
		
		Drawable drawable = getBackground();
		if (drawable != null) {
			maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
			maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
		}
		
		setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec));
	}
	
	private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy)
	{
		canvas.save();
		canvas.translate(x, y);
		canvas.clipRect(0, 0, w, h);
		canvas.scale(0.5f, 0.5f);
		canvas.scale(sx, sy, w, h);
		canvas.drawPicture(mPicture);
		canvas.restore();
	}
	
	protected void dispatchDraw(Canvas canvas)
	{
		super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
		mPicture.endRecording();
		
		int x = getWidth() / 2;
		int y = getHeight() / 2;
		
		if (false) {
			canvas.drawPicture(mPicture);
		} else {
			drawPict(canvas, 0, 0, x, y, 1, 1);
			drawPict(canvas, x, 0, x, y, -1, 1);
			drawPict(canvas, 0, y, x, y, 1, -1);
			drawPict(canvas, x, y, x, y, -1, -1);
		}
	}
	
	public ViewParent invalidateChildInParent(int[] location, Rect dirty)
	{
		location[0] = getLeft();
		location[1] = getTop();
		dirty.set(0, 0, getWidth(), getHeight());
		return getParent();
	}
	
	protected void onLayout(boolean changed, int l, int t, int r, int b)
	{
		final int count = super.getChildCount();
		
		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);
			if (child.getVisibility() != GONE) {
				final int childLeft = getPaddingLeft();
				final int childTop = getPaddingTop();
				child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight());
			}
		}
	}
}

你可能感兴趣的:(Dialog的使用(四))