001package squidpony.squidgrid.gui.gdx;
002
003import com.badlogic.gdx.graphics.Color;
004import com.badlogic.gdx.scenes.scene2d.ui.Label;
005
006import java.util.ArrayList;
007import java.util.Collection;
008import java.util.Collections;
009import java.util.List;
010
011/**
012 * A Label that changes its color automatically, taking its current color from a list such as a gradient. Useful for
013 * implementing a "blink" effect where a creature alternates being visible and invisible, for a magical object that has
014 * all the colors of the rainbow, or for all sorts of similar uses. The color pattern loops, by default one loop per two
015 * seconds (but this can be changed), so longer lists of colors will display each color for a shorter time.
016 * Created by Tommy Ettinger on 3/23/2016.
017 */
018public class ColorChangeLabel extends Label {
019
020    private List<Color> colors;
021    private float progress = 0f;
022    private float loopTime = 2f;
023
024    /**
025     * Constructs a ColorChangeLabel. Used internally by TextCellFactory, but library users are unlikely to need this.
026     * @param text the text to display in this ColorChangeLabel
027     * @param style the LabelStyle to use for this; typically TextCellFactory handles this
028     * @param colors a Collection (usually a List) of Color, such as one returned by SquidColorCenter's gradient method
029     */
030    public ColorChangeLabel(CharSequence text, LabelStyle style, Collection<Color> colors) {
031        super(text, style);
032        if(colors == null || colors.isEmpty())
033            this.colors = DefaultResources.getSCC().rainbow(12);
034        else
035            this.colors = new ArrayList<>(colors);
036    }
037
038    /**
039     * Constructs a ColorChangeLabel. Used internally by TextCellFactory, but library users are unlikely to need this.
040     * @param text the text to display in this ColorChangeLabel
041     * @param style the LabelStyle to use for this; typically TextCellFactory handles this
042     * @param colors an array or vararg of Color
043     */
044    public ColorChangeLabel(CharSequence text, LabelStyle style, Color... colors) {
045        super(text, style);
046        if (colors == null || colors.length == 0)
047            this.colors = DefaultResources.getSCC().rainbow(12);
048        else {
049            this.colors = new ArrayList<>(colors.length);
050            Collections.addAll(this.colors, colors);
051        }
052    }
053
054    /**
055     * Constructs a ColorChangeLabel. Used internally by TextCellFactory, but library users are unlikely to need this.
056     * @param text the text to display in this ColorChangeLabel
057     * @param style the LabelStyle to use for this; typically TextCellFactory handles this
058     * @param loopTime the amount of time, in seconds, it takes to loop through all the colors in the list
059     * @param colors a Collection (usually a List) of Color, such as one returned by SquidColorCenter's gradient method
060     */
061    public ColorChangeLabel(CharSequence text, LabelStyle style, float loopTime, Collection<Color> colors) {
062        super(text, style);
063        if(colors == null || colors.isEmpty())
064            this.colors = DefaultResources.getSCC().rainbow(12);
065        else
066            this.colors = new ArrayList<>(colors);
067        this.loopTime = loopTime;
068    }
069
070    /**
071     * Constructs a ColorChangeLabel. Used internally by TextCellFactory, but library users are unlikely to need this.
072     * @param text the text to display in this ColorChangeLabel
073     * @param style the LabelStyle to use for this; typically TextCellFactory handles this
074     * @param loopTime the amount of time, in seconds, it takes to loop through all the colors in the list
075     * @param colors an array or vararg of Color
076     */
077    public ColorChangeLabel(CharSequence text, LabelStyle style, float loopTime, Color... colors) {
078        super(text, style);
079        if (colors == null || colors.length == 0)
080            this.colors = DefaultResources.getSCC().rainbow(12);
081        else {
082            this.colors = new ArrayList<>(colors.length);
083            Collections.addAll(this.colors, colors);
084        }
085        this.loopTime = loopTime;
086    }
087
088    /**
089     * Returns the color the actor will be tinted when drawn. Takes the Color from the List of Color this was constructed
090     * with or assigned with setColors, not the normal Actor color assigned with setColor.
091     * @return the Color this will be drawn with
092     */
093    @Override
094    public Color getColor() {
095        return colors.get((int)(progress * colors.size() / loopTime));
096    }
097
098    /**
099     * Sets the list of colors this uses to choose what color it draws with.
100     * @param colors a Collection (usually a List) of Color, such as one returned by SquidColorCenter's gradient method
101     */
102    public void setColors(Collection<Color> colors)
103    {
104        if(colors == null || colors.isEmpty())
105            this.colors = DefaultResources.getSCC().rainbow(12);
106        else
107            this.colors = new ArrayList<>(colors);
108    }
109
110    /**
111     * Sets the list of colors this uses to choose what color it draws with.
112     * @param colors an array or vararg of Color
113     */
114    public void setColors(Color... colors)
115    {
116        if (colors == null || colors.length == 0)
117            this.colors = DefaultResources.getSCC().rainbow(12);
118        else {
119            this.colors = new ArrayList<>(colors.length);
120            Collections.addAll(this.colors, colors);
121        }
122    }
123    /**
124     * Updates the actor based on time. Typically this is called each frame by
125     * {@link com.badlogic.gdx.scenes.scene2d.Stage#act(float)}.
126     * <p>
127     * The default implementation calls
128     * {@link com.badlogic.gdx.scenes.scene2d.Action#act(float)} on each action and removes actions that are complete.
129     *
130     * @param delta Time in seconds since the last frame.
131     */
132    @Override
133    public void act(float delta) {
134        super.act(delta);
135        progress = (progress + delta) % (loopTime - 0.001f);
136    }
137
138    /**
139     * Changes the amount of time this takes to loop through all colors, and also resets the current loop to its start.
140     * @param loopTime the amount of time, in seconds, it takes to loop through all the colors in the list
141     */
142    public void resetLoopTime(float loopTime)
143    {
144        this.loopTime = loopTime;
145        progress = 0f;
146    }
147}