DroidFish: Added color picker code from Daniel Nilsson and Sergey Margaritov, adapted to DroidFish by Leo Mayer.

This commit is contained in:
Peter Osterlund
2012-08-31 23:38:12 +00:00
parent c1a0e69e75
commit 2798f59554
11 changed files with 1938 additions and 32 deletions

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Daniel Nilsson
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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:orientation="horizontal">
<net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="landscape"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/press_color_to_apply"
android:gravity="center"
android:layout_marginTop="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="↓"
android:textSize="20sp"
android:gravity="center"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_weight="0.5"
/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 Daniel Nilsson
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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:orientation="vertical">
<net.margaritov.preference.colorpicker.ColorPickerView
android:id="@+id/color_picker_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:tag="portrait"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/press_color_to_apply"
android:gravity="left"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="5dp"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:orientation="horizontal"
android:layout_below="@id/color_picker_view"
android:layout_marginBottom="10dp">
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/old_color_panel"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_weight="0.5"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="→"
android:textSize="20sp"
android:gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
<net.margaritov.preference.colorpicker.ColorPickerPanelView
android:id="@+id/new_color_panel"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="0.5"
/>
</LinearLayout>
</LinearLayout>

View File

@@ -181,6 +181,9 @@
<li>
SVG reader from <a href="http://code.google.com/p/svg-android/">svg-android</a> project.
</li>
<li>
Color picker, Copyright © 2010 Daniel Nilsson and Copyright © 2011 Sergey Margaritov.
</li>
</ul>
<h3>Translations</h3>

View File

@@ -269,6 +269,9 @@ wenn Sie es nicht aktiv nutzen.\
<string name="prefs_custom_button_2">Benutzerdefinierte Taste 2</string>
<string name="prefs_custom_button_3">Benutzerdefinierte Taste 3</string>
<string name="prefs_colors_title">Farbeinstellungen</string>
<!-- Color Picker -->
<string name="press_color_to_apply">Gewählte Farbe wird verwendet</string>
<!-- End color Picker -->
<string name="prefs_colors_summary">Einzelne Farben ändern</string>
<string name="prefs_chess_board">Spielfeld</string>
<string name="prefs_color_brightSquare_title">Helle Felder</string>

View File

@@ -291,6 +291,9 @@ you are not actively using the program.\
<string name="prefs_custom_button_2">Custom Button 2</string>
<string name="prefs_custom_button_3">Custom Button 3</string>
<string name="prefs_colors_title">Color Settings</string>
<!-- Color Picker -->
<string name="press_color_to_apply">Press on Color to apply</string>
<!-- End color Picker -->
<string name="prefs_colors_summary">Change individual colors</string>
<string name="prefs_chess_board">Chess Board</string>
<string name="prefs_color_brightSquare_title">Bright Squares</string>

View File

@@ -353,89 +353,105 @@
android:summary="@string/prefs_colors_summary">
<PreferenceCategory
android:title="@string/prefs_chess_board">
<EditTextPreference
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_brightSquare"
android:title="@string/prefs_color_brightSquare_title"
alphaSlider="true"
android:defaultValue="#FFFFFFFA">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_darkSquare"
android:title="@string/prefs_color_darkSquare_title"
alphaSlider="true"
android:defaultValue="#FF83A5D2">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_selectedSquare"
android:title="@string/prefs_color_selectedSquare_title"
alphaSlider="true"
android:defaultValue="#FF3232D1">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_cursorSquare"
android:title="@string/prefs_color_cursorSquare_title"
alphaSlider="true"
android:defaultValue="#FF5F5FFD">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_brightPiece"
android:title="@string/prefs_color_brightPiece_title"
alphaSlider="true"
android:defaultValue="#FFF0F0F0">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_darkPiece"
android:title="@string/prefs_color_darkPiece_title"
alphaSlider="true"
android:defaultValue="#FF282828">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_arrow0"
android:title="@string/prefs_color_arrow0_title"
alphaSlider="true"
android:defaultValue="#A01F1FFF">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_arrow1"
android:title="@string/prefs_color_arrow1_title"
alphaSlider="true"
android:defaultValue="#A01FFF1F">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_arrow2"
android:title="@string/prefs_color_arrow2_title"
alphaSlider="true"
android:defaultValue="#501F1FFF">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_arrow3"
android:title="@string/prefs_color_arrow3_title"
alphaSlider="true"
android:defaultValue="#501FFF1F">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_arrow4"
android:title="@string/prefs_color_arrow4_title"
alphaSlider="true"
android:defaultValue="#1E1F1FFF">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_arrow5"
android:title="@string/prefs_color_arrow5_title"
alphaSlider="true"
android:defaultValue="#281FFF1F">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_squareLabel"
android:title="@string/prefs_color_squareLabel_title"
alphaSlider="true"
android:defaultValue="#FFFF0000">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_decoration"
android:title="@string/prefs_color_decoration_title"
alphaSlider="true"
android:defaultValue="#FF808080">
</EditTextPreference>
</net.margaritov.preference.colorpicker.ColorPickerPreference>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/prefs_move_list">
<EditTextPreference
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_currentMove"
android:title="@string/prefs_color_currentMove_title"
alphaSlider="true"
android:defaultValue="#FF3333FF">
</EditTextPreference>
<EditTextPreference
</net.margaritov.preference.colorpicker.ColorPickerPreference>
<net.margaritov.preference.colorpicker.ColorPickerPreference
android:key="color_pgnComment"
android:title="@string/prefs_color_pgnComment_title"
alphaSlider="true"
android:defaultValue="#FFC0C000">
</EditTextPreference>
</net.margaritov.preference.colorpicker.ColorPickerPreference>
</PreferenceCategory>
</PreferenceScreen>
</PreferenceCategory>

