mirror of https://github.com/NekoX-Dev/NekoX.git
298 lines
9.8 KiB
Java
298 lines
9.8 KiB
Java
package org.telegram.ui.Components;
|
|
|
|
import android.animation.Animator;
|
|
import android.animation.AnimatorListenerAdapter;
|
|
import android.animation.ObjectAnimator;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Color;
|
|
import android.graphics.Paint;
|
|
import android.graphics.Path;
|
|
import android.graphics.PorterDuff;
|
|
import android.graphics.PorterDuffXfermode;
|
|
import android.graphics.Rect;
|
|
import android.graphics.RectF;
|
|
import androidx.annotation.Keep;
|
|
import android.view.View;
|
|
|
|
import org.telegram.messenger.AndroidUtilities;
|
|
import org.telegram.ui.ActionBar.Theme;
|
|
|
|
public class CheckBoxBase {
|
|
|
|
private View parentView;
|
|
private Rect bounds = new Rect();
|
|
private RectF rect = new RectF();
|
|
|
|
private static Paint paint;
|
|
private static Paint eraser;
|
|
private static Paint checkPaint;
|
|
private static Paint backgroundPaint;
|
|
|
|
private Path path = new Path();
|
|
|
|
private Bitmap drawBitmap;
|
|
private Canvas bitmapCanvas;
|
|
|
|
private boolean enabled = true;
|
|
|
|
private boolean attachedToWindow;
|
|
|
|
private float backgroundAlpha = 1.0f;
|
|
|
|
private float progress;
|
|
private ObjectAnimator checkAnimator;
|
|
|
|
private boolean isChecked;
|
|
|
|
private String checkColorKey = Theme.key_checkboxCheck;
|
|
private String backgroundColorKey = Theme.key_chat_serviceBackground;
|
|
private String background2ColorKey = Theme.key_chat_serviceBackground;
|
|
|
|
private boolean useDefaultCheck;
|
|
|
|
private boolean drawUnchecked = true;
|
|
private int drawBackgroundAsArc;
|
|
|
|
private float size = 21;
|
|
|
|
private ProgressDelegate progressDelegate;
|
|
|
|
public interface ProgressDelegate {
|
|
void setProgress(float progress);
|
|
}
|
|
|
|
public CheckBoxBase(View parent) {
|
|
parentView = parent;
|
|
if (paint == null) {
|
|
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
|
|
eraser = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
eraser.setColor(0);
|
|
eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
|
|
|
backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
backgroundPaint.setStyle(Paint.Style.STROKE);
|
|
|
|
checkPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
checkPaint.setStrokeCap(Paint.Cap.ROUND);
|
|
checkPaint.setStyle(Paint.Style.STROKE);
|
|
checkPaint.setStrokeJoin(Paint.Join.ROUND);
|
|
}
|
|
checkPaint.setStrokeWidth(AndroidUtilities.dp(1.9f));
|
|
backgroundPaint.setStrokeWidth(AndroidUtilities.dp(1.2f));
|
|
|
|
drawBitmap = Bitmap.createBitmap(AndroidUtilities.dp(size), AndroidUtilities.dp(size), Bitmap.Config.ARGB_4444);
|
|
bitmapCanvas = new Canvas(drawBitmap);
|
|
}
|
|
|
|
public void onAttachedToWindow() {
|
|
attachedToWindow = true;
|
|
}
|
|
|
|
public void onDetachedFromWindow() {
|
|
attachedToWindow = false;
|
|
}
|
|
|
|
public void setBounds(int x, int y, int width, int height) {
|
|
bounds.left = x;
|
|
bounds.top = y;
|
|
bounds.right = x + width;
|
|
bounds.bottom = y + height;
|
|
}
|
|
|
|
public void setDrawUnchecked(boolean value) {
|
|
drawUnchecked = value;
|
|
}
|
|
|
|
@Keep
|
|
public void setProgress(float value) {
|
|
if (progress == value) {
|
|
return;
|
|
}
|
|
progress = value;
|
|
if (parentView.getParent() != null) {
|
|
View parent = (View) parentView.getParent();
|
|
parent.invalidate();
|
|
}
|
|
parentView.invalidate();
|
|
if (progressDelegate != null) {
|
|
progressDelegate.setProgress(value);
|
|
}
|
|
}
|
|
|
|
public void setProgressDelegate(ProgressDelegate delegate) {
|
|
progressDelegate = delegate;
|
|
}
|
|
|
|
public void setSize(int value) {
|
|
size = value;
|
|
}
|
|
|
|
public float getProgress() {
|
|
return progress;
|
|
}
|
|
|
|
public boolean isChecked() {
|
|
return isChecked;
|
|
}
|
|
|
|
public void setEnabled(boolean value) {
|
|
enabled = value;
|
|
}
|
|
|
|
public void setDrawBackgroundAsArc(int type) {
|
|
drawBackgroundAsArc = type;
|
|
if (type == 4 || type == 5) {
|
|
backgroundPaint.setStrokeWidth(AndroidUtilities.dp(1.9f));
|
|
if (type == 5) {
|
|
checkPaint.setStrokeWidth(AndroidUtilities.dp(1.5f));
|
|
}
|
|
} else if (type == 3) {
|
|
backgroundPaint.setStrokeWidth(AndroidUtilities.dp(1.2f));
|
|
} else if (type != 0) {
|
|
backgroundPaint.setStrokeWidth(AndroidUtilities.dp(1.5f));
|
|
}
|
|
}
|
|
|
|
private void cancelCheckAnimator() {
|
|
if (checkAnimator != null) {
|
|
checkAnimator.cancel();
|
|
checkAnimator = null;
|
|
}
|
|
}
|
|
|
|
private void animateToCheckedState(boolean newCheckedState) {
|
|
checkAnimator = ObjectAnimator.ofFloat(this, "progress", newCheckedState ? 1 : 0);
|
|
checkAnimator.addListener(new AnimatorListenerAdapter() {
|
|
@Override
|
|
public void onAnimationEnd(Animator animation) {
|
|
if (animation.equals(checkAnimator)) {
|
|
checkAnimator = null;
|
|
}
|
|
}
|
|
});
|
|
checkAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT);
|
|
checkAnimator.setDuration(200);
|
|
checkAnimator.start();
|
|
}
|
|
|
|
public void setColor(String background, String background2, String check) {
|
|
backgroundColorKey = background;
|
|
background2ColorKey = background2;
|
|
checkColorKey = check;
|
|
}
|
|
|
|
public void setUseDefaultCheck(boolean value) {
|
|
useDefaultCheck = value;
|
|
}
|
|
|
|
public void setBackgroundAlpha(float alpha) {
|
|
backgroundAlpha = alpha;
|
|
}
|
|
|
|
public void setChecked(boolean checked, boolean animated) {
|
|
if (checked == isChecked) {
|
|
return;
|
|
}
|
|
isChecked = checked;
|
|
|
|
if (attachedToWindow && animated) {
|
|
animateToCheckedState(checked);
|
|
} else {
|
|
cancelCheckAnimator();
|
|
setProgress(checked ? 1.0f : 0.0f);
|
|
}
|
|
}
|
|
|
|
public void draw(Canvas canvas) {
|
|
if (drawBitmap == null) {
|
|
return;
|
|
}
|
|
|
|
drawBitmap.eraseColor(0);
|
|
float rad = AndroidUtilities.dp(size / 2);
|
|
float outerRad = rad;
|
|
if (drawBackgroundAsArc != 0) {
|
|
outerRad -= AndroidUtilities.dp(0.2f);
|
|
}
|
|
|
|
float roundProgress = progress >= 0.5f ? 1.0f : progress / 0.5f;
|
|
|
|
int cx = bounds.centerX();
|
|
int cy = bounds.centerY();
|
|
|
|
if (backgroundColorKey != null) {
|
|
if (drawUnchecked) {
|
|
paint.setColor((Theme.getServiceMessageColor() & 0x00ffffff) | 0x28000000);
|
|
backgroundPaint.setColor(Theme.getColor(checkColorKey));
|
|
} else {
|
|
backgroundPaint.setColor(AndroidUtilities.getOffsetColor(0x00ffffff, Theme.getColor(background2ColorKey != null ? background2ColorKey : checkColorKey), progress, backgroundAlpha));
|
|
}
|
|
} else {
|
|
if (drawUnchecked) {
|
|
paint.setColor(Color.argb((int) (25 * backgroundAlpha), 0, 0, 0));
|
|
backgroundPaint.setColor(AndroidUtilities.getOffsetColor(0xffffffff, Theme.getColor(checkColorKey), progress, backgroundAlpha));
|
|
} else {
|
|
backgroundPaint.setColor(AndroidUtilities.getOffsetColor(0x00ffffff, Theme.getColor(background2ColorKey != null ? background2ColorKey : checkColorKey), progress, backgroundAlpha));
|
|
}
|
|
}
|
|
|
|
if (drawUnchecked) {
|
|
canvas.drawCircle(cx, cy, rad, paint);
|
|
}
|
|
paint.setColor(Theme.getColor(checkColorKey));
|
|
if (drawBackgroundAsArc == 0) {
|
|
canvas.drawCircle(cx, cy, rad, backgroundPaint);
|
|
} else {
|
|
rect.set(cx - outerRad, cy - outerRad, cx + outerRad, cy + outerRad);
|
|
int startAngle;
|
|
int sweepAngle;
|
|
if (drawBackgroundAsArc == 1) {
|
|
startAngle = -90;
|
|
sweepAngle = (int) (-270 * progress);
|
|
} else {
|
|
startAngle = 90;
|
|
sweepAngle = (int) (270 * progress);
|
|
}
|
|
canvas.drawArc(rect, startAngle, sweepAngle, false, backgroundPaint);
|
|
}
|
|
|
|
if (roundProgress > 0) {
|
|
float checkProgress = progress < 0.5f ? 0.0f : (progress - 0.5f) / 0.5f;
|
|
|
|
if (!drawUnchecked && backgroundColorKey != null) {
|
|
paint.setColor(Theme.getColor(backgroundColorKey));
|
|
} else {
|
|
paint.setColor(Theme.getColor(enabled ? Theme.key_checkbox : Theme.key_checkboxDisabled));
|
|
}
|
|
if (!useDefaultCheck && checkColorKey != null) {
|
|
checkPaint.setColor(Theme.getColor(checkColorKey));
|
|
} else {
|
|
checkPaint.setColor(Theme.getColor(Theme.key_checkboxCheck));
|
|
}
|
|
|
|
rad -= AndroidUtilities.dp(0.5f);
|
|
bitmapCanvas.drawCircle(drawBitmap.getWidth() / 2, drawBitmap.getHeight() / 2, rad, paint);
|
|
bitmapCanvas.drawCircle(drawBitmap.getWidth() / 2, drawBitmap.getWidth() / 2, rad * (1.0f - roundProgress), eraser);
|
|
canvas.drawBitmap(drawBitmap, cx - drawBitmap.getWidth() / 2, cy - drawBitmap.getHeight() / 2, null);
|
|
|
|
if (checkProgress != 0) {
|
|
path.reset();
|
|
|
|
float scale = drawBackgroundAsArc == 5 ? 0.8f : 1.0f;
|
|
float checkSide = AndroidUtilities.dp(9 * scale) * checkProgress;
|
|
float smallCheckSide = AndroidUtilities.dp(4 * scale) * checkProgress;
|
|
int x = cx - AndroidUtilities.dp(1.5f);
|
|
int y = cy + AndroidUtilities.dp(4);
|
|
float side = (float) Math.sqrt(smallCheckSide * smallCheckSide / 2.0f);
|
|
path.moveTo(x - side, y - side);
|
|
path.lineTo(x, y);
|
|
side = (float) Math.sqrt(checkSide * checkSide / 2.0f);
|
|
path.lineTo(x + side, y - side);
|
|
canvas.drawPath(path, checkPaint);
|
|
}
|
|
}
|
|
}
|
|
}
|