Initial commit
This commit is contained in:
2
library/ColorPicker/.gitignore
vendored
Normal file
2
library/ColorPicker/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/build
|
||||
/*.iml
|
||||
11
library/ColorPicker/build.gradle
Normal file
11
library/ColorPicker/build.gradle
Normal file
@@ -0,0 +1,11 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
ext {
|
||||
isLibrary = true
|
||||
pomArtifactId = "ColorPicker"
|
||||
pomDescription = "color picker for android"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(":library:Common")
|
||||
}
|
||||
2
library/ColorPicker/src/main/AndroidManifest.xml
Normal file
2
library/ColorPicker/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="cn.qqtheme.framework.colorpicker" />
|
||||
@@ -0,0 +1,192 @@
|
||||
package cn.qqtheme.framework.picker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.InputType;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import cn.qqtheme.framework.colorpicker.R;
|
||||
import cn.qqtheme.framework.popup.ConfirmPopup;
|
||||
import cn.qqtheme.framework.util.CompatUtils;
|
||||
import cn.qqtheme.framework.util.ConvertUtils;
|
||||
import cn.qqtheme.framework.widget.ColorPanelView;
|
||||
|
||||
/**
|
||||
* 颜色选择器。
|
||||
*
|
||||
* @author 李玉江[QQ :1032694760]
|
||||
* @version 2015 /9/29
|
||||
*/
|
||||
public class ColorPicker extends ConfirmPopup<LinearLayout> implements TextView.OnEditorActionListener {
|
||||
private static final int MULTI_ID = 0x1;
|
||||
private static final int BLACK_ID = 0x2;
|
||||
private int initColor = Color.WHITE;
|
||||
private ColorPanelView multiColorView, blackColorView;
|
||||
private EditText hexValView;
|
||||
private ColorStateList hexValDefaultColor;
|
||||
private OnColorPickListener onColorPickListener;
|
||||
|
||||
/**
|
||||
* Instantiates a new Color picker.
|
||||
*
|
||||
* @param activity the activity
|
||||
*/
|
||||
public ColorPicker(Activity activity) {
|
||||
super(activity);
|
||||
setHalfScreen(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
protected LinearLayout makeCenterView() {
|
||||
LinearLayout rootLayout = new LinearLayout(activity);
|
||||
rootLayout.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
|
||||
rootLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
blackColorView = new ColorPanelView(activity);
|
||||
//noinspection ResourceType
|
||||
blackColorView.setId(BLACK_ID);
|
||||
blackColorView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, ConvertUtils.toPx(activity, 30)));
|
||||
blackColorView.setPointerDrawable(CompatUtils.getDrawable(activity, R.drawable.color_picker_cursor_bottom));
|
||||
blackColorView.setLockPointerInBounds(false);
|
||||
blackColorView.setOnColorChangedListener(new ColorPanelView.OnColorChangedListener() {
|
||||
@Override
|
||||
public void onColorChanged(ColorPanelView view, int color) {
|
||||
updateCurrentColor(color);
|
||||
}
|
||||
});
|
||||
rootLayout.addView(blackColorView);
|
||||
multiColorView = new ColorPanelView(activity);
|
||||
//noinspection ResourceType
|
||||
multiColorView.setId(MULTI_ID);
|
||||
multiColorView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, 0, 1.0f));
|
||||
multiColorView.setPointerDrawable(CompatUtils.getDrawable(activity, R.drawable.color_picker_cursor_top));
|
||||
multiColorView.setLockPointerInBounds(true);
|
||||
multiColorView.setOnColorChangedListener(new ColorPanelView.OnColorChangedListener() {
|
||||
@Override
|
||||
public void onColorChanged(ColorPanelView view, int color) {
|
||||
updateCurrentColor(color);
|
||||
}
|
||||
});
|
||||
rootLayout.addView(multiColorView);
|
||||
LinearLayout previewLayout = new LinearLayout(activity);
|
||||
previewLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
previewLayout.setGravity(Gravity.CENTER);
|
||||
previewLayout.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, ConvertUtils.toPx(activity, 30)));
|
||||
hexValView = new EditText(activity);
|
||||
hexValView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
|
||||
hexValView.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||
hexValView.setImeOptions(EditorInfo.IME_ACTION_DONE);
|
||||
hexValView.setGravity(Gravity.CENTER);
|
||||
hexValView.setBackgroundColor(initColor);
|
||||
hexValView.setTextColor(Color.BLACK);
|
||||
hexValView.setShadowLayer(3, 0, 2, Color.WHITE);//设置阴影,以便背景色为黑色系列时仍然看得见
|
||||
hexValView.setMinEms(6);
|
||||
hexValView.setMaxEms(8);
|
||||
hexValView.setPadding(0, 0, 0, 0);
|
||||
hexValView.setSingleLine(true);
|
||||
hexValView.setOnEditorActionListener(this);
|
||||
hexValDefaultColor = hexValView.getTextColors();
|
||||
previewLayout.addView(hexValView);
|
||||
rootLayout.addView(previewLayout);
|
||||
return rootLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setContentViewAfter(View contentView) {
|
||||
multiColorView.setColor(initColor);//将触发onColorChanged,故必须先待其他控件初始化完成后才能调用
|
||||
multiColorView.setBrightnessGradientView(blackColorView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit() {
|
||||
if (onColorPickListener != null) {
|
||||
onColorPickListener.onColorPicked(getCurrentColor());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current color.
|
||||
*
|
||||
* @return the current color
|
||||
*/
|
||||
@ColorInt
|
||||
public int getCurrentColor() {
|
||||
return Color.parseColor("#" + hexValView.getText());
|
||||
}
|
||||
|
||||
private void updateCurrentColor(int color) {
|
||||
String hexColorString = ConvertUtils.toColorString(color, false).toUpperCase(Locale.getDefault());
|
||||
hexValView.setText(hexColorString);
|
||||
hexValView.setTextColor(hexValDefaultColor);
|
||||
hexValView.setBackgroundColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets init color.
|
||||
*
|
||||
* @param initColor the init color
|
||||
*/
|
||||
public void setInitColor(int initColor) {
|
||||
this.initColor = initColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on color pick listener.
|
||||
*
|
||||
* @param onColorPickListener the on color pick listener
|
||||
*/
|
||||
public void setOnColorPickListener(OnColorPickListener onColorPickListener) {
|
||||
this.onColorPickListener = onColorPickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
||||
String hexString = hexValView.getText().toString();
|
||||
int length = hexString.length();
|
||||
if (length == 6 || length == 8) {
|
||||
try {
|
||||
int color = Color.parseColor("#" + hexString);
|
||||
multiColorView.setColor(color);
|
||||
hexValView.setTextColor(hexValDefaultColor);
|
||||
} catch (IllegalArgumentException e) {
|
||||
hexValView.setTextColor(Color.RED);
|
||||
}
|
||||
} else {
|
||||
hexValView.setTextColor(Color.RED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The interface On color pick listener.
|
||||
*/
|
||||
public interface OnColorPickListener {
|
||||
|
||||
/**
|
||||
* On color picked.
|
||||
*
|
||||
* @param pickedColor the picked color
|
||||
*/
|
||||
void onColorPicked(@ColorInt int pickedColor);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
package cn.qqtheme.framework.widget;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
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.PorterDuff;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* 颜色选择面板
|
||||
*
|
||||
* @author 李玉江[QQ :1023694760]
|
||||
* @version 2015/7/20
|
||||
* @link https ://github.com/jbruchanov/AndroidColorPicker
|
||||
*/
|
||||
public class ColorPanelView extends View {
|
||||
private static final int[] GRAD_COLORS = new int[]{Color.RED, Color.YELLOW, Color.GREEN, Color.CYAN, Color.BLUE, Color.MAGENTA, Color.RED};
|
||||
private static final int[] GRAD_ALPHA = new int[]{Color.WHITE, Color.TRANSPARENT};
|
||||
|
||||
private ColorPanelView mBrightnessGradientView;
|
||||
private Shader mShader;
|
||||
private Drawable mPointerDrawable;
|
||||
private Paint mPaint;
|
||||
private Paint mPaintBackground;
|
||||
private RectF mGradientRect = new RectF();
|
||||
|
||||
private float[] mHSV = new float[]{1f, 1f, 1f};
|
||||
|
||||
private int[] mSelectedColorGradient = new int[]{0, Color.BLACK};
|
||||
private float mRadius = 0;
|
||||
private int mSelectedColor = 0;
|
||||
private boolean mIsBrightnessGradient = false;
|
||||
private int mLastX = Integer.MIN_VALUE;
|
||||
private int mLastY;
|
||||
private int mPointerHeight;
|
||||
private int mPointerWidth;
|
||||
private boolean mLockPointerInBounds = false;
|
||||
|
||||
private OnColorChangedListener mOnColorChangedListener;
|
||||
|
||||
/**
|
||||
* The interface On color changed listener.
|
||||
*/
|
||||
public interface OnColorChangedListener {
|
||||
/**
|
||||
* On color changed.
|
||||
*
|
||||
* @param view the view
|
||||
* @param color the color
|
||||
*/
|
||||
void onColorChanged(ColorPanelView view, int color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Color panel view.
|
||||
*
|
||||
* @param context the context
|
||||
*/
|
||||
public ColorPanelView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Color panel view.
|
||||
*
|
||||
* @param context the context
|
||||
* @param attrs the attrs
|
||||
*/
|
||||
public ColorPanelView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Color panel view.
|
||||
*
|
||||
* @param context the context
|
||||
* @param attrs the attrs
|
||||
* @param defStyleAttr the def style attr
|
||||
*/
|
||||
public ColorPanelView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
private void init() {
|
||||
setClickable(true);
|
||||
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaintBackground = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaintBackground.setColor(Color.WHITE);
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
setLayerType(View.LAYER_TYPE_SOFTWARE, isInEditMode() ? null : mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int desiredWidth = 0;
|
||||
int desiredHeight = 0;
|
||||
|
||||
if (mPointerDrawable != null) {
|
||||
desiredHeight = mPointerDrawable.getIntrinsicHeight();
|
||||
//this is nonsense, but at least have something than 0
|
||||
desiredWidth = mPointerDrawable.getIntrinsicWidth();
|
||||
}
|
||||
|
||||
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
//Measure Width
|
||||
if (widthMode == MeasureSpec.EXACTLY) {
|
||||
//Must be this size
|
||||
width = widthSize;
|
||||
} else if (widthMode == MeasureSpec.AT_MOST) {
|
||||
//Can't be bigger than...
|
||||
width = Math.min(desiredWidth, widthSize);
|
||||
} else {
|
||||
//Be whatever you want
|
||||
width = desiredWidth;
|
||||
}
|
||||
|
||||
//Measure Height
|
||||
if (heightMode == MeasureSpec.EXACTLY) {
|
||||
//Must be this size
|
||||
height = heightSize;
|
||||
} else if (heightMode == MeasureSpec.AT_MOST) {
|
||||
//Can't be bigger than...
|
||||
height = Math.min(desiredHeight, heightSize);
|
||||
} else {
|
||||
//Be whatever you want
|
||||
height = desiredHeight;
|
||||
}
|
||||
|
||||
//MUST CALL THIS
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (mShader != null) {
|
||||
canvas.drawRoundRect(mGradientRect, mRadius, mRadius, mPaintBackground);
|
||||
canvas.drawRoundRect(mGradientRect, mRadius, mRadius, mPaint);
|
||||
}
|
||||
|
||||
onDrawPointer(canvas);
|
||||
|
||||
}
|
||||
|
||||
private void onDrawPointer(Canvas canvas) {
|
||||
if (mPointerDrawable != null) {
|
||||
int vh = getHeight();
|
||||
int pwh = mPointerWidth >> 1;
|
||||
int phh = mPointerHeight >> 1;
|
||||
float tx, ty;
|
||||
if (!mIsBrightnessGradient) {
|
||||
tx = mLastX - pwh;
|
||||
ty = mLastY - phh;
|
||||
if (mLockPointerInBounds) {
|
||||
tx = Math.max(mGradientRect.left, Math.min(tx, mGradientRect.right - mPointerWidth));
|
||||
ty = Math.max(mGradientRect.top, Math.min(ty, mGradientRect.bottom - mPointerHeight));
|
||||
} else {
|
||||
tx = Math.max(mGradientRect.left - pwh, Math.min(tx, mGradientRect.right - pwh));
|
||||
ty = Math.max(mGradientRect.top - pwh, Math.min(ty, mGradientRect.bottom - phh));
|
||||
}
|
||||
} else {//vertical lock
|
||||
tx = mLastX - pwh;
|
||||
ty = mPointerHeight != mPointerDrawable.getIntrinsicHeight() ? (vh >> 1) - phh : 0;
|
||||
if (mLockPointerInBounds) {
|
||||
tx = Math.max(mGradientRect.left, Math.min(tx, mGradientRect.right - mPointerWidth));
|
||||
ty = Math.max(mGradientRect.top, Math.min(ty, mGradientRect.bottom - mPointerHeight));
|
||||
} else {
|
||||
tx = Math.max(mGradientRect.left - pwh, Math.min(tx, mGradientRect.right - pwh));
|
||||
ty = Math.max(mGradientRect.top - pwh, Math.min(ty, mGradientRect.bottom - phh));
|
||||
}
|
||||
}
|
||||
canvas.translate(tx, ty);
|
||||
mPointerDrawable.draw(canvas);
|
||||
canvas.translate(-tx, -ty);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
mGradientRect.set(getPaddingLeft(), getPaddingTop(), right - left - getPaddingRight(), bottom - top - getPaddingBottom());
|
||||
if (changed) {
|
||||
buildShader();
|
||||
}
|
||||
|
||||
if (mPointerDrawable != null) {
|
||||
int h = (int) mGradientRect.height();
|
||||
int ph = mPointerDrawable.getIntrinsicHeight();
|
||||
int pw = mPointerDrawable.getIntrinsicWidth();
|
||||
mPointerHeight = ph;
|
||||
mPointerWidth = pw;
|
||||
if (h < ph) {
|
||||
mPointerHeight = h;
|
||||
mPointerWidth = (int) (pw * (h / (float) ph));
|
||||
}
|
||||
mPointerDrawable.setBounds(0, 0, mPointerWidth, mPointerHeight);
|
||||
updatePointerPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void buildShader() {
|
||||
if (mIsBrightnessGradient) {
|
||||
mShader = new LinearGradient(mGradientRect.left, mGradientRect.top, mGradientRect.right, mGradientRect.top, mSelectedColorGradient, null, Shader.TileMode.CLAMP);
|
||||
} else {
|
||||
LinearGradient gradientShader = new LinearGradient(mGradientRect.left, mGradientRect.top, mGradientRect.right, mGradientRect.top, GRAD_COLORS, null, Shader.TileMode.CLAMP);
|
||||
LinearGradient alphaShader = new LinearGradient(0, mGradientRect.top + (mGradientRect.height() / 3), 0, mGradientRect.bottom, GRAD_ALPHA, null, Shader.TileMode.CLAMP);
|
||||
mShader = new ComposeShader(alphaShader, gradientShader, PorterDuff.Mode.MULTIPLY);
|
||||
}
|
||||
mPaint.setShader(mShader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set radius for gradient rectangle
|
||||
*
|
||||
* @param radius the radius
|
||||
*/
|
||||
public void setRadius(float radius) {
|
||||
if (radius != mRadius) {
|
||||
mRadius = radius;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
mLastX = (int) event.getX();
|
||||
mLastY = (int) event.getY();
|
||||
onUpdateColorSelection(mLastX, mLastY);
|
||||
invalidate();
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
getParent().requestDisallowInterceptTouchEvent(true);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
getParent().requestDisallowInterceptTouchEvent(false);
|
||||
break;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update color based on touch events
|
||||
*
|
||||
* @param x the x
|
||||
* @param y the y
|
||||
*/
|
||||
protected void onUpdateColorSelection(int x, int y) {
|
||||
x = (int) Math.max(mGradientRect.left, Math.min(x, mGradientRect.right));
|
||||
y = (int) Math.max(mGradientRect.top, Math.min(y, mGradientRect.bottom));
|
||||
if (mIsBrightnessGradient) {
|
||||
float b = pointToValueBrightness(x);
|
||||
mHSV[2] = b;
|
||||
mSelectedColor = Color.HSVToColor(mHSV);
|
||||
} else {
|
||||
float hue = pointToHue(x);
|
||||
float sat = pointToSaturation(y);
|
||||
mHSV[0] = hue;
|
||||
mHSV[1] = sat;
|
||||
mHSV[2] = 1f;
|
||||
mSelectedColor = Color.HSVToColor(mHSV);
|
||||
}
|
||||
dispatchColorChanged(mSelectedColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch color changed.
|
||||
*
|
||||
* @param color the color
|
||||
*/
|
||||
protected void dispatchColorChanged(int color) {
|
||||
if (mBrightnessGradientView != null) {
|
||||
mBrightnessGradientView.setColor(color, false);
|
||||
}
|
||||
if (mOnColorChangedListener != null) {
|
||||
mOnColorChangedListener.onColorChanged(this, color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch view into brightness gradient only
|
||||
*
|
||||
* @param isBrightnessGradient the is brightness gradient
|
||||
*/
|
||||
public void setIsBrightnessGradient(boolean isBrightnessGradient) {
|
||||
mIsBrightnessGradient = isBrightnessGradient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add reference for brightness view
|
||||
*
|
||||
* @param brightnessGradient the brightness gradient
|
||||
*/
|
||||
public void setBrightnessGradientView(ColorPanelView brightnessGradient) {
|
||||
if (mBrightnessGradientView != brightnessGradient) {
|
||||
mBrightnessGradientView = brightnessGradient;
|
||||
|
||||
if (mBrightnessGradientView != null) {
|
||||
mBrightnessGradientView.setIsBrightnessGradient(true);
|
||||
mBrightnessGradientView.setColor(mSelectedColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current selectec color
|
||||
*
|
||||
* @return selected color
|
||||
*/
|
||||
public int getSelectedColor() {
|
||||
return mSelectedColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update current color
|
||||
*
|
||||
* @param selectedColor the selected color
|
||||
*/
|
||||
public void setColor(int selectedColor) {
|
||||
setColor(selectedColor, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets color.
|
||||
*
|
||||
* @param selectedColor the selected color
|
||||
* @param updatePointers the update pointers
|
||||
*/
|
||||
protected void setColor(int selectedColor, boolean updatePointers) {
|
||||
Color.colorToHSV(selectedColor, mHSV);
|
||||
if (mIsBrightnessGradient) {
|
||||
mSelectedColorGradient[0] = getColorForGradient(mHSV);
|
||||
mSelectedColor = Color.HSVToColor(mHSV);
|
||||
buildShader();
|
||||
if (mLastX != Integer.MIN_VALUE) {
|
||||
mHSV[2] = pointToValueBrightness(mLastX);
|
||||
}
|
||||
selectedColor = Color.HSVToColor(mHSV);
|
||||
}
|
||||
if (updatePointers) {
|
||||
updatePointerPosition();
|
||||
}
|
||||
mSelectedColor = selectedColor;
|
||||
invalidate();
|
||||
dispatchColorChanged(mSelectedColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get start color for gradient
|
||||
*
|
||||
* @param hsv
|
||||
* @return
|
||||
*/
|
||||
private int getColorForGradient(float[] hsv) {
|
||||
if (hsv[2] != 1f) {
|
||||
float oldV = hsv[2];
|
||||
hsv[2] = 1;
|
||||
int color = Color.HSVToColor(hsv);
|
||||
hsv[2] = oldV;
|
||||
return color;
|
||||
} else {
|
||||
return Color.HSVToColor(hsv);
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePointerPosition() {
|
||||
if (mGradientRect.width() != 0 && mGradientRect.height() != 0) {
|
||||
if (!mIsBrightnessGradient) {
|
||||
mLastX = hueToPoint(mHSV[0]);
|
||||
mLastY = saturationToPoint(mHSV[1]);
|
||||
} else {
|
||||
mLastX = brightnessToPoint(mHSV[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets on color changed listener.
|
||||
*
|
||||
* @param onColorChangedListener the on color changed listener
|
||||
*/
|
||||
public void setOnColorChangedListener(OnColorChangedListener onColorChangedListener) {
|
||||
mOnColorChangedListener = onColorChangedListener;
|
||||
}
|
||||
|
||||
//region HSL math
|
||||
|
||||
/**
|
||||
* @param x x coordinate of gradient
|
||||
* @return
|
||||
*/
|
||||
private float pointToHue(float x) {
|
||||
x = x - mGradientRect.left;
|
||||
return x * 360f / mGradientRect.width();
|
||||
}
|
||||
|
||||
private int hueToPoint(float hue) {
|
||||
return (int) (mGradientRect.left + ((hue * mGradientRect.width()) / 360));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get saturation
|
||||
*
|
||||
* @param y
|
||||
* @return
|
||||
*/
|
||||
private float pointToSaturation(float y) {
|
||||
y = y - mGradientRect.top;
|
||||
return 1 - (1.f / mGradientRect.height() * y);
|
||||
}
|
||||
|
||||
private int saturationToPoint(float sat) {
|
||||
sat = 1 - sat;
|
||||
return (int) (mGradientRect.top + (mGradientRect.height() * sat));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value of brightness
|
||||
*
|
||||
* @param x
|
||||
* @return
|
||||
*/
|
||||
private float pointToValueBrightness(float x) {
|
||||
x = x - mGradientRect.left;
|
||||
return 1 - (1.f / mGradientRect.width() * x);
|
||||
}
|
||||
|
||||
private int brightnessToPoint(float val) {
|
||||
val = 1 - val;
|
||||
return (int) (mGradientRect.left + (mGradientRect.width() * val));
|
||||
}
|
||||
//endregion HSL math
|
||||
|
||||
/**
|
||||
* Sets pointer drawable.
|
||||
*
|
||||
* @param pointerDrawable the pointer drawable
|
||||
*/
|
||||
public void setPointerDrawable(Drawable pointerDrawable) {
|
||||
if (mPointerDrawable != pointerDrawable) {
|
||||
mPointerDrawable = pointerDrawable;
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets lock pointer in bounds.
|
||||
*
|
||||
* @param lockPointerInBounds the lock pointer in bounds
|
||||
*/
|
||||
public void setLockPointerInBounds(boolean lockPointerInBounds) {
|
||||
if (lockPointerInBounds != mLockPointerInBounds) {
|
||||
mLockPointerInBounds = lockPointerInBounds;
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Parcelable onSaveInstanceState() {
|
||||
Parcelable superState = super.onSaveInstanceState();
|
||||
SavedState ss = new SavedState(superState);
|
||||
ss.isBrightnessGradient = mIsBrightnessGradient;
|
||||
ss.color = mSelectedColor;
|
||||
return ss;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Parcelable state) {
|
||||
if (!(state instanceof SavedState)) {
|
||||
super.onRestoreInstanceState(state);
|
||||
return;
|
||||
}
|
||||
|
||||
SavedState ss = (SavedState) state;
|
||||
super.onRestoreInstanceState(ss.getSuperState());
|
||||
|
||||
mIsBrightnessGradient = ss.isBrightnessGradient;
|
||||
setColor(ss.color, true);
|
||||
}
|
||||
|
||||
private static class SavedState extends BaseSavedState {
|
||||
/**
|
||||
* The Color.
|
||||
*/
|
||||
int color;
|
||||
/**
|
||||
* The Is brightness gradient.
|
||||
*/
|
||||
boolean isBrightnessGradient;
|
||||
|
||||
/**
|
||||
* Instantiates a new Saved state.
|
||||
*
|
||||
* @param superState the super state
|
||||
*/
|
||||
SavedState(Parcelable superState) {
|
||||
super(superState);
|
||||
}
|
||||
|
||||
private SavedState(Parcel in) {
|
||||
super(in);
|
||||
color = in.readInt();
|
||||
isBrightnessGradient = in.readInt() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
super.writeToParcel(out, flags);
|
||||
out.writeInt(color);
|
||||
out.writeInt(isBrightnessGradient ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* The constant CREATOR.
|
||||
*/
|
||||
//required field that makes Parcelables from a Parcel
|
||||
public static final Creator<SavedState> CREATOR =
|
||||
new Creator<SavedState>() {
|
||||
public SavedState createFromParcel(Parcel in) {
|
||||
return new SavedState(in);
|
||||
}
|
||||
|
||||
public SavedState[] newArray(int size) {
|
||||
return new SavedState[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 807 B |
Reference in New Issue
Block a user