279 lines
9.3 KiB
Java
279 lines
9.3 KiB
Java
package electrosphere.renderer.ui.elements;
|
|
|
|
import electrosphere.engine.Globals;
|
|
import electrosphere.logger.LoggerInterface;
|
|
import electrosphere.renderer.OpenGLState;
|
|
import electrosphere.renderer.RenderPipelineState;
|
|
import electrosphere.renderer.model.Material;
|
|
import electrosphere.renderer.model.Model;
|
|
import electrosphere.renderer.texture.Texture;
|
|
import electrosphere.renderer.ui.elementtypes.ClickableElement;
|
|
import electrosphere.renderer.ui.elementtypes.DrawableElement;
|
|
import electrosphere.renderer.ui.elementtypes.Element;
|
|
import electrosphere.renderer.ui.elementtypes.FocusableElement;
|
|
import electrosphere.renderer.ui.elementtypes.KeyEventElement;
|
|
import electrosphere.renderer.ui.events.ClickEvent;
|
|
import electrosphere.renderer.ui.events.Event;
|
|
import electrosphere.renderer.ui.events.FocusEvent;
|
|
import electrosphere.renderer.ui.events.KeyboardEvent;
|
|
import electrosphere.renderer.ui.font.Font;
|
|
|
|
import org.joml.Vector3f;
|
|
import org.lwjgl.opengl.GL30;
|
|
import org.lwjgl.util.yoga.Yoga;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
/**
|
|
* A Text input
|
|
*/
|
|
public class TextInput extends StandardContainerElement implements DrawableElement, FocusableElement, KeyEventElement, ClickableElement {
|
|
|
|
Vector3f boxPosition = new Vector3f();
|
|
Vector3f boxDimensions = new Vector3f();
|
|
Vector3f texPosition = new Vector3f(0,0,0);
|
|
Vector3f texScale = new Vector3f(1,1,0);
|
|
Material customMat = new Material();
|
|
|
|
public boolean visible = false;
|
|
|
|
boolean focused = false;
|
|
FocusEventCallback onFocusCallback;
|
|
FocusEventCallback onLoseFocusCallback;
|
|
KeyboardEventCallback onKeyPressCallback;
|
|
ClickEventCallback onClickCallback;
|
|
Vector3f color;
|
|
|
|
String text = "";
|
|
int textPixelWidth = 0;
|
|
|
|
float fontSize = 1.0f;
|
|
|
|
|
|
Font font;
|
|
|
|
/**
|
|
* Creates a text input element
|
|
* @param fontSize the size of the font in the text element
|
|
* @return The text input
|
|
*/
|
|
public static TextInput createTextInput(float fontSize){
|
|
return new TextInput(fontSize);
|
|
}
|
|
|
|
/**
|
|
* Private constructor
|
|
* @param fontSize
|
|
*/
|
|
private TextInput(float fontSize){
|
|
super();
|
|
this.font = Globals.fontManager.getFont("default");
|
|
this.fontSize = fontSize;
|
|
this.color = new Vector3f(1,1,1);
|
|
setHeight((int)(font.getFontHeight() * fontSize));
|
|
Yoga.YGNodeStyleSetFlexDirection(this.yogaNode, Yoga.YGFlexDirectionRow);
|
|
Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.imageHeight * fontSize);
|
|
Yoga.YGNodeStyleSetMinWidth(this.yogaNode, 1);
|
|
}
|
|
|
|
/**
|
|
* Constructor
|
|
* @param x
|
|
* @param y
|
|
* @param fontSize
|
|
*/
|
|
public TextInput(int x, int y, float fontSize){
|
|
super();
|
|
this.font = Globals.fontManager.getFont("default");
|
|
this.fontSize = fontSize;
|
|
this.color = new Vector3f(1,1,1);
|
|
setHeight((int)(font.getFontHeight() * fontSize));
|
|
Yoga.YGNodeStyleSetFlexDirection(this.yogaNode, Yoga.YGFlexDirectionRow);
|
|
Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.imageHeight * fontSize);
|
|
Yoga.YGNodeStyleSetMinWidth(this.yogaNode, 1);
|
|
}
|
|
|
|
void generateLetters(){
|
|
for(Element el : getChildren()){
|
|
Yoga.YGNodeRemoveChild(this.yogaNode,el.getYogaNode());
|
|
el.destroy();
|
|
}
|
|
childList.clear();
|
|
for(int i = 0; i < text.length(); i++){
|
|
char toDraw = text.charAt(i);
|
|
Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw);
|
|
BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.height, toDraw);
|
|
newLetter.setColor(color);
|
|
this.addChild(newLetter);
|
|
}
|
|
}
|
|
|
|
public void setText(String text){
|
|
this.text = text;
|
|
textPixelWidth = 0;
|
|
for(int i = 0; i < text.length(); i++){
|
|
Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(text.charAt(i));
|
|
textPixelWidth = textPixelWidth + (int)bitMapDimension.x;
|
|
}
|
|
generateLetters();
|
|
}
|
|
|
|
public void setColor(Vector3f color){
|
|
this.color.set(color);
|
|
for(Element character : childList){
|
|
((BitmapCharacter)character).setColor(color);
|
|
}
|
|
}
|
|
|
|
public String getText(){
|
|
return text;
|
|
}
|
|
|
|
@Override
|
|
public void draw(
|
|
RenderPipelineState renderPipelineState,
|
|
OpenGLState openGLState,
|
|
int parentFramebufferPointer,
|
|
int parentPosX,
|
|
int parentPosY,
|
|
int parentWidth,
|
|
int parentHeight
|
|
) {
|
|
//
|
|
//Draw decorations
|
|
|
|
float ndcWidth = (float)getInternalWidth()/parentWidth;
|
|
float ndcHeight = (float)getInternalHeight()/parentHeight;
|
|
float ndcX = (float)(getInternalX() + parentPosX)/parentWidth;
|
|
float ndcY = (float)(getInternalY() + parentPosY)/parentHeight;
|
|
boxPosition = new Vector3f(ndcX,ndcY,0);
|
|
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
|
|
|
Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID);
|
|
Texture windowFrame = null;
|
|
if(this.isFocused()){
|
|
windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame2.png");
|
|
} else {
|
|
windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame1.png");
|
|
}
|
|
|
|
//this call binds the screen as the "texture" we're rendering to
|
|
//have to call before actually rendering
|
|
openGLState.glBindFramebuffer(GL30.GL_FRAMEBUFFER, parentFramebufferPointer);
|
|
openGLState.glViewport(parentWidth, parentHeight);
|
|
|
|
//error if assets are null
|
|
if(planeModel == null || windowFrame == null){
|
|
LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model or window frame!!", new Exception());
|
|
}
|
|
|
|
//render background of window
|
|
if(planeModel != null && windowFrame != null){
|
|
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
|
|
planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
|
|
planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
|
|
planeModel.pushUniformToMesh("plane", "tDimension", texScale);
|
|
customMat.setTexturePointer(windowFrame.getTexturePointer());
|
|
planeModel.getMeshes().get(0).setMaterial(customMat);
|
|
planeModel.drawUI();
|
|
}
|
|
|
|
|
|
//
|
|
//Draw children elements
|
|
for(Element child : childList){
|
|
((DrawableElement)child).draw(renderPipelineState, openGLState, parentFramebufferPointer, parentPosX + this.internalPositionX, parentPosY + this.internalPositionY, parentWidth, parentHeight);
|
|
}
|
|
}
|
|
|
|
public boolean getVisible() {
|
|
return visible;
|
|
}
|
|
|
|
public void setVisible(boolean draw) {
|
|
this.visible = draw;
|
|
}
|
|
|
|
public boolean handleEvent(Event event){
|
|
boolean propagate = true;
|
|
if(event instanceof FocusEvent){
|
|
FocusEvent focusEvent = (FocusEvent)event;
|
|
if(focusEvent.isFocused()){
|
|
if(this.onFocusCallback != null){
|
|
this.onFocusCallback.execute(focusEvent);
|
|
} else {
|
|
this.focused = true;
|
|
this.setColor(new Vector3f(1,0,0));
|
|
propagate = false;
|
|
}
|
|
} else {
|
|
if(this.onLoseFocusCallback != null){
|
|
this.onLoseFocusCallback.execute(focusEvent);
|
|
} else {
|
|
this.focused = false;
|
|
this.setColor(new Vector3f(1,1,1));
|
|
propagate = false;
|
|
}
|
|
}
|
|
} else if(event instanceof KeyboardEvent){
|
|
KeyboardEvent keyEvent = (KeyboardEvent)event;
|
|
if(onKeyPressCallback != null){
|
|
onKeyPressCallback.execute(keyEvent);
|
|
} else {
|
|
propagate = defaultKeyHandling(keyEvent);
|
|
}
|
|
} else if(event instanceof ClickEvent){
|
|
ClickEvent clickEvent = (ClickEvent)event;
|
|
if(onClickCallback != null){
|
|
onClickCallback.execute(clickEvent);
|
|
} else {
|
|
Globals.elementManager.focusElement(this);
|
|
propagate = false;
|
|
}
|
|
}
|
|
return propagate;
|
|
}
|
|
|
|
/**
|
|
* The default handling for a keyboard event
|
|
* @param keyEvent the event
|
|
* @return whether to propagate or not
|
|
*/
|
|
public boolean defaultKeyHandling(KeyboardEvent keyEvent){
|
|
if(keyEvent.getKey().matches(Pattern.quote("bs"))){
|
|
if(this.text.length() > 0){
|
|
this.setText(this.text.substring(0, this.text.length() - 1));
|
|
}
|
|
} else {
|
|
this.setText(this.text + keyEvent.getKey());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isFocused() {
|
|
return focused;
|
|
}
|
|
|
|
@Override
|
|
public void setOnFocus(FocusEventCallback callback) {
|
|
onFocusCallback = callback;
|
|
}
|
|
|
|
@Override
|
|
public void setOnLoseFocus(FocusEventCallback callback) {
|
|
onLoseFocusCallback = callback;
|
|
}
|
|
|
|
@Override
|
|
public void setOnPress(KeyboardEventCallback callback) {
|
|
onKeyPressCallback = callback;
|
|
}
|
|
|
|
@Override
|
|
public void setOnClick(ClickEventCallback callback) {
|
|
onClickCallback = callback;
|
|
}
|
|
|
|
}
|