View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2010 Daniel Nilsson
*
* 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 net.margaritov.preference.colorpicker;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
/**
* This drawable that draws a simple white and gray chessboard pattern.
* It's pattern you will often see as a background behind a
* partly transparent image in many applications.
* @author Daniel Nilsson
*/
public class AlphaPatternDrawable extends Drawable {
private int mRectangleSize = 10;
private Paint mPaint = new Paint();
private Paint mPaintWhite = new Paint();
private Paint mPaintGray = new Paint();
private int numRectanglesHorizontal;
private int numRectanglesVertical;
/**
* Bitmap in which the pattern will be cahched.
*/
private Bitmap mBitmap;
public AlphaPatternDrawable(int rectangleSize) {
mRectangleSize = rectangleSize;
mPaintWhite.setColor(0xffffffff);
mPaintGray.setColor(0xffcbcbcb);
}
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(mBitmap, null, getBounds(), mPaint);
}
@Override
public int getOpacity() {
return 0;
}
@Override
public void setAlpha(int alpha) {
throw new UnsupportedOperationException("Alpha is not supported by this drawwable.");
}
@Override
public void setColorFilter(ColorFilter cf) {
throw new UnsupportedOperationException("ColorFilter is not supported by this drawwable.");
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
int height = bounds.height();
int width = bounds.width();
numRectanglesHorizontal = (int) Math.ceil((width / mRectangleSize));
numRectanglesVertical = (int) Math.ceil(height / mRectangleSize);
generatePatternBitmap();
}
/**
* This will generate a bitmap with the pattern
* as big as the rectangle we were allow to draw on.
* We do this to chache the bitmap so we don't need to
* recreate it each time draw() is called since it
* takes a few milliseconds.
*/
private void generatePatternBitmap(){
if(getBounds().width() <= 0 || getBounds().height() <= 0){
return;
}
mBitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmap);
Rect r = new Rect();
boolean verticalStartWhite = true;
for (int i = 0; i <= numRectanglesVertical; i++) {
boolean isWhite = verticalStartWhite;
for (int j = 0; j <= numRectanglesHorizontal; j++) {
r.top = i * mRectangleSize;
r.left = j * mRectangleSize;
r.bottom = r.top + mRectangleSize;
r.right = r.left + mRectangleSize;
canvas.drawRect(r, isWhite ? mPaintWhite : mPaintGray);
isWhite = !isWhite;
}
verticalStartWhite = !verticalStartWhite;
}
}
}

View File

@@ -0,0 +1,148 @@
/*
* Copyright (C) 2010 Daniel Nilsson
*
* 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 net.margaritov.preference.colorpicker;
import org.petero.droidfish.R;
import android.app.Dialog;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
public class ColorPickerDialog
extends
Dialog
implements
ColorPickerView.OnColorChangedListener,
View.OnClickListener {
private ColorPickerView mColorPicker;
private ColorPickerPanelView mOldColor;
private ColorPickerPanelView mNewColor;
private OnColorChangedListener mListener;
private CharSequence additionalInfo;
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerDialog(Context context, int initialColor,
CharSequence additionalInfo) {
super(context);
this.additionalInfo = additionalInfo;
init(initialColor);
}
private void init(int color) {
// To fight color banding.
getWindow().setFormat(PixelFormat.RGBA_8888);
setUp(color);
}
private void setUp(int color) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.dialog_color_picker, null);
setContentView(layout);
setTitle(getContext().getText(R.string.prefs_colors_title) + " '"
+ additionalInfo + "'");
mColorPicker = (ColorPickerView) layout.findViewById(R.id.color_picker_view);
mOldColor = (ColorPickerPanelView) layout.findViewById(R.id.old_color_panel);
mNewColor = (ColorPickerPanelView) layout.findViewById(R.id.new_color_panel);
((LinearLayout) mOldColor.getParent()).setPadding(
Math.round(mColorPicker.getDrawingOffset()),
0,
Math.round(mColorPicker.getDrawingOffset()),
0
);
mOldColor.setOnClickListener(this);
mNewColor.setOnClickListener(this);
mColorPicker.setOnColorChangedListener(this);
mOldColor.setColor(color);
mColorPicker.setColor(color, true);
}
@Override
public void onColorChanged(int color) {
mNewColor.setColor(color);
/*
if (mListener != null) {
mListener.onColorChanged(color);
}
*/
}
public void setAlphaSliderVisible(boolean visible) {
mColorPicker.setAlphaSliderVisible(visible);
}
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener){
mListener = listener;
}
public int getColor() {
return mColorPicker.getColor();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.new_color_panel) {
if (mListener != null) {
mListener.onColorChanged(mNewColor.getColor());
}
}
dismiss();
}
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
state.putInt("old_color", mOldColor.getColor());
state.putInt("new_color", mNewColor.getColor());
return state;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mOldColor.setColor(savedInstanceState.getInt("old_color"));
mColorPicker.setColor(savedInstanceState.getInt("new_color"), true);
}
}

