NekoX/TMessagesProj/src/main/java/org/telegram/ui/Components/Crop/CropRotationWheel.java

221 lines
7.7 KiB
Java

package org.telegram.ui.Components.Crop;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
public class CropRotationWheel extends FrameLayout {
public interface RotationWheelListener {
void onStart();
void onChange(float angle);
void onEnd(float angle);
void aspectRatioPressed();
void rotate90Pressed();
}
private static final int MAX_ANGLE = 45;
private static final int DELTA_ANGLE = 5;
private Paint whitePaint;
private Paint bluePaint;
private ImageView aspectRatioButton;
private TextView degreesLabel;
protected float rotation;
private RectF tempRect;
private float prevX;
private RotationWheelListener rotationListener;
public CropRotationWheel(Context context) {
super(context);
tempRect = new RectF(0, 0, 0, 0);
whitePaint = new Paint();
whitePaint.setStyle(Paint.Style.FILL);
whitePaint.setColor(Color.WHITE);
whitePaint.setAlpha(255);
whitePaint.setAntiAlias(true);
bluePaint = new Paint();
bluePaint.setStyle(Paint.Style.FILL);
bluePaint.setColor(0xff51bdf3);
bluePaint.setAlpha(255);
bluePaint.setAntiAlias(true);
aspectRatioButton = new ImageView(context);
aspectRatioButton.setImageResource(R.drawable.tool_cropfix);
aspectRatioButton.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.ACTION_BAR_WHITE_SELECTOR_COLOR));
aspectRatioButton.setScaleType(ImageView.ScaleType.CENTER);
aspectRatioButton.setOnClickListener(v -> {
if (rotationListener != null)
rotationListener.aspectRatioPressed();
});
aspectRatioButton.setContentDescription(LocaleController.getString("AccDescrAspectRatio", R.string.AccDescrAspectRatio));
addView(aspectRatioButton, LayoutHelper.createFrame(70, 64, Gravity.LEFT | Gravity.CENTER_VERTICAL));
ImageView rotation90Button = new ImageView(context);
rotation90Button.setImageResource(R.drawable.tool_rotate);
rotation90Button.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.ACTION_BAR_WHITE_SELECTOR_COLOR));
rotation90Button.setScaleType(ImageView.ScaleType.CENTER);
rotation90Button.setOnClickListener(v -> {
if (rotationListener != null) {
rotationListener.rotate90Pressed();
}
});
rotation90Button.setContentDescription(LocaleController.getString("AccDescrRotate", R.string.AccDescrRotate));
addView(rotation90Button, LayoutHelper.createFrame(70, 64, Gravity.RIGHT | Gravity.CENTER_VERTICAL));
degreesLabel = new TextView(context);
degreesLabel.setTextColor(Color.WHITE);
addView(degreesLabel, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL));
setWillNotDraw(false);
setRotation(0.0f, false);
}
public void setFreeform(boolean freeform) {
aspectRatioButton.setVisibility(freeform ? VISIBLE : GONE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
super.onMeasure(MeasureSpec.makeMeasureSpec(Math.min(width, AndroidUtilities.dp(400)), MeasureSpec.EXACTLY), heightMeasureSpec);
}
public void reset() {
setRotation(0.0f, false);
}
public void setListener(RotationWheelListener listener) {
rotationListener = listener;
}
public void setRotation(float rotation, boolean animated) {
this.rotation = rotation;
float value = this.rotation;
if (Math.abs(value) < 0.1 - 0.001)
value = Math.abs(value);
degreesLabel.setText(String.format("%.1fº", value));
invalidate();
}
public void setAspectLock(boolean enabled) {
aspectRatioButton.setColorFilter(enabled ? new PorterDuffColorFilter(0xff51bdf3, PorterDuff.Mode.SRC_IN) : null);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getActionMasked();
float x = ev.getX();
if (action == MotionEvent.ACTION_DOWN) {
prevX = x;
if (rotationListener != null)
rotationListener.onStart();
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
if (rotationListener != null)
rotationListener.onEnd(this.rotation);
AndroidUtilities.makeAccessibilityAnnouncement(String.format("%.1f°", this.rotation));
} else if (action == MotionEvent.ACTION_MOVE) {
float delta = prevX - x;
float newAngle = this.rotation + (float)(delta / AndroidUtilities.density / Math.PI / 1.65f);
newAngle = Math.max(-MAX_ANGLE, Math.min(MAX_ANGLE, newAngle));
if (Math.abs(newAngle - this.rotation) > 0.001) {
if (Math.abs(newAngle) < 0.05)
newAngle = 0;
setRotation(newAngle, false);
if (rotationListener != null)
rotationListener.onChange(this.rotation);
prevX = x;
}
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
float angle = -rotation * 2;
float delta = angle % DELTA_ANGLE;
int segments = (int)Math.floor(angle / DELTA_ANGLE);
for (int i = 0; i < 16; i++) {
Paint paint = whitePaint;
int a = i;
if (a < segments || (a == 0 && delta < 0))
paint = bluePaint;
drawLine(canvas, a, delta, width, height, (a == segments || a == 0 && segments == - 1), paint);
if (i != 0) {
a = -i;
paint = a > segments ? bluePaint : whitePaint;
drawLine(canvas, a, delta, width, height, a == segments + 1, paint);
}
}
bluePaint.setAlpha(255);
tempRect.left = (width - AndroidUtilities.dp(2.5f)) / 2;
tempRect.top = (height - AndroidUtilities.dp(22)) / 2;
tempRect.right = (width + AndroidUtilities.dp(2.5f)) / 2;
tempRect.bottom = (height + AndroidUtilities.dp(22)) / 2;
canvas.drawRoundRect(tempRect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), bluePaint);
}
protected void drawLine(Canvas canvas, int i, float delta, int width, int height, boolean center, Paint paint) {
int radius = (int)(width / 2.0f - AndroidUtilities.dp(70));
float angle = 90 - (i * DELTA_ANGLE + delta);
int val = (int)(radius * Math.cos(Math.toRadians(angle)));
int x = width / 2 + val;
float f = Math.abs(val) / (float)radius;
int alpha = Math.min(255, Math.max(0, (int)((1.0f - f * f) * 255)));
if (center)
paint = bluePaint;
paint.setAlpha(alpha);
int w = center ? 4 : 2;
int h = center ? AndroidUtilities.dp(16) : AndroidUtilities.dp(12);
canvas.drawRect(x - w / 2, (height - h) / 2, x + w / 2, (height + h) / 2, paint);
}
}