com.github.ligangty.common.highconvert.Color.java Source code

Java tutorial

Introduction

Here is the source code for com.github.ligangty.common.highconvert.Color.java

Source

/*
 * Copyright 2011 Moxie Group
 *
 * 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 com.github.ligangty.common.highconvert;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;

/**
 * Represents a color as either a solid RGB color, an RBG color with an alpha channel,
 * or a gradient of colors.  Many of the configurable chart objects support setting various
 * color options (backgrounds, borders, etc).  They all support a simply mechanism for
 * setting the color to a standard RGB hex value (such as {@link Chart#setBackgroundColor(String)}.
 * However, if they also support alpha channels or gradients an overloaded method will be
 * provided that takes a Color instance instead (e.g. {@link Chart#setBackgroundColor(Color)}.
 * <p/>
 * Example which sets the background color to a 10% opacity red color:
 * <pre><code>
 * chart.setBackgroundColor(new Color(255, 0, 0, .1));
 * </code></pre>
 * <p/>
 * Example which sets the background color to a linear gradient from white to
 * a 50% opaque blue:
 * <pre><code>
 * chart.setBackgroundColor(new Color()
 *   .setLinearGradient(0.0, 0.0, 1.0, 1.0)
 *   .addColorStop(0, "#FFFFFF")
 *   .addColorStop(0, 200, 200, 255, 0.5)
 * );
 * </code></pre>
 *
 * @author squinn@moxiegroup.com (Shawn Quinn)
 * @since 1.0.0
 */
public class Color extends Configurable<Color> {

    /**
     * An empty constructor that can be used when creating a color as a gradient.  See the
     * {@link #setLinearGradient(double, double, double, double)} and {@link #addColorStop(double, String)}
     * methods (and their overloaded variants.)
     */
    public Color() {
    }

    /**
     * Create a color instance specifying the color in standard RGB hex notation (include the "#")
     *
     * @param rgbHexColor The RGB hex of the color (include the "#").
     */
    public Color(String rgbHexColor) {
        value = new JSONString(rgbHexColor);
    }

    /**
     * Create a color instance specifying the three components of the RGB color separately (will
     * result in a color that looks like "rgb(200, 255, 10)".
     *
     * @param r The red component of the color in the RGB color space (0 to 255)
     * @param g The green component of the color in the RGB color space (0 to 255)
     * @param b The blue component of the color in the RGB color space (0 to 255)
     */
    public Color(int r, int g, int b) {
        value = new JSONString(createRGB(r, g, b));

    }

    /**
     * Create a color instance specifying the three components of the RGB color separately as we
     * as the alpha channel (will result in a color that looks like "rgb(200, 255, 10, 0.5)".
     *
     * @param r The red component of the color in the RGB color space (0 to 255)
     * @param g The green component of the color in the RGB color space (0 to 255)
     * @param b The blue component of the color in the RGB color space (0 to 255)
     * @param a The alpha channel of the color (0.0 to 1.0)
     */
    public Color(int r, int g, int b, double a) {
        value = new JSONString(createRGBA(r, g, b, a));
    }

    private JSONValue value;

    /**
     * Sets up this color as a linear gradient from one location in space to another.
     * Coordinates can either be provided as whole numbers, in which case they are
     * treated as pixels.  Or, they can be provided as number with a "%" character on the
     * end, in which case they are treated in percentages. E.g.
     * <p/>
     * <pre><code>
     *   color.setLinearGradient("0", "0", "500", "500");
     * </code></pre>
     * Or:
     * <pre><code>
     *   color.setLinearGradient("20%", "20%", "80%", "80%");
     * </code></pre>
     * Note that you can also use the {@link #setLinearGradient(int, int, int, int)}
     * version if you know you're only going to be operating in pixels, or the
     * {@link #setLinearGradient(double, double, double, double)} if you're only operating
     * in percentages.
     *
     * @param x0 The x-coordinate of the start point of the gradient.
     * @param y0 The y-coordinate of the start point of the gradient.
     * @param x1 The x-coordinate of the end point of the gradient.
     * @param y1 The y-coordinate of the end point of the gradient.
     * @return A reference to this {@link Color} instance for convenient method chaining.
     */
    public Color setLinearGradient(String x0, String y0, String x1, String y1) {
        value = null;
        JSONArray coordinates = new JSONArray();
        coordinates.set(0, new JSONString(x0));
        coordinates.set(1, new JSONString(y0));
        coordinates.set(2, new JSONString(x1));
        coordinates.set(3, new JSONString(y1));
        return this.setOption("linearGradient", coordinates);
    }

