universum.studios.android.dialog.ColorPickerDialog.java Source code

Java tutorial

Introduction

Here is the source code for universum.studios.android.dialog.ColorPickerDialog.java

Source

/*
 * =================================================================================================
 *                             Copyright (C) 2017 Universum Studios
 * =================================================================================================
 *         Licensed under the Apache License, Version 2.0 or later (further "License" only).
 * -------------------------------------------------------------------------------------------------
 * You may use this file only in compliance with the License. More details and copy of this License
 * you may obtain at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * You can redistribute, modify or publish any part of the code written within this file but as it
 * is described in the License, the software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES or CONDITIONS OF ANY KIND.
 *
 * See the License for the specific language governing permissions and limitations under the License.
 * =================================================================================================
 */
package universum.studios.android.dialog;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcel;
import android.support.annotation.AttrRes;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StyleRes;
import android.support.v4.widget.Space;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import universum.studios.android.dialog.view.ColorPickerDialogView;

/**
 * A {@link SimpleDialog} implementation that can be used to allow to a user to pick its desired color
 * via specifying values for <b>RGBA</b> color components using slider or text field. This dialog uses
 * default {@link ColorPickerDialogView} implementation as its content view which consists of
 * {@link universum.studios.android.dialog.widget.DialogColorView DialogColorView} used to present
 * picked color and 4 sliders with text input fields that can be used to input the desired value for
 * the mentioned color components.
 * <p>
 * The picked color may be obtained via {@link #getColor()}.
 * <p>
 * See {@link ColorOptions} for options that can be supplied to the ColorPickerDialog from the desired
 * context via {@link #newInstance(ColorOptions)} or via {@link #setOptions(DialogOptions)}.
 * <p>
 * <b>Note</b>, that current state of this dialog will be always preserved after orientation change,
 * as all dialog views from this library save theirs current state for that matter.
 *
 * <h3>Xml options</h3>
 * This dialog parses its global options from the current dialog theme referenced via
 * {@link R.attr#dialogColorOptions dialogColorOptions} attribute.
 *
 * @author Martin Albedinsky
 */
public class ColorPickerDialog extends SimpleDialog {

    /**
     * Constants ===================================================================================
     */

    /**
     * Log TAG.
     */
    // private static final String TAG = "ColorPickerDialog";

    /*
     * Interface ===================================================================================
     */

    /**
     * Static members ==============================================================================
     */

    /**
     * Members =====================================================================================
     */

    /**
     * ColorPicker dialog view implementation.
     */
    private ColorPickerDialogView mColorView;

    /**
     * Constructors ================================================================================
     */

    /**
     * Creates a new instance of ColorPickerDialog with a {@link universum.studios.android.dialog.widget.DialogColorView DialogColorView}
     * and 4 layouts with sliders and text fields allowing to pick a value of each of the color components
     * (RGBA) respectively.
     */
    public ColorPickerDialog() {
        super(R.attr.dialogColorOptions);
    }

    /**
     * Methods =====================================================================================
     */

    /**
     * Creates a new instance of ColorPickerDialog with the specified options.
     *
     * @param options Specific options for this type of dialog.
     * @return New ColorPickerDialog instance.
     */
    @NonNull
    public static ColorPickerDialog newInstance(@NonNull ColorOptions options) {
        final ColorPickerDialog dialog = new ColorPickerDialog();
        dialog.setOptions(options);
        return dialog;
    }

    /**
     */
    @NonNull
    @Override
    protected DialogOptions onCreateDefaultOptions(@NonNull Resources resources) {
        return new ColorOptions(resources);
    }

    /**
     */
    @Override
    protected void onProcessOptionsStyle(@NonNull Context context, @StyleRes int optionsStyle) {
        super.onProcessOptionsStyle(context, optionsStyle);
        if (mOptions instanceof ColorOptions) {
            final TypedArray attributes = context.obtainStyledAttributes(optionsStyle,
                    R.styleable.Dialog_Options_Color);
            final ColorOptions options = (ColorOptions) mOptions;
            for (int i = 0; i < attributes.getIndexCount(); i++) {
                int index = attributes.getIndex(i);
                if (index == R.styleable.Dialog_Options_Color_dialogColor) {
                    if (!options.isSet(ColorOptions.COLOR)) {
                        options.color(attributes.getColor(index, options.color));
                    }
                } else if (index == R.styleable.Dialog_Options_Color_dialogColorCanvas) {
                    if (!options.isSet(ColorOptions.CANVAS_COLOR)) {
                        options.canvasColor(attributes.getColor(index, options.canvasColor));
                    }
                }
            }
            attributes.recycle();
        }
    }

