Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Unified Diff: ui/android/java/src/org/chromium/ui/ColorPickerDialog.java

Issue 11316153: implement input type=color for android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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");
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698