    /**
     * Sets up this color as a linear gradient from one location in space to another, specifying
     * the coordinates in pixels.
     * <p/>
     * Note that you can also use the {@link #setLinearGradient(double, double, double, double)}
     * version if you know you instead want to operate in percentages, or the
     * {@link #setLinearGradient(String, String, String, String)} version if you need to
     * operate in both percentages and pixels concurrently.
     *
     * @param x0 The x-coordinate of the start point of the gradient (in pixels).
     * @param y0 The y-coordinate of the start point of the gradient (in pixels).
     * @param x1 The x-coordinate of the end point of the gradient (in pixels).
     * @param y1 The y-coordinate of the end point of the gradient (in pixels).
     * @return A reference to this {@link Color} instance for convenient method chaining.
     */
    public Color setLinearGradient(int x0, int y0, int x1, int y1) {
        value = null;
        JSONArray coordinates = new JSONArray();
        coordinates.set(0, new JSONNumber(x0));
        coordinates.set(1, new JSONNumber(y0));
        coordinates.set(2, new JSONNumber(x1));
        coordinates.set(3, new JSONNumber(y1));
        return this.setOption("linearGradient", coordinates);
    }

    /**
     * Sets up this color as a linear gradient from one location in space to another, specifying
     * the coordinates in percentages of the space the gradient will fill.  Note that the percentage
     * is specified by providing a floating point number in the range of 0.0 to 1.0, where 0.0 is
     * equivalent to "0%" and 1.0 is equivalent to "100%".
     * <p/>
     * Note that you can also use the {@link #setLinearGradient(int, int, int, int)}
     * version if you know you instead want to operate in pixels, or the
     * {@link #setLinearGradient(String, String, String, String)} version if you need to
     * operate in both percentages and pixels concurrently.
     *
     * @param x0 The x-percentage of the start point of the gradient (0.0 to 1.0)
     * @param y0 The y-percentage of the start point of the gradient (0.0 to 1.0)
     * @param x1 The x-percentage of the end point of the gradient (0.0 to 1.0)
     * @param y1 The y-percentage of the end point of the gradient (0.0 to 1.0)
     * @return A reference to this {@link Color} instance for convenient method chaining.
     */
    public Color setLinearGradient(double x0, double y0, double x1, double y1) {
        value = null;
        JSONArray coordinates = new JSONArray();
        coordinates.set(0, new JSONString(((Double) (x0 * 100)).intValue() + "%"));
        coordinates.set(1, new JSONString(((Double) (y0 * 100)).intValue() + "%"));
        coordinates.set(2, new JSONString(((Double) (x1 * 100)).intValue() + "%"));
        coordinates.set(3, new JSONString(((Double) (y1 * 100)).intValue() + "%"));
        return this.setOption("linearGradient", coordinates);
    }

    private JSONArray colorStops = new JSONArray();

    /**
     * Adds the specified color at some position within the gradient (to be used in
     * conjunction with the {@link #setLinearGradient(double, double, double, double)} method
     * or another one of its overloaded variants.)
     * <p/>
     * Example which sets the background color to a linear gradient from white to blue:
     * <pre><code>
     * chart.setBackgroundColor(new Color()
     *   .setLinearGradient(0.0, 0.0, 1.0, 1.0)
     *   .addColorStop(0.0, "#FFFFFF")
     *   .addColorStop(0.0, "#0000FF")
     * );
     * </code></pre>
     * Note that this method is intended to be used when you simply want to set the gradient
     * stop color to a standard RGB hex value.  If you need more control use the
     * {@link #addColorStop(double, int, int, int)} or {@link #addColorStop(double, int, int, int, double)}
     * method instead.
     *
     * @param offset      A floating point value between 0.0 and 1.0 that represents the position
     *                    between the start and end points in a gradient.
     * @param rgbHexColor The RGB hex color that the gradient should display at the given offset (include the "#").
     * @return A reference to this {@link Color} instance for convenient method chaining.
     */
    public Color addColorStop(double offset, String rgbHexColor) {
        return this.internalAddColorStop(offset, rgbHexColor);
    }