    /**
     */
    @NonNull
    @Override
    protected View onCreateContentView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.dialog_content_color, container, false);
    }

    /**
     */
    @NonNull
    @Override
    protected View onCreateButtonsView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        // Content view already contains buttons view.
        final View view = new Space(mContext);
        view.setVisibility(View.GONE);
        return view;
    }

    /**
     */
    @Override
    void onBindContentView(View contentView, DialogOptions options) {
        if (contentView instanceof ColorPickerDialogView && options instanceof ColorOptions) {
            final ColorOptions colorOptions = (ColorOptions) options;
            final ColorPickerDialogView colorView = (ColorPickerDialogView) contentView;
            if (colorOptions.color != 0) {
                colorView.setColor(colorOptions.color);
            }
            colorView.setCanvasColor(colorOptions.canvasColor);
        }
    }

    /**
     */
    @Override
    protected void onUpdateContentViewPadding() {
        // Do not update content view padding.
    }

    /**
     */
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        final View contentView = getContentView();
        if (contentView instanceof ColorPickerDialogView) {
            this.mColorView = (ColorPickerDialogView) contentView;
        }
    }

    /**
     * Returns the current value of <b>color</b> picked within this picker dialog.
     *
     * @return Picked color either by user or initially specified via options.
     */
    @ColorInt
    public int getColor() {
        return mColorView != null ? mColorView.getColor() : Color.TRANSPARENT;
    }

    /**
     * Inner classes ===============================================================================
     */

    /**
     * A {@link DialogOptions} implementation specific for the {@link ColorPickerDialog}.
     * <p>
     * Below are listed setters which may be used to supply desired data to {@link ColorPickerDialog}
     * through these options:
     * <ul>
     * <li>{@link #color(int)}</li>
     * <li>{@link #canvasColor(int)}</li>
     * </ul>
     *
     * <h3>Xml attributes</h3>
     * See {@link R.styleable#Dialog_Options_Color ColorOptions Attributes},
     * {@link R.styleable#Dialog_Options DialogOptions Attributes}
     *
     * @author Martin Albedinsky
     */
    public static class ColorOptions extends DialogOptions<ColorOptions> {

        /**
         * Creator used to create an instance or array of instances of ColorOptions from {@link Parcel}.
         */
        public static final Creator<ColorOptions> CREATOR = new Creator<ColorOptions>() {

            /**
             */
            @Override
            public ColorOptions createFromParcel(@NonNull Parcel source) {
                return new ColorOptions(source);
            }

            /**
             */
            @Override
            public ColorOptions[] newArray(int size) {
                return new ColorOptions[size];
            }
        };

        /**
         * Flag for <b>color</b> parameter.
         */
        static final int COLOR = 0x00000001;

        /**
         * Flag for <b>canvas color</b> parameter.
         */
        static final int CANVAS_COLOR = 0x00000001 << 1;

        /**
         * Initial color for ColorView.
         */
        int color;

        /**
         * Background color for ColorView.
         */
        int canvasColor = Color.WHITE;

        /**
         * Creates a new instance of ColorOptions.
         */
        public ColorOptions() {
            super();
        }

        /**
         * Creates a new instance of ColorOptions.
         *
         * @param resources Application resources used to obtain values for these options when they
         *                  are requested by theirs resource ids.
         */
        public ColorOptions(@NonNull Resources resources) {
            super(resources);
        }

        /**
         * Called form {@link #CREATOR} to create an instance of ColorOptions form the given parcel
         * <var>source</var>.
         *
         * @param source Parcel with data for the new instance.
         */
        protected ColorOptions(@NonNull Parcel source) {
            super(source);
            this.color = source.readInt();
            this.canvasColor = source.readInt();
        }

        /**
         */
        @Override
        public void writeToParcel(@NonNull Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeInt(color);
            dest.writeInt(canvasColor);
        }

        /**
         */
        @Override
        public ColorOptions merge(@NonNull DialogOptions options) {
            if (!(options instanceof ColorOptions)) {
                return super.merge(options);
            }
            final ColorOptions colorOptions = (ColorOptions) options;
            if (colorOptions.isSet(COLOR)) {
                this.color = colorOptions.color;
                updateIsSet(COLOR);
            }
            if (colorOptions.isSet(CANVAS_COLOR)) {
                this.canvasColor = colorOptions.canvasColor;
                updateIsSet(CANVAS_COLOR);
            }
            return super.merge(options);
        }

        /**
         * Sets the initial color for ColorView of a dialog associated with these options.
         * <p>
         * Default color: <b>{@link Color#TRANSPARENT}</b>
         *
         * @param color The desired initial color.
         * @return These options to allow methods chaining.
         * @see R.attr#dialogColor dialog:dialogColor
         * @see #color()
         */
        public ColorOptions color(@ColorInt int color) {
            updateIsSet(COLOR);
            if (this.color != color) {
                this.color = color;
                notifyChanged();
            }
            return this;
        }

        /**
         * Returns the initial color for ColorView, set to these options.
         *
         * @return The initial color specified via {@link #color(int)} or {@link Color#TRANSPARENT}
         * by default.
         * @see #color(int)
         */
        @ColorInt
        public int color() {
            return color;
        }

        /**
         * Sets the color for canvas (background) of ColorView of a dialog associated with these
         * options.
         * <p>
         * Default color: <b>{@link Color#WHITE}</b>
         *
         * @param color The desired canvas (background) color.
         * @return These options to allow methods chaining.
         * @see R.attr#dialogColorCanvas dialog:dialogColorCanvas
         * @see #canvasColor()
         */
        public ColorOptions canvasColor(@ColorInt int color) {
            updateIsSet(CANVAS_COLOR);
            if (this.canvasColor != color) {
                this.canvasColor = color;
                notifyChanged();
            }
            return this;
        }

        /**
         * Returns the canvas color of ColorView, set to these options.
         *
         * @return The canvas (background) color specified via {@link #canvasColor(int)} or
         * {@link Color#WHITE} by default.
         * @see #canvasColor(int)
         */
        @ColorInt
        public int canvasColor() {
            return canvasColor;
        }

        /**
         */
        @Override
        protected void onParseXmlAttribute(@NonNull XmlResourceParser xmlParser, int index, @AttrRes int attr,
                @NonNull Resources resources, @Nullable Resources.Theme theme) {
            if (attr == R.attr.dialogColor) {
                color(xmlParser.getAttributeIntValue(index, color));
            } else if (attr == R.attr.dialogColorCanvas) {
                canvasColor(xmlParser.getAttributeIntValue(index, canvasColor));
            } else {
                super.onParseXmlAttribute(xmlParser, index, attr, resources, theme);
            }
        }
    }
}