You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CustoMIUIzer/app/src/main/java/name/mikanoshi/customiuizer/utils/ColorCircle.java

188 lines
6.3 KiB
Java

package name.mikanoshi.customiuizer.utils;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RadialGradient;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import name.mikanoshi.customiuizer.R;
public class ColorCircle extends View {
private float posXin;
private float posYin;
private float radius;
private float innerRadius;
private int offset;
private final Paint paint1 = new Paint();
private final Paint paint1a = new Paint();
private final Paint paint2 = new Paint();
private final Paint paint3 = new Paint();
private ColorListener listener;
private boolean mTransparent = false;
private final float[] mColor = new float[3];
private boolean initialized = false;
public ColorCircle(Context context) {
this(context, null);
}
public ColorCircle(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0);
}
public ColorCircle(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
}
public int getColor() {
return this.mTransparent ? Color.TRANSPARENT : Color.HSVToColor(this.mColor);
}
public void setColor(int color) {
this.mTransparent = color == Color.TRANSPARENT;
Color.RGBToHSV(Color.red(color), Color.green(color), Color.blue(color), this.mColor);
if (this.listener != null) this.listener.onColorSelected(mTransparent ? Color.TRANSPARENT : Color.HSVToColor(this.mColor));
PointF coords = getPointForColor();
updatePickerPos(coords.x, coords.y);
postInvalidate();
}
private void update() {
float diameter = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels) *
(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 0.7f : 0.8f);
this.radius = diameter / 2.0f;
this.innerRadius = this.radius - this.offset * 2;
this.getLayoutParams().width = Math.round(diameter);
this.getLayoutParams().height = Math.round(diameter);
int steps = 6;
int[] colors = new int[steps + 1];
float[] hsv = new float[] { 0.0f, 1.0f, 1.0f };
for (int i = 0; i < steps; i++) {
hsv[0] = (360f / steps) * i;
colors[i] = Color.HSVToColor(hsv);
}
colors[steps] = colors[0];
this.paint1.setShader(new SweepGradient(this.radius, this.radius, colors, null));
this.paint1a.setShader(new RadialGradient(this.radius, this.radius, this.radius, 0xFFFFFFFF, 0x00FFFFFF, android.graphics.Shader.TileMode.CLAMP));
}
public PointF getPointForColor() {
float hue = this.mColor[0];
float sat = this.mColor[1];
PointF point = new PointF();
point.x = (float)(this.radius + this.radius * sat * Math.cos(Math.toRadians(hue)));
point.y = (float)(this.radius + this.radius * sat * Math.sin(Math.toRadians(hue)));
return point;
}
public void getColorForPoint(int x, int y) {
x -= this.radius;
y -= this.radius;
this.mColor[0] = (float)(Math.toDegrees(Math.atan2(y, x)) + 360f) % 360f;
this.mColor[1] = Math.max(0f, Math.min(1f, (float)(Math.hypot(x, y) / this.radius)));
this.mTransparent = false;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
update();
postInvalidate();
}
public void init() {
this.setLayerType(View.LAYER_TYPE_HARDWARE, null);
this.paint1.setAntiAlias(true);
this.paint1a.setAntiAlias(true);
this.paint2.setAntiAlias(true);
this.paint2.setColor(Color.CYAN);
this.paint2.setStrokeWidth(2.0f);
this.paint2.setStyle(Paint.Style.STROKE);
this.paint3.setAntiAlias(true);
this.paint3.setColor(Color.WHITE);
this.paint3.setStyle(Paint.Style.FILL_AND_STROKE);
this.offset = (int)getResources().getDimension(R.dimen.screen_color_preview_offset);
int prefColor = Helpers.prefs.getInt((String)getTag(), Color.WHITE);
this.mTransparent = prefColor == Color.TRANSPARENT;
Color.RGBToHSV(Color.red(prefColor), Color.green(prefColor), Color.blue(prefColor), this.mColor);
update();
PointF coords = getPointForColor();
updatePickerPos(coords.x, coords.y);
initialized = true;
postInvalidate();
}
public void setValue(float value) {
this.mTransparent = false;
this.mColor[2] = value;
if (this.listener != null) this.listener.onColorSelected(Color.HSVToColor(this.mColor));
postInvalidate();
}
public interface ColorListener {
void onColorSelected(int color);
}
public void setListener(ColorListener colorListener) {
this.listener = colorListener;
}
private float distanceToCenter(float f, float f2) {
return (float)Math.hypot((double)(this.radius - f), (double)(this.radius - f2));
}
private boolean isInCircle(float f, float f2, float radius) {
return distanceToCenter(f, f2) <= radius;
}
private void limitByCircle(float f, float f2, float radius) {
float angle = (float)Math.atan2(f - this.radius, f2 - this.radius);
this.posXin = radius + (float)(radius * Math.sin(angle)) + this.offset * 2;
this.posYin = radius + (float)(radius * Math.cos(angle)) + this.offset * 2;
}
private void updatePickerPos(float x, float y) {
if (isInCircle(x, y, this.innerRadius)) {
this.posXin = x;
this.posYin = y;
} else {
limitByCircle(x, y, this.innerRadius);
}
}
public boolean dispatchTouchEvent(MotionEvent motionEvent) {
if (!initialized) return false;
getParent().requestDisallowInterceptTouchEvent(true);
if (!isEnabled()) return true;
float x = motionEvent.getX();
float y = motionEvent.getY();
updatePickerPos(x, y);
getColorForPoint((int)x, (int)y);
if (this.listener != null) this.listener.onColorSelected(Color.HSVToColor(this.mColor));
postInvalidate();
return true;
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!initialized) return;
canvas.drawCircle(this.radius, this.radius, this.radius - this.offset * 2, paint1);
canvas.drawCircle(this.radius, this.radius, this.radius - this.offset * 2, paint1a);
canvas.drawCircle(this.posXin, this.posYin, (float)this.offset, this.paint2);
canvas.drawCircle(this.posXin, this.posYin, (float)(this.offset - 2), this.paint3);
}
}