001package squidpony.squidgrid.gui.gdx; 002 003import java.util.ArrayList; 004import java.util.List; 005 006import com.badlogic.gdx.Gdx; 007import com.badlogic.gdx.graphics.Color; 008 009import squidpony.SquidTags; 010import squidpony.panel.IColoredString; 011import squidpony.panel.ICombinedPanel; 012import squidpony.panel.ISquidPanel; 013import squidpony.squidgrid.gui.gdx.UIUtil.CornerStyle; 014 015/** 016 * A panel to display some text. It can either compute its size on its own or 017 * use preallocated panels to determine its size. 018 * 019 * <p> 020 * This class is somehow doing a simpler business as {@link ButtonsPanel} but 021 * they did not get merged, because {@link ButtonsPanel} would then become a 022 * monster. 023 * </p> 024 * 025 * <p> 026 * This class is deprecated. You should likely use {@link TextPanel} instead, 027 * because it directly relies on libgdx for rendering and hence has a more 028 * "serif" display, which is appropriate for text. Moreover {@link TextPanel} 029 * uses more recent stuff (such as {@link GDXMarkup}), supports scrolling, and 030 * is more memory efficient (no backing {@link SquidPanel} -> save on allocated 031 * arrays). 032 * </p> 033 * 034 * @author smelC 035 * @param <T> 036 * 037 * @deprecated Use {@link TextPanel} instead 038 * @see ButtonsPanel 039 */ 040@Deprecated 041public abstract class SquidTextPanel<T extends Color> extends GroupCombinedPanel<T> { 042 043 protected List<IColoredString<T>> text; 044 045 /** 046 * The maximum width that this panel can take (in number of cells). This is 047 * a pretty much random value. Overwrite it with something computed from 048 * your game (for example, use your dungeon's width if you display it 049 * entirely, and want this panel fullscreen). 050 */ 051 public int maxWidth = 8; 052 053 /** 054 * The maximum height that this panel can take (in number of cells). This is 055 * a pretty much random value. Overwrite it with something computed from 056 * your game (for example, use your dungeon's height if you display it 057 * entirely, and want this panel fullscreen). 058 */ 059 public int maxHeight = 8; 060 061 /** The background color */ 062 public T backgroundColor = null; 063 064 /** The border's color */ 065 public T borderColor = null; 066 067 /** The style of the border */ 068 public CornerStyle borderStyle = CornerStyle.ROUNDED; 069 070 public int borderSize = 0; 071 public float zoomMultiplierX = 1, zoomMultiplierY = 1; 072 073 /** Whether to use {@link IColoredString#justify(int)} on text */ 074 public boolean justifyText = true; 075 076 protected int h = -1; 077 078 /** 079 * A panel with preallocated backers. 080 * 081 * @param bg 082 * @param fg 083 */ 084 public SquidTextPanel(ISquidPanel<T> bg, ISquidPanel<T> fg) { 085 super(bg, fg); 086 } 087 088 /** 089 * A panel with backers created lazily. 090 */ 091 public SquidTextPanel() { 092 super(); 093 } 094 095 /** 096 * Sets the text and prepares for display. This method should be called 097 * after the constructor, and before {@link #put(boolean)} or 098 * {@link #putBorder()}. 099 * 100 * @param text 101 */ 102 public void init(List<IColoredString<T>> text) { 103 this.text = new ArrayList<>(text); 104 105 prepare(); 106 } 107 108 /** 109 * @param putBorders 110 * Puts this panel on screen, but do not draw it yet (we'd need a 111 * {@code Stage} for that). 112 */ 113 public void put(boolean putBorders) { 114 if (h == -1) 115 throw new IllegalStateException( 116 getClass().getSimpleName() + "::prepare() should be called before put(boolean)"); 117 118 if (backgroundColor != null) 119 fill(ICombinedPanel.What.BG, backgroundColor); 120 121 if (putBorders) 122 putBorder(); 123 124 for (int y = 0; y < h; y++) { 125 /* Put text */ 126 putFG(0, y, text.get(y)); 127 } 128 } 129 130 public void putBorder() { 131 if (bg == null) 132 return; 133 134 if (borderColor != null && 0 < borderSize) { 135 final float x = getX(); 136 final float y = getY(); 137 final int w = bg.gridWidth(); 138 final int h = bg.gridHeight(); 139 UIUtil.drawMarginsAround(null, x, y, w * bg.cellWidth(), h * bg.cellHeight(), borderSize, 140 borderColor, borderStyle, zoomMultiplierX, zoomMultiplierY); 141 } 142 } 143 144 /** 145 * This method can be left unimplemented if you give the panels at 146 * construction time. 147 * 148 * @param width 149 * The width that the panel must have. 150 * @param height 151 * The height that the panel must have. 152 * @return A freshly allocated {@link ISquidPanel}. 153 */ 154 protected abstract ISquidPanel<T> buildPanel(int width, int height); 155 156 protected void prepare() { 157 if (text == null) 158 throw new NullPointerException( 159 "Text must be set before calling " + getClass().getSimpleName() + "::prepare()"); 160 161 final int w; 162 if (bg == null) { 163 /* 164 * We need to allocate the panels, hence we need to compute their 165 * sizes 166 */ 167 final int w_ = computeRequiredWidth(); 168 if (maxWidth < w_) { 169 /* Wrapping needed */ 170 final List<IColoredString<T>> wrapped = new ArrayList<>(text.size() * 2); 171 for (IColoredString<T> t : text) { 172 final List<IColoredString<T>> wrap = t.wrap(maxWidth); 173 for (IColoredString<T> ics : wrap) 174 wrapped.add(justifyText ? ics.justify(maxWidth) : ics); 175 } 176 this.text = wrapped; 177 w = maxWidth; 178 } else 179 w = w_; 180 final int tsz = text.size(); 181 h = Math.min(maxHeight, tsz); 182 183 Gdx.app.log(SquidTags.LAYOUT, 184 "Chosen size of " + getClass().getSimpleName() + ": " + w + "x" + h); 185 186 setPanels(buildPanel(w, h), buildPanel(w, h)); 187 } else { 188 w = bg.gridWidth(); 189 h = bg.gridHeight(); 190 if (justifyText) { 191 final List<IColoredString<T>> adjusted = new ArrayList<>(text.size()); 192 for (IColoredString<T> t : text) 193 adjusted.add(t.justify(w)); 194 text = adjusted; 195 } 196 } 197 } 198 199 private int computeRequiredWidth() { 200 int result = 0; 201 for (IColoredString<?> ics : text) 202 result = Math.max(result, ics.length()); 203 return result; 204 } 205 206}