/**
*
* Copyright 2014
*
* 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.
*
* @project loon
* @author cping
* @email:javachenpeng@yahoo.com
* @version 0.4.1
*
* 该类效果与LInfo和LMessage近似,但与强调专用场合的前两类不同,此类的应用场合更广阔,默认效果使用上也较前两类自动化。
* API也更简便,并且,此并不强迫背景图的使用,缺省状态系统也提供了默认背景。
*
* Examples1:
*
* LTextArea area = new LTextArea(66, 66, 300, 100);
* area.put("GGGGGGGGGG",LColor.red); area.put("GGGGGGGGGG");
* //addString为在前一行追加数据 area.addString("1",LColor.red);
*/
package loon.component;
import loon.LSystem;
import loon.LTexture;
import loon.LTextures;
import loon.canvas.LColor;
import loon.component.skin.MessageSkin;
import loon.component.skin.SkinManager;
import loon.font.FontSet;
import loon.font.IFont;
import loon.font.LFont;
import loon.opengl.GLEx;
import loon.opengl.LSTRDictionary;
import loon.utils.StringUtils;
/**
* 字符串显示用类,支持多种文字显示特效,个人建议主要用来做信息推送显示
*/
public class LTextArea extends LComponent implements FontSet<LTextArea> {
// 数据向下推入
public static final int TYPE_DOWN = 0;
// 数据向上推入
public static final int TYPE_UP = 1;
private int leftOffset, topOffset;
private int showType;
private String[] message;
private int[] bright;
private int[] brightType;
private boolean[] drawNew;
private int[] drawNewCr;
private int[] drawNewCg;
private int[] drawNewCb;
private int[] drawNewLV;
private int brightMax = 100;
private int brightSpeed = 1;
private int[] cr;
private int[] cg;
private int[] cb;
private int default_cr = 255 - this.brightMax;
private int default_cg = 255 - this.brightMax;
private int default_cb = 255 - this.brightMax;
private String[] getMessage;
private int[] getMessageLength;
private int messageWidthLimit = 200;
private int postLine = 0;
private int max;
private int num;
private int drawY;
private boolean waitFlag;
private String str;
private int posx;
private int posy;
private int numBak;
private boolean over;
private boolean slideMessage;
private int[] slideX;
private boolean center;
private IFont font;
private int countFrame;
private LColor triangleColor = LColor.orange;
private LColor tmpcolor = new LColor(LColor.white);
private String flag = LSystem.FLAG_TAG;
public LTextArea(int x, int y, int w, int h) {
this(-1, x, y, w, h);
}
public LTextArea(int max, int x, int y, int w, int h) {
this(LTextArea.TYPE_DOWN, max, SkinManager.get().getMessageSkin().getFont(), x, y, w, h);
}
public LTextArea(int max, IFont font, int x, int y, int w, int h) {
this(LTextArea.TYPE_DOWN, max, font, x, y, w, h);
}
public LTextArea(int type, int max, IFont font, int x, int y, int w, int h) {
this(type, max, font, x, y, w, h, SkinManager.get().getMessageSkin().getBackgroundTexture());
}
public LTextArea(int x, int y, int w, int h, String bgFile) {
this(LTextArea.TYPE_DOWN, w, SkinManager.get().getMessageSkin().getFont(), x, y, w, h,
LTextures.loadTexture(bgFile));
}
public LTextArea(int x, int y, int w, int h, LTexture bg) {
this(LTextArea.TYPE_DOWN, w, SkinManager.get().getMessageSkin().getFont(), x, y, w, h, bg);
}
public LTextArea(MessageSkin skin, int type, int max, int x, int y, int w,
int h) {
this(type, max, skin.getFont(), x, y, w, h, skin.getBackgroundTexture());
}
public LTextArea(int type, int max, IFont font, int x, int y, int w, int h,
LTexture bg) {
super(x, y, w, h);
this.showType = type;
this.font = font;
this.postLine = (h / font.getHeight());
if (max < 0) {
this.set(LSystem.isDesktop() ? postLine - 1 : postLine + 1);
} else {
this.set(max);
}
this.setWidthLimit(w);
this.setWaitFlag(true);
this.setSlideMessage(true);
this._background = bg;
this._drawBackground = false;
}
public void set(int mMax) {
this.max = (mMax + 1);
this.message = new String[this.max];
this.cr = new int[this.max];
this.cg = new int[this.max];
this.cb = new int[this.max];
this.bright = new int[this.max];
this.brightType = new int[this.max];
this.getMessage = new String[this.max];
this.getMessageLength = new int[this.max];
this.drawNew = new boolean[this.max];
this.drawNewCr = new int[this.max];
this.drawNewCg = new int[this.max];
this.drawNewCb = new int[this.max];
this.drawNewLV = new int[this.max];
this.slideX = new int[this.max];
this.num = 0;
for (int i = 0; i < this.max; i++) {
this.message[i] = "";
this.getMessage[i] = "";
this.getMessageLength[i] = 0;
this.bright[i] = (this.brightMax * i / this.max);
}
}
public void setDefaultColor(int d_cr, int d_cg, int d_cb) {
this.default_cr = d_cr;
this.default_cg = d_cg;
this.default_cb = d_cb;
if (this.default_cr > 255 - this.brightMax) {
this.default_cr = (255 - this.brightMax);
}
if (this.default_cg > 255 - this.brightMax) {
this.default_cg = (255 - this.brightMax);
}
if (this.default_cb > 255 - this.brightMax) {
this.default_cb = (255 - this.brightMax);
}
}
@Override
public IFont getFont() {
return font;
}
@Override
public LTextArea setFont(IFont changeFont) {
this.font = changeFont;
return this;
}
public void setWidthLimit(int widthLimit) {
this.messageWidthLimit = widthLimit;
}
public void setNewFlag() {
this.drawNew[this.num] = true;
}
public void clear() {
this.num = 0;
}
public int count() {
return this.num;
}
public void setSlideMessage(boolean bool) {
this.slideMessage = bool;
}
public void setCenter(boolean bool) {
this.center = bool;
}
public void setColor(int d_cr, int d_cg, int d_cb) {
this.cr[this.num] = d_cr;
this.cg[this.num] = d_cg;
this.cb[this.num] = d_cb;
if (this.cr[this.num] > 255 - this.brightMax) {
this.cr[this.num] = (255 - this.brightMax);
}
if (this.cg[this.num] > 255 - this.brightMax) {
this.cg[this.num] = (255 - this.brightMax);
}
if (this.cb[this.num] > 255 - this.brightMax) {
this.cb[this.num] = (255 - this.brightMax);
}
}
public void put(String mes, LColor color) {
if (StringUtils.isEmpty(mes)) {
return;
}
String[] messages = StringUtils.split(mes, '\n');
for (int i = messages.length - 1; i > -1; i--) {
setColor(color.getRed(), color.getGreen(), color.getBlue());
putOne(messages[i]);
}
}
public void put(String mes) {
if (StringUtils.isEmpty(mes)) {
return;
}
String[] messages = StringUtils.split(mes, '\n');
for (int i = messages.length - 1; i > -1; i--) {
putOne(messages[i]);
}
}
private void putOne(String mes) {
this.over = false;
this.numBak = this.num;
if (font != null && font instanceof LFont) {
LSTRDictionary.get().bind((LFont) font, mes);
}
this.message[this.num] = mes;
if ((this.cr[this.num] == 0) && (this.cg[this.num] == 0)
&& (this.cb[this.num] == 0)) {
this.cr[this.num] = this.default_cr;
this.cg[this.num] = this.default_cg;
this.cb[this.num] = this.default_cb;
} else {
if (this.cr[this.num] + this.brightMax > 255) {
this.cr[this.num] = (255 - this.brightMax);
} else if (this.cr[this.num] < 0) {
this.cr[this.num] = 0;
}
if (this.cg[this.num] + this.brightMax > 255) {
this.cr[this.num] = (255 - this.brightMax);
} else if (this.cg[this.num] < 0) {
this.cg[this.num] = 0;
}
if (this.cb[this.num] + this.brightMax > 255) {
this.cr[this.num] = (255 - this.brightMax);
} else if (this.cb[this.num] < 0) {
this.cb[this.num] = 0;
}
}
if ((this.font != null)
&& (this.font.stringWidth(this.message[this.num]) > this.messageWidthLimit)) {
this.posx = 1;
for (;;) {
if (this.font.stringWidth(this.message[this.num].substring(0,
this.message[this.num].length() - this.posx)) <= this.messageWidthLimit) {
this.str = this.message[this.num].substring(
this.message[this.num].length() - this.posx,
this.message[this.num].length());
this.message[this.num] = this.message[this.num].substring(
0, this.message[this.num].length() - this.posx);
this.over = true;
break;
}
this.posx += 1;
}
}
this.num += 1;
if (this.num >= this.max) {
this.num = 0;
}
this.cr[this.num] = this.default_cr;
this.cg[this.num] = this.default_cg;
this.cb[this.num] = this.default_cb;
this.getMessageLength[this.num] = 0;
this.getMessage[this.num] = "";
this.drawNew[this.num] = false;
this.slideX[this.num] = -200;
if (this.over) {
setColor(this.cr[this.numBak], this.cg[this.numBak],
this.cb[this.numBak]);
put(this.str);
}
}
private void setGetMessageLength(int d_length) {
this.getMessageLength[this.num] = d_length;
}
public void addString(String mes, LColor color) {
setColor(color.getRed(), color.getGreen(), color.getBlue());
addString(mes);
}
public void addString(String mes) {
this.num -= 1;
if (this.num < 0) {
this.num = (this.max - 1);
}
setGetMessageLength(this.getMessageLength[this.num]);
put(this.message[this.num] + mes);
}
public void setBright(int max, int speed) {
this.brightMax = max;
this.brightSpeed = speed;
}
public void setWaitTriangleColor(LColor color) {
this.triangleColor = color;
}
public void draw(GLEx g, int dx, int dy, int d_type, int lines) {
if (_background != null) {
g.draw(_background, dx, dy, getWidth(), getHeight(), baseColor);
}
int oldColor = g.color();
this.countFrame += 1;
int index = num;
for (int i = 0; i < this.max - 1; i++) {
this.num -= 1;
if (this.num < 0) {
this.num = (this.max - 1);
}
if (i <= lines) {
for (int i2 = 0; i2 < 2; i2++) {
if (this.getMessageLength[this.num] < this.message[this.num]
.length()) {
String[] temp = this.getMessage;
temp[this.num] = (temp[this.num] + this.message[this.num]
.substring(this.getMessageLength[this.num],
this.getMessageLength[this.num] + 1));
this.getMessageLength[this.num] += 1;
}
}
if (d_type == 0) {
this.drawY = (dy + i * this.font.getSize());
} else {
this.drawY = (dy - i * this.font.getSize() - this.font
.getSize());
}
this.posx = dx;
if (this.center) {
this.posx -= this.font.stringWidth(this.message[this.num]) / 2;
}
if (this.slideMessage) {
this.posx += this.slideX[this.num];
if (this.slideX[this.num] < 0)
this.slideX[this.num] += 10;
else {
this.slideX[this.num] = 0;
}
}
if (this.drawNew[this.num]) {
if (this.drawNewLV[this.num] == 0) {
this.drawNewCr[this.num] += 20;
if (this.drawNewCr[this.num] >= 255) {
this.drawNewCr[this.num] = 255;
this.drawNewLV[this.num] = 1;
}
} else if (this.drawNewLV[this.num] == 1) {
this.drawNewCg[this.num] += 20;
if (this.drawNewCg[this.num] >= 255) {
this.drawNewCg[this.num] = 255;
this.drawNewLV[this.num] = 2;
}
} else if (this.drawNewLV[this.num] == 2) {
this.drawNewCb[this.num] += 20;
if (this.drawNewCb[this.num] >= 255) {
this.drawNewCb[this.num] = 255;
this.drawNewLV[this.num] = 3;
}
} else if (this.drawNewLV[this.num] == 3) {
this.drawNewCr[this.num] -= 20;
if (this.drawNewCr[this.num] <= 0) {
this.drawNewCr[this.num] = 0;
this.drawNewLV[this.num] = 4;
}
} else if (this.drawNewLV[this.num] == 4) {
this.drawNewCg[this.num] -= 20;
if (this.drawNewCg[this.num] <= 0) {
this.drawNewCg[this.num] = 0;
this.drawNewLV[this.num] = 5;
}
} else if (this.drawNewLV[this.num] == 5) {
this.drawNewCb[this.num] -= 20;
if (this.drawNewCb[this.num] <= 0) {
this.drawNewCb[this.num] = 0;
this.drawNewLV[this.num] = 0;
}
}
tmpcolor.setColor(this.drawNewCr[this.num],
this.drawNewCg[this.num], this.drawNewCb[this.num]);
this.str = "new";
drawString(g, this.str, this.posx, this.drawY, tmpcolor);
this.posx += this.font.stringWidth(this.str);
}
tmpcolor.setColor(50, 50, 50);
drawString(g, this.getMessage[this.num], this.posx + 1,
this.drawY + 1, tmpcolor);
tmpcolor.setColor(this.cr[this.num] + this.bright[i],
this.cg[this.num] + this.bright[i], this.cb[this.num]
+ this.bright[i]);
drawString(g, this.getMessage[this.num], this.posx, this.drawY,
tmpcolor);
if ((this.waitFlag) && (i == 0) && index > 0) {
this.posy = (this.countFrame * 1 / 3 % this.font.getSize()
/ 2 - 2);
drawString(
g,
flag,
this.posx
+ this.font
.stringWidth(this.getMessage[this.num]),
this.drawY - this.posy, this.triangleColor);
}
if (this.brightType[i] == TYPE_DOWN) {
this.bright[i] += this.brightSpeed;
if (this.bright[i] >= this.brightMax) {
this.bright[i] = this.brightMax;
this.brightType[i] = TYPE_UP;
}
} else {
this.bright[i] -= this.brightSpeed;
if (this.bright[i] < 0) {
this.bright[i] = 0;
this.brightType[i] = TYPE_DOWN;
}
}
}
}
this.num -= 1;
if (this.num < 0) {
this.num = (this.max - 1);
}
g.setColor(oldColor);
}
public void setWaitFlag(boolean w) {
this.waitFlag = w;
}
public int getMax() {
return this.max - 1;
}
public int getShowType() {
return showType;
}
public void setShowType(int showType) {
this.showType = showType;
}
public int[] getBright() {
return bright;
}
public void setBright(int[] bright) {
this.bright = bright;
}
public int[] getBrightType() {
return brightType;
}
public void setBrightType(int[] brightType) {
this.brightType = brightType;
}
public int getBrightMax() {
return brightMax;
}
public void setBrightMax(int brightMax) {
this.brightMax = brightMax;
}
public int getBrightSpeed() {
return brightSpeed;
}
public void setBrightSpeed(int brightSpeed) {
this.brightSpeed = brightSpeed;
}
public int getPostLine() {
return postLine;
}
public void setPostLine(int postLine) {
this.postLine = postLine;
}
public int getCountFrame() {
return countFrame;
}
public void setCountFrame(int countFrame) {
this.countFrame = countFrame;
}
@Override
public void setBackground(LTexture texture) {
this._background = texture;
}
@Override
public void setBackground(String path) {
setBackground(LTextures.loadTexture(path));
}
private void drawString(GLEx g, String str, int x, int y, LColor color) {
if (showType == TYPE_DOWN) {
font.drawString(g, str, x + leftOffset + 5, (y - 5) + topOffset
+ font.getAscent() / 2, color);
} else {
font.drawString(g, str, x + leftOffset + 5, (y - 5) + topOffset
+ font.getAscent() / 2 + getHeight() - font.getHeight(),
color);
}
}
public int getLeftOffset() {
return leftOffset;
}
public void setLeftOffset(int leftOffset) {
this.leftOffset = leftOffset;
}
public int getTopOffset() {
return topOffset;
}
public void setTopOffset(int topOffset) {
this.topOffset = topOffset;
}
@Override
public void createUI(GLEx g, int x, int y, LComponent component,
LTexture[] buttonImage) {
draw(g, x, y, showType, postLine);
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
@Override
public void close() {
super.close();
if (_background != null) {
_background.close();
}
}
@Override
public String getUIName() {
return "TextArea";
}
}