aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/yuku/ambilwarna/AmbilWarnaDialog.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/yuku/ambilwarna/AmbilWarnaDialog.java')
-rw-r--r--src/main/java/yuku/ambilwarna/AmbilWarnaDialog.java300
1 files changed, 300 insertions, 0 deletions
diff --git a/src/main/java/yuku/ambilwarna/AmbilWarnaDialog.java b/src/main/java/yuku/ambilwarna/AmbilWarnaDialog.java
new file mode 100644
index 00000000..e553ed10
--- /dev/null
+++ b/src/main/java/yuku/ambilwarna/AmbilWarnaDialog.java
@@ -0,0 +1,300 @@
+package yuku.ambilwarna;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.graphics.Color;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+
+import eu.siacs.conversations.R;
+
+public class AmbilWarnaDialog {
+ public interface OnAmbilWarnaListener {
+ void onCancel(AmbilWarnaDialog dialog);
+
+ void onOk(AmbilWarnaDialog dialog, int color);
+ }
+
+ final AlertDialog dialog;
+ private final boolean supportsAlpha;
+ final OnAmbilWarnaListener listener;
+ final View viewHue;
+ final AmbilWarnaSquare viewSatVal;
+ final ImageView viewCursor;
+ final ImageView viewAlphaCursor;
+ final View viewOldColor;
+ final View viewNewColor;
+ final View viewAlphaOverlay;
+ final ImageView viewTarget;
+ final ImageView viewAlphaCheckered;
+ final ViewGroup viewContainer;
+ final float[] currentColorHsv = new float[3];
+ int alpha;
+
+ /**
+ * Create an AmbilWarnaDialog.
+ *
+ * @param context activity context
+ * @param color current color
+ * @param listener an OnAmbilWarnaListener, allowing you to get back error or OK
+ */
+ public AmbilWarnaDialog(final Context context, int color, OnAmbilWarnaListener listener) {
+ this(context, color, false, listener);
+ }
+
+ /**
+ * Create an AmbilWarnaDialog.
+ *
+ * @param context activity context
+ * @param color current color
+ * @param supportsAlpha whether alpha/transparency controls are enabled
+ * @param listener an OnAmbilWarnaListener, allowing you to get back error or OK
+ */
+ public AmbilWarnaDialog(final Context context, int color, boolean supportsAlpha, OnAmbilWarnaListener listener) {
+ this.supportsAlpha = supportsAlpha;
+ this.listener = listener;
+
+ if (!supportsAlpha) { // remove alpha if not supported
+ color = color | 0xff000000;
+ }
+
+ Color.colorToHSV(color, currentColorHsv);
+ alpha = Color.alpha(color);
+
+ final View view = LayoutInflater.from(context).inflate(R.layout.ambilwarna_dialog, null);
+ viewHue = view.findViewById(R.id.ambilwarna_viewHue);
+ viewSatVal = (AmbilWarnaSquare) view.findViewById(R.id.ambilwarna_viewSatBri);
+ viewCursor = (ImageView) view.findViewById(R.id.ambilwarna_cursor);
+ viewOldColor = view.findViewById(R.id.ambilwarna_oldColor);
+ viewNewColor = view.findViewById(R.id.ambilwarna_newColor);
+ viewTarget = (ImageView) view.findViewById(R.id.ambilwarna_target);
+ viewContainer = (ViewGroup) view.findViewById(R.id.ambilwarna_viewContainer);
+ viewAlphaOverlay = view.findViewById(R.id.ambilwarna_overlay);
+ viewAlphaCursor = (ImageView) view.findViewById(R.id.ambilwarna_alphaCursor);
+ viewAlphaCheckered = (ImageView) view.findViewById(R.id.ambilwarna_alphaCheckered);
+
+ { // hide/show alpha
+ viewAlphaOverlay.setVisibility(supportsAlpha? View.VISIBLE: View.GONE);
+ viewAlphaCursor.setVisibility(supportsAlpha? View.VISIBLE: View.GONE);
+ viewAlphaCheckered.setVisibility(supportsAlpha? View.VISIBLE: View.GONE);
+ }
+
+ viewSatVal.setHue(getHue());
+ viewOldColor.setBackgroundColor(color);
+ viewNewColor.setBackgroundColor(color);
+
+ viewHue.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_MOVE
+ || event.getAction() == MotionEvent.ACTION_DOWN
+ || event.getAction() == MotionEvent.ACTION_UP) {
+
+ float y = event.getY();
+ if (y < 0.f) y = 0.f;
+ if (y > viewHue.getMeasuredHeight()) {
+ y = viewHue.getMeasuredHeight() - 0.001f; // to avoid jumping the cursor from bottom to top.
+ }
+ float hue = 360.f - 360.f / viewHue.getMeasuredHeight() * y;
+ if (hue == 360.f) hue = 0.f;
+ setHue(hue);
+
+ // update view
+ viewSatVal.setHue(getHue());
+ moveCursor();
+ viewNewColor.setBackgroundColor(getColor());
+ updateAlphaView();
+ return true;
+ }
+ return false;
+ }
+ });
+
+ if (supportsAlpha) viewAlphaCheckered.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if ((event.getAction() == MotionEvent.ACTION_MOVE)
+ || (event.getAction() == MotionEvent.ACTION_DOWN)
+ || (event.getAction() == MotionEvent.ACTION_UP)) {
+
+ float y = event.getY();
+ if (y < 0.f) {
+ y = 0.f;
+ }
+ if (y > viewAlphaCheckered.getMeasuredHeight()) {
+ y = viewAlphaCheckered.getMeasuredHeight() - 0.001f; // to avoid jumping the cursor from bottom to top.
+ }
+ final int a = Math.round(255.f - ((255.f / viewAlphaCheckered.getMeasuredHeight()) * y));
+ AmbilWarnaDialog.this.setAlpha(a);
+
+ // update view
+ moveAlphaCursor();
+ int col = AmbilWarnaDialog.this.getColor();
+ int c = a << 24 | col & 0x00ffffff;
+ viewNewColor.setBackgroundColor(c);
+ return true;
+ }
+ return false;
+ }
+ });
+ viewSatVal.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_MOVE
+ || event.getAction() == MotionEvent.ACTION_DOWN
+ || event.getAction() == MotionEvent.ACTION_UP) {
+
+ float x = event.getX(); // touch event are in dp units.
+ float y = event.getY();
+
+ if (x < 0.f) x = 0.f;
+ if (x > viewSatVal.getMeasuredWidth()) x = viewSatVal.getMeasuredWidth();
+ if (y < 0.f) y = 0.f;
+ if (y > viewSatVal.getMeasuredHeight()) y = viewSatVal.getMeasuredHeight();
+
+ setSat(1.f / viewSatVal.getMeasuredWidth() * x);
+ setVal(1.f - (1.f / viewSatVal.getMeasuredHeight() * y));
+
+ // update view
+ moveTarget();
+ viewNewColor.setBackgroundColor(getColor());
+
+ return true;
+ }
+ return false;
+ }
+ });
+
+ dialog = new AlertDialog.Builder(context)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (AmbilWarnaDialog.this.listener != null) {
+ AmbilWarnaDialog.this.listener.onOk(AmbilWarnaDialog.this, getColor());
+ }
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (AmbilWarnaDialog.this.listener != null) {
+ AmbilWarnaDialog.this.listener.onCancel(AmbilWarnaDialog.this);
+ }
+ }
+ })
+ .setOnCancelListener(new OnCancelListener() {
+ // if back button is used, call back our listener.
+ @Override
+ public void onCancel(DialogInterface paramDialogInterface) {
+ if (AmbilWarnaDialog.this.listener != null) {
+ AmbilWarnaDialog.this.listener.onCancel(AmbilWarnaDialog.this);
+ }
+
+ }
+ })
+ .create();
+ // kill all padding from the dialog window
+ dialog.setView(view, 0, 0, 0, 0);
+
+ // move cursor & target on first draw
+ ViewTreeObserver vto = view.getViewTreeObserver();
+ vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ moveCursor();
+ if (AmbilWarnaDialog.this.supportsAlpha) moveAlphaCursor();
+ moveTarget();
+ if (AmbilWarnaDialog.this.supportsAlpha) updateAlphaView();
+ view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
+ }
+ });
+ }
+
+ protected void moveCursor() {
+ float y = viewHue.getMeasuredHeight() - (getHue() * viewHue.getMeasuredHeight() / 360.f);
+ if (y == viewHue.getMeasuredHeight()) y = 0.f;
+ RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewCursor.getLayoutParams();
+ layoutParams.leftMargin = (int) (viewHue.getLeft() - Math.floor(viewCursor.getMeasuredWidth() / 2) - viewContainer.getPaddingLeft());
+ layoutParams.topMargin = (int) (viewHue.getTop() + y - Math.floor(viewCursor.getMeasuredHeight() / 2) - viewContainer.getPaddingTop());
+ viewCursor.setLayoutParams(layoutParams);
+ }
+
+ protected void moveTarget() {
+ float x = getSat() * viewSatVal.getMeasuredWidth();
+ float y = (1.f - getVal()) * viewSatVal.getMeasuredHeight();
+ RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewTarget.getLayoutParams();
+ layoutParams.leftMargin = (int) (viewSatVal.getLeft() + x - Math.floor(viewTarget.getMeasuredWidth() / 2) - viewContainer.getPaddingLeft());
+ layoutParams.topMargin = (int) (viewSatVal.getTop() + y - Math.floor(viewTarget.getMeasuredHeight() / 2) - viewContainer.getPaddingTop());
+ viewTarget.setLayoutParams(layoutParams);
+ }
+
+ protected void moveAlphaCursor() {
+ final int measuredHeight = this.viewAlphaCheckered.getMeasuredHeight();
+ float y = measuredHeight - ((this.getAlpha() * measuredHeight) / 255.f);
+ final RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) this.viewAlphaCursor.getLayoutParams();
+ layoutParams.leftMargin = (int) (this.viewAlphaCheckered.getLeft() - Math.floor(this.viewAlphaCursor.getMeasuredWidth() / 2) - this.viewContainer.getPaddingLeft());
+ layoutParams.topMargin = (int) ((this.viewAlphaCheckered.getTop() + y) - Math.floor(this.viewAlphaCursor.getMeasuredHeight() / 2) - this.viewContainer.getPaddingTop());
+
+ this.viewAlphaCursor.setLayoutParams(layoutParams);
+ }
+
+ private int getColor() {
+ final int argb = Color.HSVToColor(currentColorHsv);
+ return alpha << 24 | (argb & 0x00ffffff);
+ }
+
+ private float getHue() {
+ return currentColorHsv[0];
+ }
+
+ private float getAlpha() {
+ return this.alpha;
+ }
+
+ private float getSat() {
+ return currentColorHsv[1];
+ }
+
+ private float getVal() {
+ return currentColorHsv[2];
+ }
+
+ private void setHue(float hue) {
+ currentColorHsv[0] = hue;
+ }
+
+ private void setSat(float sat) {
+ currentColorHsv[1] = sat;
+ }
+
+ private void setAlpha(int alpha) {
+ this.alpha = alpha;
+ }
+
+ private void setVal(float val) {
+ currentColorHsv[2] = val;
+ }
+
+ public void show() {
+ dialog.show();
+ }
+
+ public AlertDialog getDialog() {
+ return dialog;
+ }
+
+ private void updateAlphaView() {
+ final GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[] {
+ Color.HSVToColor(currentColorHsv), 0x0
+ });
+ viewAlphaOverlay.setBackgroundDrawable(gd);
+ }
+} \ No newline at end of file