202 lines
6.0 KiB
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);
|
|
}
|
|
} |