mirror of https://github.com/NekoX-Dev/NekoX.git
261 lines
9.4 KiB
Java
261 lines
9.4 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 float xTouchDown;
|
|
private float yTouchDown;
|
|
|
|
private int startMovingPreset;
|
|
|
|
private String[] optionsStr;
|
|
private int[] optionsSizes;
|
|
|
|
private int selectedIndex;
|
|
|
|
private Callback callback;
|
|
private final Theme.ResourcesProvider resourcesProvider;
|
|
|
|
public SlideChooseView(Context context) {
|
|
this(context, null);
|
|
}
|
|
|
|
public SlideChooseView(Context context, Theme.ResourcesProvider resourcesProvider) {
|
|
super(context);
|
|
this.resourcesProvider = resourcesProvider;
|
|
|
|
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();
|
|
float y = event.getY();
|
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
|
xTouchDown = x;
|
|
yTouchDown = y;
|
|
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 (!moving) {
|
|
if (Math.abs(xTouchDown - x) > Math.abs(yTouchDown - y)) {
|
|
getParent().requestDisallowInterceptTouchEvent(true);
|
|
}
|
|
}
|
|
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;
|
|
getParent().requestDisallowInterceptTouchEvent(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));
|
|
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(getThemedColor(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;
|
|
int color = a <= selectedIndex ? getThemedColor(Theme.key_switchTrackChecked) : getThemedColor(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;
|
|
}
|
|
|
|
private int getThemedColor(String key) {
|
|
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
|
|
return color != null ? color : Theme.getColor(key);
|
|
}
|
|
|
|
|
|
public interface Callback {
|
|
void onOptionSelected(int index);
|
|
|
|
default void onTouchEnd() {
|
|
|
|
}
|
|
}
|
|
} |