View File

@@ -0,0 +1,171 @@
/*
* Copyright (C) 2010 Daniel Nilsson
*
* 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 net.margaritov.preference.colorpicker;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* This class draws a panel which which will be filled with a color which can be set.
* It can be used to show the currently selected color which you will get from
* the {@link ColorPickerView}.
* @author Daniel Nilsson
*
*/
public class ColorPickerPanelView extends View {
/**
* The width in pixels of the border
* surrounding the color panel.
*/
private final static float BORDER_WIDTH_PX = 1;
private float mDensity = 1f;
private int mBorderColor = 0xff6E6E6E;
private int mColor = 0xff000000;
private Paint mBorderPaint;
private Paint mColorPaint;
private RectF mDrawingRect;
private RectF mColorRect;
private AlphaPatternDrawable mAlphaPattern;
public ColorPickerPanelView(Context context){
this(context, null);
}
public ColorPickerPanelView(Context context, AttributeSet attrs){
this(context, attrs, 0);
}
public ColorPickerPanelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
mBorderPaint = new Paint();
mColorPaint = new Paint();
mDensity = getContext().getResources().getDisplayMetrics().density;
}
@Override
protected void onDraw(Canvas canvas) {
final RectF rect = mColorRect;
if(BORDER_WIDTH_PX > 0){
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(mDrawingRect, mBorderPaint);
}
if(mAlphaPattern != null){
mAlphaPattern.draw(canvas);
}
mColorPaint.setColor(mColor);
canvas.drawRect(rect, mColorPaint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mDrawingRect = new RectF();
mDrawingRect.left = getPaddingLeft();
mDrawingRect.right = w - getPaddingRight();
mDrawingRect.top = getPaddingTop();
mDrawingRect.bottom = h - getPaddingBottom();
setUpColorRect();
}
private void setUpColorRect(){
final RectF dRect = mDrawingRect;
float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
mColorRect = new RectF(left,top, right, bottom);
mAlphaPattern = new AlphaPatternDrawable((int)(5 * mDensity));
mAlphaPattern.setBounds(
Math.round(mColorRect.left),
Math.round(mColorRect.top),
Math.round(mColorRect.right),
Math.round(mColorRect.bottom)
);
}
/**
* Set the color that should be shown by this view.
* @param color
*/
public void setColor(int color){
mColor = color;
invalidate();
}
/**
* Get the color currently show by this view.
* @return
*/
public int getColor(){
return mColor;
}
/**
* Set the color of the border surrounding the panel.
* @param color
*/
public void setBorderColor(int color){
mBorderColor = color;
invalidate();
}
/**
* Get the color of the border surrounding the panel.
*/
public int getBorderColor(){
return mBorderColor;
}
}

View File

