Index: ui/android/java/src/org/chromium/ui/ColorPickerDialog.java |
diff --git a/ui/android/java/src/org/chromium/ui/ColorPickerDialog.java b/ui/android/java/src/org/chromium/ui/ColorPickerDialog.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..aaca1dc1da24a702ab49fa7f40f8e16d0e3ba3bc |
--- /dev/null |
+++ b/ui/android/java/src/org/chromium/ui/ColorPickerDialog.java |
@@ -0,0 +1,206 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.ui; |
+ |
+import android.app.Dialog; |
+import android.content.Context; |
+import android.content.DialogInterface; |
+import android.graphics.Canvas; |
+import android.graphics.Color; |
+import android.graphics.Paint; |
+import android.graphics.RectF; |
+import android.graphics.Shader; |
+import android.graphics.SweepGradient; |
+import android.os.Bundle; |
+import android.view.MotionEvent; |
+import android.view.View; |
+ |
+public class ColorPickerDialog extends Dialog { |
+ |
+ public interface OnColorChangedListener { |
+ void colorChanged(int color); |
+ } |
+ |
+ private OnColorChangedListener mListener; |
+ private int mInitialColor; |
+ |
+ private static class ColorPickerView extends View { |
+ private static final int CENTER_RADIUS = 32; |
+ private static final int DIALOG_HEIGHT = 200; |
+ private static final int CONTAINER_R = 100; |
Peter Beverloo
2012/11/23 17:55:48
BOUNDING_BOX_EDGE maybe?
Miguel Garcia
2012/11/26 11:35:10
Done.
|
+ |
+ private Paint mPaint; |
+ private Paint mCenterPaint; |
+ private final int[] mColors; |
+ private OnColorChangedListener mListener; |
+ private boolean mTrackingCenter; |
+ private boolean mHighlightCenter; |
+ |
+ private int center_x = -1; |
+ private int center_y = -1; |
+ |
+ ColorPickerView(Context c, OnColorChangedListener listener, int color) { |
+ super(c); |
+ mListener = listener; |
Peter Beverloo
2012/11/23 17:55:48
Should we add a TODO about this not being the fina
Miguel Garcia
2012/11/26 11:35:10
Peter and I followed up offline and decided that t
bulach
2012/11/26 11:39:16
agree on adding a TODO / ensuring the patch descri
|
+ 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); |
+ } |
+ |
+ @Override |
+ protected void onDraw(Canvas canvas) { |
+ if (center_x == -1) |
+ center_x = getWidth() / 2; |
+ if (center_y == -1) |
+ center_y = getHeight() / 2; |
+ |
+ float r = CONTAINER_R - 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); |
+ } |
+ } |
+ |
+ @Override |
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
+ setMeasuredDimension(widthMeasureSpec, DIALOG_HEIGHT); |
+ } |
+ |
+ private int ave(int s, int d, float p) { |
Peter Beverloo
2012/11/23 17:55:48
This calculates the position between [s]tart and [
Miguel Garcia
2012/11/26 11:35:10
it's actually [0,1) but yeah it's a normal interpo
|
+ 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; |
+ |
+ // now p is just the fractional part [0...1) and i is the index |
+ 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 static final float PI = 3.1415926f; |
+ |
+ @Override |
+ 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); |
+ // need to turn angle [-PI ... PI] into unit [0....1] |
+ 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; // so we draw w/o halo |
Peter Beverloo
2012/11/23 17:55:48
nit: please use whole sentences for comments.
Miguel Garcia
2012/11/26 11:35:10
Done.
|
+ invalidate(); |
+ } |
+ break; |
+ } |
+ return true; |
+ } |
+ } |
+ |
+ public ColorPickerDialog(Context context, |
+ OnColorChangedListener listener, |
+ int initialColor) { |
+ super(context); |
+ |
+ mListener = listener; |
+ mInitialColor = initialColor; |
+ |
+ |
+ setOnCancelListener(new DialogInterface.OnCancelListener() { |
+ @Override |
+ public void onCancel(DialogInterface arg0) { |
+ mListener.colorChanged(mInitialColor); |
+ } |
+ }); |
+ } |
+ |
+ @Override |
+ protected void onCreate(Bundle savedInstanceState) { |
+ super.onCreate(savedInstanceState); |
+ OnColorChangedListener listener = new OnColorChangedListener() { |
+ @Override |
+ public void colorChanged(int color) { |
+ mListener.colorChanged(color); |
+ } |
+ }; |
+ setContentView( |
+ new ColorPickerView(getContext(), listener, mInitialColor)); |
Peter Beverloo
2012/11/23 17:55:48
nit: this would fit on a single line.
Miguel Garcia
2012/11/26 11:35:10
Done.
|
+ |
+ // TODO(miguelg): Internationalization |
+ setTitle("Select Color"); |
+ } |
+} |