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