@@ -0,0 +1,329 @@
/*
* Copyright (C) 2011 Sergey Margaritov
*
* 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 net.margaritov.preference.colorpicker;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
* A preference type that allows a user to choose a time
* @author Sergey Margaritov
*/
public class ColorPickerPreference
extends
Preference
implements
Preference.OnPreferenceClickListener,
ColorPickerDialog.OnColorChangedListener {
View mView;
ColorPickerDialog mDialog;
int mDefaultValue = Color.BLACK;
private int mValue = Color.BLACK;
private float mDensity = 0;
private boolean mAlphaSliderEnabled = false;
private static final String androidns = "http://schemas.android.com/apk/res/android";
public ColorPickerPreference(Context context) {
super(context);
init(context, null);
}
public ColorPickerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ColorPickerPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
onColorChanged(restoreValue ? getValue() : (Integer) defaultValue);
}
private void init(Context context, AttributeSet attrs) {
mDensity = getContext().getResources().getDisplayMetrics().density;
setOnPreferenceClickListener(this);
if (attrs != null) {
String defaultValue = attrs.getAttributeValue(androidns, "defaultValue");
if (defaultValue.startsWith("#")) {
try {
mDefaultValue = convertToColorInt(defaultValue);
} catch (NumberFormatException e) {
Log.e("ColorPickerPreference", "Wrong color: " + defaultValue);
mDefaultValue = convertToColorInt("#FF000000");
}
} else {
int resourceId = attrs.getAttributeResourceValue(androidns, "defaultValue", 0);
if (resourceId != 0) {
mDefaultValue = context.getResources().getInteger(resourceId);
}
}
mAlphaSliderEnabled = attrs.getAttributeBooleanValue(null, "alphaSlider", false);
}
mValue = mDefaultValue;
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
mView = view;
setPreviewColor();
}
private void setPreviewColor() {
if (mView == null) return;
ImageView iView = new ImageView(getContext());
LinearLayout widgetFrameView = ((LinearLayout)mView.findViewById(android.R.id.widget_frame));
if (widgetFrameView == null) return;
widgetFrameView.setVisibility(View.VISIBLE);
widgetFrameView.setPadding(
widgetFrameView.getPaddingLeft(),
widgetFrameView.getPaddingTop(),
(int)(mDensity * 8),
widgetFrameView.getPaddingBottom()
);
// remove already create preview image
int count = widgetFrameView.getChildCount();
if (count > 0) {
widgetFrameView.removeViews(0, count);
}
widgetFrameView.addView(iView);
widgetFrameView.setMinimumWidth(0);
iView.setBackgroundDrawable(new AlphaPatternDrawable((int)(5 * mDensity)));
iView.setImageBitmap(getPreviewBitmap());
}
private Bitmap getPreviewBitmap() {
int d = (int) (mDensity * 31); //30dip
int color = getValue();
Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
int w = bm.getWidth();
int h = bm.getHeight();
int c = color;
for (int i = 0; i < w; i++) {
for (int j = i; j < h; j++) {
c = (i <= 1 || j <= 1 || i >= w-2 || j >= h-2) ? Color.GRAY : color;
bm.setPixel(i, j, c);
if (i != j) {
bm.setPixel(j, i, c);
}
}
}
return bm;
}
public int getValue() {
try {
if (isPersistent()) {
/*
* doesn't work in DroidFish, cause the values for the color
* were stored as Strings [2012-08-30; leo]
*/
// mValue = getPersistedInt(mDefaultValue);
String tmpValue = getPersistedString(mDefaultValue + "");
if (tmpValue == null) {
mValue = mDefaultValue;
} else {
try {
mValue = Color.parseColor(tmpValue);
} catch (IllegalArgumentException e) {
mValue = mDefaultValue;
} catch (StringIndexOutOfBoundsException e) {
mValue = mDefaultValue;
}
}
}
} catch (ClassCastException e) {
mValue = mDefaultValue;
}
return mValue;
}
@Override
public void onColorChanged(int color) {
if (isPersistent()) {
/* for Droidfish: the colors are stored as strings [2012-08-30; leo] */
persistString(convertToARGB(color));
}
mValue = color;
setPreviewColor();
try {
getOnPreferenceChangeListener().onPreferenceChange(this, color);
} catch (NullPointerException e) {
}
}
public boolean onPreferenceClick(Preference preference) {
showDialog(null);
return false;
}
protected void showDialog(Bundle state) {
mDialog = new ColorPickerDialog(getContext(), getValue(), getTitle());
mDialog.setOnColorChangedListener(this);
if (mAlphaSliderEnabled) {
mDialog.setAlphaSliderVisible(true);
}
if (state != null) {
mDialog.onRestoreInstanceState(state);
}
mDialog.show();
}
/**
* Toggle Alpha Slider visibility (by default it's disabled)
* @param enable
*/
public void setAlphaSliderEnabled(boolean enable) {
mAlphaSliderEnabled = enable;
}
/**
* For custom purposes. Not used by ColorPickerPreferrence
* @param color
* @author Unknown
*/
public static String convertToARGB(int color) {
String alpha = Integer.toHexString(Color.alpha(color));
String red = Integer.toHexString(Color.red(color));
String green = Integer.toHexString(Color.green(color));
String blue = Integer.toHexString(Color.blue(color));
if (alpha.length() == 1) {
alpha = "0" + alpha;
}
if (red.length() == 1) {
red = "0" + red;
}
if (green.length() == 1) {
green = "0" + green;
}
if (blue.length() == 1) {
blue = "0" + blue;
}
return "#" + alpha + red + green + blue;
}
/**
* For custom purposes. Not used by ColorPickerPreferrence
* @param argb
* @throws NumberFormatException
* @author Unknown
*/
public static int convertToColorInt(String argb) throws NumberFormatException {
if (argb.startsWith("#")) {
argb = argb.replace("#", "");
}
int alpha = -1, red = -1, green = -1, blue = -1;
if (argb.length() == 8) {
alpha = Integer.parseInt(argb.substring(0, 2), 16);
red = Integer.parseInt(argb.substring(2, 4), 16);
green = Integer.parseInt(argb.substring(4, 6), 16);
blue = Integer.parseInt(argb.substring(6, 8), 16);
}
else if (argb.length() == 6) {
alpha = 255;
red = Integer.parseInt(argb.substring(0, 2), 16);
green = Integer.parseInt(argb.substring(2, 4), 16);
blue = Integer.parseInt(argb.substring(4, 6), 16);
}
return Color.argb(alpha, red, green, blue);
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (mDialog == null || !mDialog.isShowing()) {
return superState;
}
final SavedState myState = new SavedState(superState);
myState.dialogBundle = mDialog.onSaveInstanceState();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !(state instanceof SavedState)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
showDialog(myState.dialogBundle);
}
private static class SavedState extends BaseSavedState {
Bundle dialogBundle;
public SavedState(Parcel source) {
super(source);
dialogBundle = source.readBundle();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeBundle(dialogBundle);
}
public SavedState(Parcelable superState) {
super(superState);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

View File

@@ -0,0 +1,952 @@
/*
* Copyright (C) 2010 Daniel Nilsson
*
* 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 net.margaritov.preference.colorpicker;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposeShader;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/**
* Displays a color picker to the user and allow them
* to select a color. A slider for the alpha channel is
* also available. Enable it by setting
* setAlphaSliderVisible(boolean) to true.
* @author Daniel Nilsson
*/
public class ColorPickerView extends View {
private final static int PANEL_SAT_VAL = 0;
private final static int PANEL_HUE = 1;
private final static int PANEL_ALPHA = 2;
/**
* The width in pixels of the border
* surrounding all color panels.
*/
private final static float BORDER_WIDTH_PX = 1;
/**
* The width in dp of the hue panel.
*/
private float HUE_PANEL_WIDTH = 30f;
/**
* The height in dp of the alpha panel
*/
private float ALPHA_PANEL_HEIGHT = 20f;
/**
* The distance in dp between the different
* color panels.
*/
private float PANEL_SPACING = 10f;
/**
* The radius in dp of the color palette tracker circle.
*/
private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
/**
* The dp which the tracker of the hue or alpha panel
* will extend outside of its bounds.
*/
private float RECTANGLE_TRACKER_OFFSET = 2f;
private float mDensity = 1f;
private OnColorChangedListener mListener;
private Paint mSatValPaint;
private Paint mSatValTrackerPaint;
private Paint mHuePaint;
private Paint mHueTrackerPaint;
private Paint mAlphaPaint;
private Paint mAlphaTextPaint;
private Paint mBorderPaint;
private Shader mValShader;
private Shader mSatShader;
private Shader mHueShader;
private Shader mAlphaShader;
private int mAlpha = 0xff;
private float mHue = 360f;
private float mSat = 0f;
private float mVal = 0f;
private String mAlphaSliderText = "";
private int mSliderTrackerColor = 0xff1c1c1c;
private int mBorderColor = 0xff6E6E6E;
private boolean mShowAlphaPanel = false;
/*
* To remember which panel that has the "focus" when
* processing hardware button data.
*/
private int mLastTouchedPanel = PANEL_SAT_VAL;
/**
* Offset from the edge we must have or else
* the finger tracker will get clipped when
* it is drawn outside of the view.
*/
private float mDrawingOffset;
/*
* Distance form the edges of the view
* of where we are allowed to draw.
*/
private RectF mDrawingRect;
private RectF mSatValRect;
private RectF mHueRect;
private RectF mAlphaRect;
private AlphaPatternDrawable mAlphaPattern;
private Point mStartTouchPoint = null;
public interface OnColorChangedListener {
public void onColorChanged(int color);
}
public ColorPickerView(Context context){
this(context, null);
}
public ColorPickerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
mDensity = getContext().getResources().getDisplayMetrics().density;
PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
RECTANGLE_TRACKER_OFFSET *= mDensity;
HUE_PANEL_WIDTH *= mDensity;
ALPHA_PANEL_HEIGHT *= mDensity;
PANEL_SPACING = PANEL_SPACING * mDensity;
mDrawingOffset = calculateRequiredOffset();
initPaintTools();
//Needed for receiving trackball motion events.
setFocusable(true);
setFocusableInTouchMode(true);
}
private void initPaintTools(){
mSatValPaint = new Paint();
mSatValTrackerPaint = new Paint();
mHuePaint = new Paint();
mHueTrackerPaint = new Paint();
mAlphaPaint = new Paint();
mAlphaTextPaint = new Paint();
mBorderPaint = new Paint();
mSatValTrackerPaint.setStyle(Style.STROKE);
mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
mSatValTrackerPaint.setAntiAlias(true);
mHueTrackerPaint.setColor(mSliderTrackerColor);
mHueTrackerPaint.setStyle(Style.STROKE);
mHueTrackerPaint.setStrokeWidth(2f * mDensity);
mHueTrackerPaint.setAntiAlias(true);
mAlphaTextPaint.setColor(0xff1c1c1c);
mAlphaTextPaint.setTextSize(14f * mDensity);
mAlphaTextPaint.setAntiAlias(true);
mAlphaTextPaint.setTextAlign(Align.CENTER);
mAlphaTextPaint.setFakeBoldText(true);
}
private float calculateRequiredOffset(){
float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);
return offset * 1.5f;
}
private int[] buildHueColorArray(){
int[] hue = new int[361];
int count = 0;
for(int i = hue.length -1; i >= 0; i--, count++){
hue[count] = Color.HSVToColor(new float[]{i, 1f, 1f});
}
return hue;
}
@Override
protected void onDraw(Canvas canvas) {
if(mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) return;
drawSatValPanel(canvas);
drawHuePanel(canvas);
drawAlphaPanel(canvas);
}
private void drawSatValPanel(Canvas canvas){
final RectF rect = mSatValRect;
if(BORDER_WIDTH_PX > 0){
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
}
if (mValShader == null) {
mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
0xffffffff, 0xff000000, TileMode.CLAMP);
}
int rgb = Color.HSVToColor(new float[]{mHue,1f,1f});
mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
0xffffffff, rgb, TileMode.CLAMP);
ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);
mSatValPaint.setShader(mShader);
canvas.drawRect(rect, mSatValPaint);
Point p = satValToPoint(mSat, mVal);
mSatValTrackerPaint.setColor(0xff000000);
canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);
mSatValTrackerPaint.setColor(0xffdddddd);
canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
}
private void drawHuePanel(Canvas canvas){
final RectF rect = mHueRect;
if(BORDER_WIDTH_PX > 0){
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(rect.left - BORDER_WIDTH_PX,
rect.top - BORDER_WIDTH_PX,
rect.right + BORDER_WIDTH_PX,
rect.bottom + BORDER_WIDTH_PX,
mBorderPaint);
}
if (mHueShader == null) {
mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);
mHuePaint.setShader(mHueShader);
}
canvas.drawRect(rect, mHuePaint);
float rectHeight = 4 * mDensity / 2;
Point p = hueToPoint(mHue);
RectF r = new RectF();
r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
r.top = p.y - rectHeight;
r.bottom = p.y + rectHeight;
canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
}
private void drawAlphaPanel(Canvas canvas){
if(!mShowAlphaPanel || mAlphaRect == null || mAlphaPattern == null) return;
final RectF rect = mAlphaRect;
if(BORDER_WIDTH_PX > 0){
mBorderPaint.setColor(mBorderColor);
canvas.drawRect(rect.left - BORDER_WIDTH_PX,
rect.top - BORDER_WIDTH_PX,
rect.right + BORDER_WIDTH_PX,
rect.bottom + BORDER_WIDTH_PX,
mBorderPaint);
}
mAlphaPattern.draw(canvas);
float[] hsv = new float[]{mHue,mSat,mVal};
int color = Color.HSVToColor(hsv);
int acolor = Color.HSVToColor(0, hsv);
mAlphaShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
color, acolor, TileMode.CLAMP);
mAlphaPaint.setShader(mAlphaShader);
canvas.drawRect(rect, mAlphaPaint);
if(mAlphaSliderText != null && mAlphaSliderText!= ""){
canvas.drawText(mAlphaSliderText, rect.centerX(), rect.centerY() + 4 * mDensity, mAlphaTextPaint);
}
float rectWidth = 4 * mDensity / 2;
Point p = alphaToPoint(mAlpha);
RectF r = new RectF();
r.left = p.x - rectWidth;
r.right = p.x + rectWidth;
r.top = rect.top - RECTANGLE_TRACKER_OFFSET;
r.bottom = rect.bottom + RECTANGLE_TRACKER_OFFSET;
canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
}
private Point hueToPoint(float hue){
final RectF rect = mHueRect;
final float height = rect.height();
Point p = new Point();
p.y = (int) (height - (hue * height / 360f) + rect.top);
p.x = (int) rect.left;
return p;
}
private Point satValToPoint(float sat, float val){
final RectF rect = mSatValRect;
final float height = rect.height();
final float width = rect.width();
Point p = new Point();
p.x = (int) (sat * width + rect.left);
p.y = (int) ((1f - val) * height + rect.top);
return p;
}
private Point alphaToPoint(int alpha){
final RectF rect = mAlphaRect;
final float width = rect.width();
Point p = new Point();
p.x = (int) (width - (alpha * width / 0xff) + rect.left);
p.y = (int) rect.top;
return p;
}
private float[] pointToSatVal(float x, float y){
final RectF rect = mSatValRect;
float[] result = new float[2];
float width = rect.width();
float height = rect.height();
if (x < rect.left){
x = 0f;
}
else if(x > rect.right){
x = width;
}
else{
x = x - rect.left;
}
if (y < rect.top){
y = 0f;
}
else if(y > rect.bottom){
y = height;
}
else{
y = y - rect.top;
}
result[0] = 1.f / width * x;
result[1] = 1.f - (1.f / height * y);
return result;
}
private float pointToHue(float y){
final RectF rect = mHueRect;
float height = rect.height();
if (y < rect.top){
y = 0f;
}
else if(y > rect.bottom){
y = height;
}
else{
y = y - rect.top;
}
return 360f - (y * 360f / height);
}
private int pointToAlpha(int x){
final RectF rect = mAlphaRect;
final int width = (int) rect.width();
if(x < rect.left){
x = 0;
}
else if(x > rect.right){
x = width;
}
else{
x = x - (int)rect.left;
}
return 0xff - (x * 0xff / width);
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
boolean update = false;
if(event.getAction() == MotionEvent.ACTION_MOVE){
switch(mLastTouchedPanel){
case PANEL_SAT_VAL:
float sat, val;
sat = mSat + x/50f;
val = mVal - y/50f;
if(sat < 0f){
sat = 0f;
}
else if(sat > 1f){
sat = 1f;
}
if(val < 0f){
val = 0f;
}
else if(val > 1f){
val = 1f;
}
mSat = sat;
mVal = val;
update = true;
break;
case PANEL_HUE:
float hue = mHue - y * 10f;
if(hue < 0f){
hue = 0f;
}
else if(hue > 360f){
hue = 360f;
}
mHue = hue;
update = true;
break;
case PANEL_ALPHA:
if(!mShowAlphaPanel || mAlphaRect == null){
update = false;
}
else{
int alpha = (int) (mAlpha - x*10);
if(alpha < 0){
alpha = 0;
}
else if(alpha > 0xff){
alpha = 0xff;
}
mAlpha = alpha;
update = true;
}
break;
}
}
if(update){
if(mListener != null){
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
}
invalidate();
return true;
}
return super.onTrackballEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean update = false;
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
mStartTouchPoint = new Point((int)event.getX(), (int)event.getY());
update = moveTrackersIfNeeded(event);
break;
case MotionEvent.ACTION_MOVE:
update = moveTrackersIfNeeded(event);
break;
case MotionEvent.ACTION_UP:
mStartTouchPoint = null;
update = moveTrackersIfNeeded(event);
break;
}
if(update){
if(mListener != null){
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
}
invalidate();
return true;
}
return super.onTouchEvent(event);
}
private boolean moveTrackersIfNeeded(MotionEvent event){
if(mStartTouchPoint == null) return false;
boolean update = false;
int startX = mStartTouchPoint.x;
int startY = mStartTouchPoint.y;
if(mHueRect.contains(startX, startY)){
mLastTouchedPanel = PANEL_HUE;
mHue = pointToHue(event.getY());
update = true;
}
else if(mSatValRect.contains(startX, startY)){
mLastTouchedPanel = PANEL_SAT_VAL;
float[] result = pointToSatVal(event.getX(), event.getY());
mSat = result[0];
mVal = result[1];
update = true;
}
else if(mAlphaRect != null && mAlphaRect.contains(startX, startY)){
mLastTouchedPanel = PANEL_ALPHA;
mAlpha = pointToAlpha((int)event.getX());
update = true;
}
return update;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = 0;
int height = 0;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);
widthAllowed = chooseWidth(widthMode, widthAllowed);
heightAllowed = chooseHeight(heightMode, heightAllowed);
if(!mShowAlphaPanel){
height = (int) (widthAllowed - PANEL_SPACING - HUE_PANEL_WIDTH);
//If calculated height (based on the width) is more than the allowed height.
if(height > heightAllowed || getTag().equals("landscape")) {
height = heightAllowed;
width = (int) (height + PANEL_SPACING + HUE_PANEL_WIDTH);
}
else{
width = widthAllowed;
}
}
else{
width = (int) (heightAllowed - ALPHA_PANEL_HEIGHT + HUE_PANEL_WIDTH);
if(width > widthAllowed){
width = widthAllowed;
height = (int) (widthAllowed - HUE_PANEL_WIDTH + ALPHA_PANEL_HEIGHT);
}
else{
height = heightAllowed;
}
}
setMeasuredDimension(width, height);
}
private int chooseWidth(int mode, int size){
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else { // (mode == MeasureSpec.UNSPECIFIED)
return getPrefferedWidth();
}
}
private int chooseHeight(int mode, int size){
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else { // (mode == MeasureSpec.UNSPECIFIED)
return getPrefferedHeight();
}
}
private int getPrefferedWidth(){
int width = getPrefferedHeight();
if(mShowAlphaPanel){
width -= (PANEL_SPACING + ALPHA_PANEL_HEIGHT);
}
return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
}
private int getPrefferedHeight(){
int height = (int)(200 * mDensity);
if(mShowAlphaPanel){
height += PANEL_SPACING + ALPHA_PANEL_HEIGHT;
}
return height;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mDrawingRect = new RectF();
mDrawingRect.left = mDrawingOffset + getPaddingLeft();
mDrawingRect.right = w - mDrawingOffset - getPaddingRight();
mDrawingRect.top = mDrawingOffset + getPaddingTop();
mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();
setUpSatValRect();
setUpHueRect();
setUpAlphaRect();
}
private void setUpSatValRect(){
final RectF dRect = mDrawingRect;
float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;
if(mShowAlphaPanel){
panelSide -= PANEL_SPACING + ALPHA_PANEL_HEIGHT;
}
float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = top + panelSide;
float right = left + panelSide;
mSatValRect = new RectF(left,top, right, bottom);
}
private void setUpHueRect(){
final RectF dRect = mDrawingRect;
float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
float top = dRect.top + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX - (mShowAlphaPanel ? (PANEL_SPACING + ALPHA_PANEL_HEIGHT) : 0);
float right = dRect.right - BORDER_WIDTH_PX;
mHueRect = new RectF(left, top, right, bottom);
}
private void setUpAlphaRect() {
if(!mShowAlphaPanel) return;
final RectF dRect = mDrawingRect;
float left = dRect.left + BORDER_WIDTH_PX;
float top = dRect.bottom - ALPHA_PANEL_HEIGHT + BORDER_WIDTH_PX;
float bottom = dRect.bottom - BORDER_WIDTH_PX;
float right = dRect.right - BORDER_WIDTH_PX;
mAlphaRect = new RectF(left, top, right, bottom);
mAlphaPattern = new AlphaPatternDrawable((int) (5 * mDensity));
mAlphaPattern.setBounds(
Math.round(mAlphaRect.left),
Math.round(mAlphaRect.top),
Math.round(mAlphaRect.right),
Math.round(mAlphaRect.bottom)
);
}
/**
* Set a OnColorChangedListener to get notified when the color
* selected by the user has changed.
* @param listener
*/
public void setOnColorChangedListener(OnColorChangedListener listener){
mListener = listener;
}
/**
* Set the color of the border surrounding all panels.
* @param color
*/
public void setBorderColor(int color){
mBorderColor = color;
invalidate();
}
/**
* Get the color of the border surrounding all panels.
*/
public int getBorderColor(){
return mBorderColor;
}
/**
* Get the current color this view is showing.
* @return the current color.
*/
public int getColor(){
return Color.HSVToColor(mAlpha, new float[]{mHue,mSat,mVal});
}
/**
* Set the color the view should show.
* @param color The color that should be selected.
*/
public void setColor(int color){
setColor(color, false);
}
/**
* Set the color this view should show.
* @param color The color that should be selected.
* @param callback If you want to get a callback to
* your OnColorChangedListener.
*/
public void setColor(int color, boolean callback){
int alpha = Color.alpha(color);
int red = Color.red(color);
int blue = Color.blue(color);
int green = Color.green(color);
float[] hsv = new float[3];
Color.RGBToHSV(red, green, blue, hsv);
mAlpha = alpha;
mHue = hsv[0];
mSat = hsv[1];
mVal = hsv[2];
if(callback && mListener != null){
mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
}
invalidate();
}
/**
* Get the drawing offset of the color picker view.
* The drawing offset is the distance from the side of
* a panel to the side of the view minus the padding.
* Useful if you want to have your own panel below showing
* the currently selected color and want to align it perfectly.
* @return The offset in pixels.
*/
public float getDrawingOffset(){
return mDrawingOffset;
}
/**
* Set if the user is allowed to adjust the alpha panel. Default is false.
* If it is set to false no alpha will be set.
* @param visible
*/
public void setAlphaSliderVisible(boolean visible){
if(mShowAlphaPanel != visible){
mShowAlphaPanel = visible;
/*
* Reset all shader to force a recreation.
* Otherwise they will not look right after
* the size of the view has changed.
*/
mValShader = null;
mSatShader = null;
mHueShader = null;
mAlphaShader = null;;
requestLayout();
}
}
public void setSliderTrackerColor(int color){
mSliderTrackerColor = color;
mHueTrackerPaint.setColor(mSliderTrackerColor);
invalidate();
}
public int getSliderTrackerColor(){
return mSliderTrackerColor;
}
/**
* Set the text that should be shown in the
* alpha slider. Set to null to disable text.
* @param res string resource id.
*/
public void setAlphaSliderText(int res){
String text = getContext().getString(res);
setAlphaSliderText(text);
}
/**
* Set the text that should be shown in the
* alpha slider. Set to null to disable text.
* @param text Text that should be shown.
*/
public void setAlphaSliderText(String text){
mAlphaSliderText = text;
invalidate();
}
/**
* Get the current value of the text
* that will be shown in the alpha
* slider.
* @return
*/
public String getAlphaSliderText(){
return mAlphaSliderText;
}
}