/*
* Copyright 2016 Nathan Howard
*
* This file is part of OpenGrave
*
* OpenGrave is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenGrave is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenGrave. If not, see <http://www.gnu.org/licenses/>.
*/
package com.opengrave.og.gui;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.opengrave.common.event.EventDispatcher;
import com.opengrave.common.event.EventHandler;
import com.opengrave.common.event.EventHandlerPriority;
import com.opengrave.common.event.EventListener;
import com.opengrave.og.gui.callback.TextSelectedEvent;
import com.opengrave.og.input.MouseButtonRenderableEvent;
import com.opengrave.og.resources.Font;
import com.opengrave.og.resources.FontData;
import com.opengrave.og.resources.Resources;
import com.opengrave.og.util.Vector4f;
public abstract class BaseText extends UIElement implements TextInterface, EventListener {
Pattern colour, link;
boolean picking = false;
private boolean background;
public BaseText(ElementData ed) {
super(ed);
EventDispatcher.addHandler(this);
}
private String contents = "";
private Font f = null;
public Font getFont() {
if (f == null) {
return Resources.defaultFont;
}
return f;
}
@Override
public void setFont(Font font) {
changed = true;
f = font;
}
@Override
public String getString() {
return contents;
}
@Override
public void setString(String contents) {
changed = true;
this.contents = contents;
}
@EventHandler(priority = EventHandlerPriority.EARLY)
public void onMousePress(MouseButtonRenderableEvent event) {
if (event.getObject() == this && event.getButton() == 0) {
for (UIQuad quad : this.getQuads()) {
if (quad.isInside(event.getRX(), event.getRY())) {
if (quad.meta == null) {
continue;
}
event.setConsumed();
TextSelectedEvent tsevent = new TextSelectedEvent();
tsevent.area = this;
tsevent.link = quad.meta;
EventDispatcher.dispatchEvent(tsevent);
}
}
}
}
@Override
public void repopulateQuads() {
if (background) {
addQuad(new UIQuad().setPos(0, 0, width, height).setColour(ed.disabledColour));
}
checkRegexs();
picking = false;
Font font = getFont();
if (font == null) {
return;
}
texture = font.texture;
int x = 0, y = 0, index = 0;
if (contents == null) {
contents = "";
}
Vector4f col = getTextColour();
String meta = null;
for (index = 0; index < contents.length(); index++) {
String remainder = contents.substring(index);
Matcher mc = colour.matcher(remainder);
Matcher ml = link.matcher(remainder);
if (remainder.startsWith("@") && meta != null) {
meta = null;
continue;
}
if (mc.find()) {
String hex = mc.group(1);
col = new Vector4f(Integer.parseInt(hex.substring(0, 1), 16) / 15f, Integer.parseInt(hex.substring(1, 2), 16) / 15f, Integer.parseInt(
hex.substring(2, 3), 16) / 15f, 1f);
index += 3;
continue;
} else if (ml.find()) {
picking = true;
String match = ml.group(1);
meta = match;
index += match.length() + 2;
continue;
}
char c = contents.charAt(index);
int i = (int) c;
if (i == 10) { // New Line
y += font.fontheight;
x = 0;
} else {
FontData fd = font.fontData.get(i);
if (fd == null) {
// System.out.println("Null char in font : " + i);
continue;
}
UIQuad q = new UIQuad();
q.setPos(x, y, x + fd.width, y + fd.height).setTexture(fd.x, fd.x2, fd.y, fd.y2, 0).setColour(col.x, col.y, col.z, col.w);
q.meta = meta;
x += fd.width;
addQuad(q);
}
}
}
private void checkRegexs() {
if (colour == null) {
colour = Pattern.compile("^#([0-9a-fA-F]{3})");
}
if (link == null) {
link = Pattern.compile("^@<(.*?)>");
}
}
/**
* Read through the current string and give the smallest width possible
* without adding extra new lines
*
* @return
*/
public int getTextMinWidth() {
checkRegexs();
int x = 0, index = 0;
int maxWidth = 1;
if (contents == null) {
contents = "";
}
for (index = 0; index < contents.length(); index++) {
String remainder = contents.substring(index);
// First, Check if we're at the start of a colour code
Matcher mc = colour.matcher(remainder);
Matcher ml = link.matcher(remainder);
if (mc.find()) {
// String hex = mc.group(0);
// Vector4f col = new
// Vector4f(Integer.parseInt(hex.substring(0,1),16)/15f,
// Integer.parseInt(hex.substring(1,2),16)/15f,
// Integer.parseInt(hex.substring(2,3),16)/15f,1f);
index += 3;
continue;
} else if (ml.find()) {
String match = ml.group(1);
index += match.length();
continue;
}
char c = contents.charAt(index);
int i = (int) c;
if (i == 10) { // New Line
if (x > maxWidth) {
maxWidth = x;
}
x = 0;
} else {
FontData fd = getFont().fontData.get(i);
if (fd == null) {
continue;
}
x += fd.width;
}
}
if (x > maxWidth) {
maxWidth = x;
}
return maxWidth;
}
@Override
protected boolean shouldRenderForPicking() {
return picking;
}
public void drawBackground(boolean b) {
background = b;
}
}