    /**
     * Adds the specified color at some position within the gradient (to be used in
     * conjunction with the {@link #setLinearGradient(double, double, double, double)} method
     * or another one of its overloaded variants.)
     * <p/>
     * Example which sets the background color to a linear gradient from white to blue:
     * <pre><code>
     * chart.setBackgroundColor(new Color()
     *   .setLinearGradient(0.0, 0.0, 1.0, 1.0)
     *   .addColorStop(0.0, 255, 255, 255)
     *   .addColorStop(0.0, 0, 0, 255)
     * );
     * </code></pre>
     * Note that this method is intended to be used when you simply want to set the gradient
     * stop color to a standard RGB hex value.  If you need more control use the
     * {@link #addColorStop(double, int, int, int, double)} method instead.
     *
     * @param offset A floating point value between 0.0 and 1.0 that represents the position
     *               between the start and end points in a gradient.
     * @param r      The red component of the color in the RGB color space (0 to 255)
     * @param g      The green component of the color in the RGB color space (0 to 255)
     * @param b      The blue component of the color in the RGB color space (0 to 255)
     * @return A reference to this {@link Color} instance for convenient method chaining.
     */
    public Color addColorStop(double offset, int r, int g, int b) {
        return this.internalAddColorStop(offset, createRGB(r, g, b));
    }

    /**
     * Adds the specified color at some position within the gradient allowing for the color
     * to be specified with an alpha channel (to be used in conjunction with the
     * {@link #setLinearGradient(double, double, double, double)} method or another one of its overloaded variants.)
     * <p/>
     * Example which sets the background color to a linear gradient from solid white to
     * a 50% opaque blue:
     * <pre><code>
     * chart.setBackgroundColor(new Color()
     *   .setLinearGradient(0.0, 0.0, 1.0, 1.0)
     *   .addColorStop(0.0, 255, 255, 255)
     *   .addColorStop(0.0, 0, 0, 255, 0.5)
     * );
     * </code></pre>
     *
     * @param offset A floating point value between 0.0 and 1.0 that represents the position
     *               between the start and end points in a gradient.
     * @param r      The red component of the color in the RGB color space (0 to 255)
     * @param g      The green component of the color in the RGB color space (0 to 255)
     * @param b      The blue component of the color in the RGB color space (0 to 255)
     * @param a      The alpha channel of the color (0.0 to 1.0)
     * @return A reference to this {@link Color} instance for convenient method chaining.
     */
    public Color addColorStop(double offset, int r, int g, int b, double a) {
        return this.internalAddColorStop(offset, createRGBA(r, g, b, a));
    }

    /**
     * This method will return the value of the object as a single value if it is
     * represented as just a solid color or as a JSONObject if it represents a gradient.
     * Note that this method is primarily intended for internal use.
     *
     * @return The value of this object as a single value (if appropriate), or a JSONObject
     *         if this color represents a gradient.
     */
    public JSONValue getOptionValue() {
        return value != null ? value : this.getOptions();
    }

    // Internal helper methods
    private Color internalAddColorStop(double offset, String color) {
        value = null;
        JSONArray colorStop = new JSONArray();
        colorStop.set(0, new JSONNumber(offset));
        colorStop.set(1, new JSONString(color));
        colorStops.set(colorStops.size(), colorStop);
        return this.setOption("stops", colorStops);
    }

    private String createRGB(int r, int g, int b) {
        return new StringBuilder().append("rgb(").append(r).append(",").append(g).append(",").append(b).append(")")
                .toString();
    }

    private String createRGBA(int r, int g, int b, double a) {
        return new StringBuilder().append("rgba(").append(r).append(",").append(g).append(",").append(b).append(",")
                .append(a).append(")").toString();
    }

}