NekoX/TMessagesProj/src/main/java/org/telegram/ui/Components/SlideChooseView.java

246 lines
8.9 KiB
Java

package org.telegram.ui.Components;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.os.Bundle;
import android.text.TextPaint;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.ActionBar.Theme;
public class SlideChooseView extends View {
private final SeekBarAccessibilityDelegate accessibilityDelegate;
private Paint paint;
private Paint linePaint;
private TextPaint textPaint;
private int lastDash;
private int circleSize;
private int gapSize;
private int sideSide;
private int lineSize;
private int dashedFrom = -1;
private boolean moving;
private boolean startMoving;
private float startX;
private int startMovingPreset;
private String[] optionsStr;
private int[] optionsSizes;
private int selectedIndex;
private Callback callback;
public SlideChooseView(Context context) {
super(context);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setStrokeWidth(AndroidUtilities.dp(2));
linePaint.setStrokeCap(Paint.Cap.ROUND);
textPaint.setTextSize(AndroidUtilities.dp(13));
accessibilityDelegate = new IntSeekBarAccessibilityDelegate() {
@Override
protected int getProgress() {
return selectedIndex;
}
@Override
protected void setProgress(int progress) {
setOption(progress);
}
@Override
protected int getMaxValue() {
return optionsStr.length - 1;
}
@Override
protected CharSequence getContentDescription(View host) {
return selectedIndex < optionsStr.length ? optionsStr[selectedIndex] : null;
}
};
}
public void setCallback(Callback callback) {
this.callback = callback;
}
public void setOptions(int selected, String... options) {
this.optionsStr = options;
selectedIndex = selected;
optionsSizes = new int[optionsStr.length];
for (int i = 0; i < optionsStr.length; i++) {
optionsSizes[i] = (int) Math.ceil(textPaint.measureText(optionsStr[i]));
}
requestLayout();
}
public void setDashedFrom(int from) {
dashedFrom = from;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
getParent().requestDisallowInterceptTouchEvent(true);
for (int a = 0; a < optionsStr.length; a++) {
int cx = sideSide + (lineSize + gapSize * 2 + circleSize) * a + circleSize / 2;
if (x > cx - AndroidUtilities.dp(15) && x < cx + AndroidUtilities.dp(15)) {
startMoving = a == selectedIndex;
startX = x;
startMovingPreset = selectedIndex;
break;
}
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (startMoving) {
if (Math.abs(startX - x) >= AndroidUtilities.getPixelsInCM(0.5f, true)) {
moving = true;
startMoving = false;
}
} else if (moving) {
for (int a = 0; a < optionsStr.length; a++) {
int cx = sideSide + (lineSize + gapSize * 2 + circleSize) * a + circleSize / 2;
int diff = lineSize / 2 + circleSize / 2 + gapSize;
if (x > cx - diff && x < cx + diff) {
if (selectedIndex != a) {
setOption(a);
}
break;
}
}
}
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
if (!moving) {
for (int a = 0; a < 5; a++) {
int cx = sideSide + (lineSize + gapSize * 2 + circleSize) * a + circleSize / 2;
if (x > cx - AndroidUtilities.dp(15) && x < cx + AndroidUtilities.dp(15)) {
if (selectedIndex != a) {
setOption(a);
}
break;
}
}
} else {
if (selectedIndex != startMovingPreset) {
setOption(selectedIndex);
}
}
if (callback != null) {
callback.onTouchEnd();
}
startMoving = false;
moving = false;
}
return true;
}
private void setOption(int index) {
selectedIndex = index;
if (callback != null) {
callback.onOptionSelected(index);
}
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(74), MeasureSpec.EXACTLY));
int width = MeasureSpec.getSize(widthMeasureSpec);
circleSize = AndroidUtilities.dp(6);
gapSize = AndroidUtilities.dp(2);
sideSide = AndroidUtilities.dp(22);
lineSize = (getMeasuredWidth() - circleSize * optionsStr.length - gapSize * 2 * (optionsStr.length - 1) - sideSide * 2) / (optionsStr.length - 1);
}
@Override
protected void onDraw(Canvas canvas) {
textPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
int cy = getMeasuredHeight() / 2 + AndroidUtilities.dp(11);
for (int a = 0; a < optionsStr.length; a++) {
int cx = sideSide + (lineSize + gapSize * 2 + circleSize) * a + circleSize / 2;
if (a <= selectedIndex) {
int color = Theme.getColor(Theme.key_switchTrackChecked);
paint.setColor(color);
linePaint.setColor(color);
} else {
int color = Theme.getColor(Theme.key_switchTrack);
paint.setColor(color);
linePaint.setColor(color);
}
canvas.drawCircle(cx, cy, a == selectedIndex ? AndroidUtilities.dp(6) : circleSize / 2, paint);
if (a != 0) {
int x = cx - circleSize / 2 - gapSize - lineSize;
int width = lineSize;
if (dashedFrom != -1 && a - 1 >= dashedFrom) {
x += AndroidUtilities.dp(3);
width -= AndroidUtilities.dp(3);
int dash = width / AndroidUtilities.dp(13);
if (lastDash != dash) {
float gap = (width - dash * AndroidUtilities.dp(8)) / (float) (dash - 1);
linePaint.setPathEffect(new DashPathEffect(new float[]{AndroidUtilities.dp(6), gap}, 0));
lastDash = dash;
}
canvas.drawLine(x + AndroidUtilities.dp(1), cy, x + width - AndroidUtilities.dp(1), cy, linePaint);
} else {
if (a == selectedIndex || a == selectedIndex + 1) {
width -= AndroidUtilities.dp(3);
}
if (a == selectedIndex + 1) {
x += AndroidUtilities.dp(3);
}
canvas.drawRect(x, cy - AndroidUtilities.dp(1), x + width, cy + AndroidUtilities.dp(1), paint);
}
}
int size = optionsSizes[a];
String text = optionsStr[a];
if (a == 0) {
canvas.drawText(text, AndroidUtilities.dp(22), AndroidUtilities.dp(28), textPaint);
} else if (a == optionsStr.length - 1) {
canvas.drawText(text, getMeasuredWidth() - size - AndroidUtilities.dp(22), AndroidUtilities.dp(28), textPaint);
} else {
canvas.drawText(text, cx - size / 2, AndroidUtilities.dp(28), textPaint);
}
}
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
accessibilityDelegate.onInitializeAccessibilityNodeInfoInternal(this, info);
}
@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
return super.performAccessibilityAction(action, arguments) || accessibilityDelegate.performAccessibilityActionInternal(this, action, arguments);
}
public int getSelectedIndex() {
return selectedIndex;
}
public interface Callback {
void onOptionSelected(int index);
default void onTouchEnd() {
}
}
}