/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.arakhne.afc.ui.android.colorpicker; import org.arakhne.afc.ui.android.R; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.graphics.Color; 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; /** A dialog that permits to pick a color. * This view is a panel on which all the colors are painted * and on which the user may click to pick a color. * <p> * The original source code was copied from * <a href="http://code.google.com/p/android-color-picker/">android-color-picker</a>. * Comments were added, and source code patched for * AFC compliance. * * @author $Author: yukuku$ * @author $Author: sgalland$ * @version $Name$ $Revision$ $Date$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ * @deprecated see JavaFX API */ @Deprecated public class ColorPickerDialog extends AlertDialog { private final OnColorPickerListener listener; private final float[] currentColorHsv = new float[3]; private final View viewHue; private final ColorPickerView viewSatVal; private final ImageView viewCursor; private final View viewOldColor; private final View viewNewColor; private final ImageView viewTarget; private final ViewGroup viewContainer; /** * Create a ColorPickerDialog with black color. * Call this only from {@code OnCreateDialog()} or from a background thread. * * @param context * @param enableDefaultColorButton indicates if the button to select a default color * is displayed or not. * @param listener is a listener on the picking events. */ public ColorPickerDialog(Context context, boolean enableDefaultColorButton, OnColorPickerListener listener) { this(context, 0xff000000, enableDefaultColorButton, listener); } /** * Create a ColorPickerDialog. * Call this only from {@code OnCreateDialog()} or from a background thread. * * @param context * @param color is the RGB color * @param enableDefaultColorButton indicates if the button to select a default color * is displayed or not. * @param listener is a listener on the picking events. */ public ColorPickerDialog(Context context, int color, boolean enableDefaultColorButton, OnColorPickerListener listener) { super(context); this.listener = listener; Color.colorToHSV(color, this.currentColorHsv); final View rootView = LayoutInflater.from(context).inflate(R.layout.colorpicker_dialog, null); this.viewHue = rootView.findViewById(R.id.colorpicker_viewHue); this.viewSatVal = (ColorPickerView) rootView.findViewById(R.id.colorpicker_viewSatBri); this.viewCursor = (ImageView) rootView.findViewById(R.id.colorpicker_cursor); this.viewOldColor = rootView.findViewById(R.id.colorpicker_warnaLama); this.viewNewColor = rootView.findViewById(R.id.colorpicker_warnaBaru); this.viewTarget = (ImageView) rootView.findViewById(R.id.colorpicker_target); this.viewContainer = (ViewGroup) rootView.findViewById(R.id.colorpicker_viewContainer); this.viewSatVal.setHue(getHue()); this.viewOldColor.setBackgroundColor(color); this.viewNewColor.setBackgroundColor(color); this.viewHue.setOnTouchListener(new View.OnTouchListener() { @SuppressWarnings("synthetic-access") @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 > ColorPickerDialog.this.viewHue.getMeasuredHeight()) y = ColorPickerDialog.this.viewHue.getMeasuredHeight() - 0.001f; // to avoid looping from end to start. float hue = 360.f - 360.f / ColorPickerDialog.this.viewHue.getMeasuredHeight() * y; if (hue == 360.f) hue = 0.f; setHue(hue); return true; } return false; } }); this.viewSatVal.setOnTouchListener(new View.OnTouchListener() { @SuppressWarnings("synthetic-access") @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 > ColorPickerDialog.this.viewSatVal.getMeasuredWidth()) x = ColorPickerDialog.this.viewSatVal.getMeasuredWidth(); if (y < 0.f) y = 0.f; if (y > ColorPickerDialog.this.viewSatVal.getMeasuredHeight()) y = ColorPickerDialog.this.viewSatVal.getMeasuredHeight(); setSaturationAndValue( 1.f / ColorPickerDialog.this.viewSatVal.getMeasuredWidth() * x, 1.f - (1.f / ColorPickerDialog.this.viewSatVal.getMeasuredHeight() * y)); return true; } return false; } }); setButton(BUTTON_POSITIVE, context.getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { fireColorPicked(); } }); setButton(BUTTON_NEGATIVE, context.getString(android.R.string.cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { fireColorPickingCanceled(); } }); setOnCancelListener(new OnCancelListener() { @Override public void onCancel(DialogInterface paramDialogInterface) { fireColorPickingCanceled(); } }); if (enableDefaultColorButton) { setButton(BUTTON_NEUTRAL, context.getString(R.string.default_color), new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); fireDefaultColorPicked(); } }); } // kill all padding from the dialog window setView(rootView, 0, 0, 0, 0); // move cursor & target on first draw ViewTreeObserver vto = rootView.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @SuppressWarnings("synthetic-access") @Override public void onGlobalLayout() { moveCursor(); moveTarget(); rootView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } }); } /** Notifies the listeners about the cancelation of the color picking. */ protected void fireColorPickingCanceled() { if (this.listener != null) { this.listener.onColorPickingCanceled(this); } } /** Notifies the listeners about the selection of the color. */ protected void fireColorPicked() { if (this.listener != null) { this.listener.onColorPicked(this, getRGB()); } } /** Notifies the listeners about the selection of the default color. */ protected void fireDefaultColorPicked() { if (this.listener != null) { this.listener.onDefaultColorPicked(this); } } private void moveCursor() { float y = this.viewHue.getMeasuredHeight() - (getHue() * this.viewHue.getMeasuredHeight() / 360.f); if (y == this.viewHue.getMeasuredHeight()) y = 0.f; RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) this.viewCursor.getLayoutParams(); layoutParams.leftMargin = (int) (this.viewHue.getLeft() - this.viewCursor.getMeasuredWidth() / 2 - this.viewContainer.getPaddingLeft()); layoutParams.topMargin = (int) (this.viewHue.getTop() + y - this.viewCursor.getMeasuredHeight() / 2 - this.viewContainer.getPaddingTop()); this.viewCursor.setLayoutParams(layoutParams); } private void moveTarget() { float x = getSaturation() * this.viewSatVal.getMeasuredWidth(); float y = (1.f - getValue()) * this.viewSatVal.getMeasuredHeight(); RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) this.viewTarget.getLayoutParams(); layoutParams.leftMargin = (int) (this.viewSatVal.getLeft() + x - this.viewTarget.getMeasuredWidth() / 2 - this.viewContainer.getPaddingLeft()); layoutParams.topMargin = (int) (this.viewSatVal.getTop() + y - this.viewTarget.getMeasuredHeight() / 2 - this.viewContainer.getPaddingTop()); this.viewTarget.setLayoutParams(layoutParams); } /** Replies the RGB representation of the current selected color. * * @return RGB */ public int getRGB() { return Color.HSVToColor(this.currentColorHsv); } /** Set the RGB representation of the current selected color. * * @param rgb */ public void setRGB(int rgb) { float[] hsv = new float[3]; Color.colorToHSV(rgb, hsv); setHSV(hsv); } /** Replies the HSV representation of the current selected color. * * @return HSV */ public float[] getHSV() { return this.currentColorHsv.clone(); } /** Set the HSV representation of the current selected color. * * @param hsv */ public final void setHSV(float[] hsv) { setHSV(hsv[0], hsv[1], hsv[2]); } /** Set the HSV representation of the current selected color. * * @param hue * @param saturation * @param value */ public void setHSV(float hue, float saturation, float value) { if (hue!=this.currentColorHsv[0] ||saturation!=this.currentColorHsv[1] ||value!=this.currentColorHsv[2]) { this.currentColorHsv[0] = hue; this.currentColorHsv[1] = saturation; this.currentColorHsv[2] = value; this.viewSatVal.setHue(getHue()); moveCursor(); moveTarget(); this.viewNewColor.setBackgroundColor(getRGB()); } } /** Replies the hue of the current color, according * to the HSV representation. * * @return the hue of the color. */ public float getHue() { return this.currentColorHsv[0]; } /** Set the hue of the current color, according * to the HSV representation. * * @param hue the hue of the color. */ public void setHue(float hue) { if (hue!=this.currentColorHsv[0]) { this.currentColorHsv[0] = hue; this.viewSatVal.setHue(getHue()); moveCursor(); this.viewNewColor.setBackgroundColor(getRGB()); } } /** Replies the saturation of the current color, according * to the HSV representation. * * @return the saturation of the color. */ public float getSaturation() { return this.currentColorHsv[1]; } /** Set the saturation of the current color, according * to the HSV representation. * * @param sat is the saturation of the color. */ public void setSaturation(float sat) { if (sat!=this.currentColorHsv[1]) { this.currentColorHsv[1] = sat; moveTarget(); this.viewNewColor.setBackgroundColor(getRGB()); } } /** Replies the value of the current color, according * to the HSV representation. * * @return the value of the color. */ public float getValue() { return this.currentColorHsv[2]; } /** Set the value of the current color, according * to the HSV representation. * * @param val is the value of the color. */ public void setValue(float val) { if (val!=this.currentColorHsv[2]) { this.currentColorHsv[2] = val; moveTarget(); this.viewNewColor.setBackgroundColor(getRGB()); } } /** Set the saturation and the value of the current color, according * to the HSV representation. * * @param sat is the saturation of the color. * @param val is the value of the color. */ protected void setSaturationAndValue(float sat, float val) { if (sat!=this.currentColorHsv[1] || val!=this.currentColorHsv[2]) { this.currentColorHsv[1] = sat; this.currentColorHsv[2] = val; moveTarget(); this.viewNewColor.setBackgroundColor(getRGB()); } } /** Listener on color picking in a color picked * dialog. * * @author $Author: yukuku$ * @author $Author: sgalland$ * @version $Name$ $Revision$ $Date$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ public interface OnColorPickerListener { /** Invoked when the color picking was canceled. * * @param dialog is the canceled dialog. */ public void onColorPickingCanceled(ColorPickerDialog dialog); /** Invoked when the color picking was successfull * with a selected color. * * @param dialog is the dialog from which the color was selected. * @param color is the RGB color. */ public void onColorPicked(ColorPickerDialog dialog, int color); /** Invoked when the color picking was successfull * with the default color. * * @param dialog is the dialog from which the color was selected. */ public void onDefaultColorPicked(ColorPickerDialog dialog); } }