session-android/src/org/thoughtcrime/securesms/scribbles/widget/VerticalSlideColorPicker.java

202 lines
6.0 KiB
Java

/**
* Copyright (c) 2016 Mark Charles
* Copyright (c) 2016 Open Whisper Systems
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.thoughtcrime.securesms.scribbles.widget;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import org.thoughtcrime.securesms.R;
public class VerticalSlideColorPicker extends View {
private Paint paint;
private Paint strokePaint;
private Path path;
private Bitmap bitmap;
private Canvas bitmapCanvas;
private int viewWidth;
private int viewHeight;
private int centerX;
private float colorPickerRadius;
private RectF colorPickerBody;
private OnColorChangeListener onColorChangeListener;
private int borderColor;
private float borderWidth;
private int[] colors;
public VerticalSlideColorPicker(Context context) {
super(context);
init();
}
public VerticalSlideColorPicker(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.VerticalSlideColorPicker, 0, 0);
try {
int colorsResourceId = a.getResourceId(R.styleable.VerticalSlideColorPicker_pickerColors, R.array.scribble_colors);
colors = a.getResources().getIntArray(colorsResourceId);
borderColor = a.getColor(R.styleable.VerticalSlideColorPicker_pickerBorderColor, Color.WHITE);
borderWidth = a.getDimension(R.styleable.VerticalSlideColorPicker_pickerBorderWidth, 10f);
} finally {
a.recycle();
}
init();
}
public VerticalSlideColorPicker(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public VerticalSlideColorPicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
setWillNotDraw(false);
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
path = new Path();
strokePaint = new Paint();
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setColor(borderColor);
strokePaint.setAntiAlias(true);
strokePaint.setStrokeWidth(borderWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.addCircle(centerX, borderWidth + colorPickerRadius, colorPickerRadius, Path.Direction.CW);
path.addRect(colorPickerBody, Path.Direction.CW);
path.addCircle(centerX, viewHeight - (borderWidth + colorPickerRadius), colorPickerRadius, Path.Direction.CW);
bitmapCanvas.drawColor(Color.TRANSPARENT);
bitmapCanvas.drawPath(path, strokePaint);
bitmapCanvas.drawPath(path, paint);
canvas.drawBitmap(bitmap, 0, 0, null);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float yPos = Math.min(event.getY(), colorPickerBody.bottom);
yPos = Math.max(colorPickerBody.top, yPos);
int selectedColor = bitmap.getPixel(viewWidth/2, (int) yPos);
if (onColorChangeListener != null) {
onColorChangeListener.onColorChange(selectedColor);
}
return true;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewWidth = w;
viewHeight = h;
centerX = viewWidth / 2;
colorPickerRadius = (viewWidth / 2) - borderWidth;
colorPickerBody = new RectF(centerX - colorPickerRadius, borderWidth + colorPickerRadius, centerX + colorPickerRadius, viewHeight - (borderWidth + colorPickerRadius));
LinearGradient gradient = new LinearGradient(0, colorPickerBody.top, 0, colorPickerBody.bottom, colors, null, Shader.TileMode.CLAMP);
paint.setShader(gradient);
if (bitmap != null) {
bitmap.recycle();
}
bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas(bitmap);
resetToDefault();
}
public void setBorderColor(int borderColor) {
this.borderColor = borderColor;
invalidate();
}
public void setBorderWidth(float borderWidth) {
this.borderWidth = borderWidth;
invalidate();
}
public void setColors(int[] colors) {
this.colors = colors;
invalidate();
}
public void resetToDefault() {
if (onColorChangeListener != null) {
onColorChangeListener.onColorChange(Color.RED);
}
invalidate();
}
public void setOnColorChangeListener(OnColorChangeListener onColorChangeListener) {
this.onColorChangeListener = onColorChangeListener;
}
public interface OnColorChangeListener {
void onColorChange(int selectedColor);
}
}