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}