Start implementing the new color selector

This commit is contained in:
artdeell
2022-04-18 23:56:54 +03:00
parent e733d1d53b
commit d1a7fd11e0
6 changed files with 280 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
package net.kdt.pojavlaunch.colorselector;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import net.kdt.pojavlaunch.R;
public class ColorSelector implements HueSelectionListener, RectangleSelectionListener {
HueView mHueView;
SVRectangleView mLuminosityIntensityView;
TextView mTextView;
float[] mHueTemplate = new float[] {0,1,1};
float[] mHsvSelected = new float[] {360,1,1};
AlertDialog mDialog;
public ColorSelector(Context context) {
AlertDialog.Builder bldr = new AlertDialog.Builder(context);
View view = LayoutInflater.from(context).inflate(R.layout.dialog_color_selector,null);
mHueView = view.findViewById(R.id.color_selector_hue_view);
mHueView.setHueSelectionListener(this);
mLuminosityIntensityView = view.findViewById(R.id.color_selector_rectangle_view);
mLuminosityIntensityView.setRectSelectionListener(this);
mTextView = view.findViewById(R.id.color_selector_color_text_view);
bldr.setView(view);
mDialog = bldr.create();
}
public void show() {
mDialog.show();
}
@Override
public void onHueSelected(float hue) {
mHueTemplate[0] = hue;
mLuminosityIntensityView.setColor(Color.HSVToColor(mHueTemplate));
}
@Override
public void onLuminosityIntensityChanged(float luminosity, float intensity) {
mHsvSelected[0] = mHueTemplate[0];
mHsvSelected[1] = (intensity -1)*-1 ;
mHsvSelected[2] = luminosity;
mTextView.setTextColor(Color.HSVToColor(mHsvSelected));
}
}

View File

@@ -0,0 +1,5 @@
package net.kdt.pojavlaunch.colorselector;
public interface HueSelectionListener {
void onHueSelected(float hue);
}

View File

@@ -0,0 +1,77 @@
package net.kdt.pojavlaunch.colorselector;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import net.kdt.pojavlaunch.Tools;
public class HueView extends View {
Bitmap mGamma;
Paint blackPaint = new Paint();
float mSelectionHue;
float mWidthHueRatio;
float mWidth;
float mHeight;
float mHeightThird;
HueSelectionListener mHueSelectionListener;
public HueView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
blackPaint.setColor(Color.BLACK);
blackPaint.setStrokeWidth(Tools.dpToPx(3));
}
public void setHueSelectionListener(HueSelectionListener listener) {
mHueSelectionListener = listener;
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
mSelectionHue = event.getX() * mWidthHueRatio;
invalidate();
if(mHueSelectionListener != null) mHueSelectionListener.onHueSelected(mSelectionHue);
return true;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mGamma, 0, 0 ,null);
float linePos = mSelectionHue / mWidthHueRatio;
canvas.drawLine(linePos, 0 ,linePos, mHeightThird, blackPaint);
canvas.drawLine(linePos, mHeightThird * 2 ,linePos, mHeight, blackPaint);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mWidth = w;
mHeight = h;
mHeightThird = mHeight / 3;
regenerateGammaBitmap();
}
protected void regenerateGammaBitmap() {
if(mGamma != null)
mGamma.recycle();
mGamma = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
Canvas canvas = new Canvas(mGamma);
mWidthHueRatio = 360/ mWidth;
float[] hsvFiller = new float[] {0,1,1};
for(float i = 0; i < mWidth; i++) {
hsvFiller[0] = i * mWidthHueRatio;
paint.setColor(Color.HSVToColor(hsvFiller));
canvas.drawLine(i,0,i, mHeight,paint);
}
}
}

View File

@@ -0,0 +1,5 @@
package net.kdt.pojavlaunch.colorselector;
public interface RectangleSelectionListener {
void onLuminosityIntensityChanged(float luminosity, float intensity);
}

View File

@@ -0,0 +1,106 @@
package net.kdt.pojavlaunch.colorselector;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import net.kdt.pojavlaunch.Tools;
public class SVRectangleView extends View {
Bitmap mSvRectangle;
Paint mColorPaint = new Paint();
Paint mCrosshairPaint = new Paint();
RectF mViewSize;
float mHeightInverted;
float mWidthInverted;
float mCrosshairSize;
float mFingerPosX;
float mFingerPosY;
RectangleSelectionListener mRectSeelctionListener;
public SVRectangleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mColorPaint.setColor(Color.BLACK);
mColorPaint.setStyle(Paint.Style.FILL);
mCrosshairSize = Tools.dpToPx(6);
mCrosshairPaint.setColor(Color.BLACK);
mCrosshairPaint.setStrokeWidth(Tools.dpToPx(3));
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
mFingerPosX = x * mWidthInverted;
mFingerPosY = y * mHeightInverted;
if(mFingerPosX < 0) mFingerPosX = 0;
else if(mFingerPosX > 1) mFingerPosX = 1;
if(mFingerPosY < 0) mFingerPosY = 0;
else if(mFingerPosY > 1) mFingerPosY = 1;
if(mRectSeelctionListener != null) mRectSeelctionListener.onLuminosityIntensityChanged(mFingerPosY,mFingerPosX);
invalidate();
return true;
}
public void setColor(int color) {
mColorPaint.setColor(color);
invalidate();
}
public void setRectSelectionListener(RectangleSelectionListener listener) {
mRectSeelctionListener = listener;
}
protected void drawCrosshair(Canvas canvas, float x, float y) {
canvas.drawLine(mCrosshairSize * 2 + x, y, mCrosshairSize + x, y, mCrosshairPaint);
canvas.drawLine(x - mCrosshairSize * 2, y, x - mCrosshairSize, y, mCrosshairPaint);
canvas.drawLine(x, mCrosshairSize * 2 + y, x, mCrosshairSize + y, mCrosshairPaint);
canvas.drawLine(x, y - mCrosshairSize * 2, x, y - mCrosshairSize, mCrosshairPaint);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(mViewSize, mColorPaint);
drawCrosshair(canvas, mViewSize.right * mFingerPosX, mViewSize.bottom * mFingerPosY);
if(mSvRectangle != null)
canvas.drawBitmap(mSvRectangle, 0,0, null);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mViewSize = new RectF(0,0, w,h);
mWidthInverted = 1/mViewSize.right;
mHeightInverted = 1/mViewSize.bottom;
if(w > 0 && h > 0)
regenerateRectangle();
}
protected void regenerateRectangle() {
int w = getWidth();
int h = getHeight();
if(mSvRectangle != null)
mSvRectangle.recycle();
mSvRectangle = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
float intensityRatio = 255f / h;
float luminosityRatio = 255f / w;
for(int x = 0; x < w; x++) {
for(int y = 0; y < h; y++) {
int intensity = (int)(y * intensityRatio);
mSvRectangle.setPixel(x,y,Color.argb((int)(x * luminosityRatio), intensity, intensity, intensity));
}
}
}
}

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<net.kdt.pojavlaunch.colorselector.HueView
android:id="@+id/color_selector_hue_view"
android:layout_width="0dp"
android:layout_height="55dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<net.kdt.pojavlaunch.colorselector.SVRectangleView
android:id="@+id/color_selector_rectangle_view"
android:layout_width="0dp"
android:layout_height="250dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toTopOf="@+id/color_selector_color_text_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/color_selector_color_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/color_selector_hue_view"
app:layout_constraintStart_toStartOf="@+id/color_selector_hue_view" />
</androidx.constraintlayout.widget.ConstraintLayout>