334 lines
10 KiB
Java
334 lines
10 KiB
Java
package electrosphere.renderer.ui.elements;
|
|
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
|
|
import org.joml.Vector3f;
|
|
|
|
import electrosphere.engine.Globals;
|
|
import electrosphere.renderer.OpenGLState;
|
|
import electrosphere.renderer.RenderPipelineState;
|
|
import electrosphere.renderer.ui.DrawableElement;
|
|
import electrosphere.renderer.ui.Element;
|
|
import electrosphere.renderer.ui.FocusableElement;
|
|
import electrosphere.renderer.ui.MenuEventElement;
|
|
import electrosphere.renderer.ui.ValueElement;
|
|
import electrosphere.renderer.ui.events.Event;
|
|
import electrosphere.renderer.ui.events.FocusEvent;
|
|
import electrosphere.renderer.ui.events.MenuEvent;
|
|
import electrosphere.renderer.ui.events.ValueChangeEvent;
|
|
import electrosphere.renderer.ui.events.MenuEvent.MenuEventType;
|
|
import electrosphere.renderer.ui.font.Font;
|
|
import electrosphere.renderer.ui.font.FontUtils;
|
|
import electrosphere.renderer.ui.font.bitmapchar.BitmapCharacter;
|
|
|
|
public class StringCarousel implements DrawableElement, MenuEventElement, FocusableElement, ValueElement {
|
|
|
|
public int width = 1;
|
|
public int height = 1;
|
|
|
|
public int positionX = 0;
|
|
public int positionY = 0;
|
|
|
|
public int parentWidth = 1;
|
|
public int parentHeight = 1;
|
|
|
|
public boolean visible = false;
|
|
|
|
MenuEventCallback onMenuEventCallback;
|
|
ValueChangeEventCallback onValueChange;
|
|
|
|
boolean focused = false;
|
|
FocusEventCallback onFocusCallback;
|
|
FocusEventCallback onLoseFocusCallback;
|
|
|
|
List<String> options = new LinkedList<String>();
|
|
int currentOption = -1;
|
|
String textCurrent = "";
|
|
int textPixelWidth = 0;
|
|
|
|
float fontSize = 1.0f;
|
|
|
|
List<BitmapCharacter> childrenElements = new LinkedList<BitmapCharacter>();
|
|
|
|
Font font;
|
|
|
|
public StringCarousel(int x, int y, float fontSize){
|
|
this.positionX = x;
|
|
this.positionY = y;
|
|
this.width = 0;
|
|
this.font = Globals.fontManager.getFont("default");
|
|
this.height = (int)(font.getFontHeight() * fontSize);
|
|
this.fontSize = fontSize;
|
|
}
|
|
|
|
public void addOption(String option){
|
|
options.add(option);
|
|
if(currentOption == -1){
|
|
currentOption = 0;
|
|
setText(option);
|
|
if(onValueChange != null){
|
|
onValueChange.execute(new ValueChangeEvent(option));
|
|
}
|
|
}
|
|
}
|
|
|
|
public List<String> getOptions(){
|
|
return options;
|
|
}
|
|
|
|
public void removeOption(String option){
|
|
options.remove(option);
|
|
if(currentOption > options.size() - 1){
|
|
currentOption = options.size() - 1;
|
|
}
|
|
}
|
|
|
|
void generateLetters(){
|
|
childrenElements.clear();
|
|
int rollingOffset = 0;
|
|
for(int i = 0; i < textCurrent.length(); i++){
|
|
char toDraw = textCurrent.charAt(i);
|
|
Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw);
|
|
BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(rollingOffset * fontSize) + positionX, positionY, (int)(bitMapDimension.x * fontSize), this.height, toDraw);
|
|
rollingOffset += (int)bitMapDimension.x;
|
|
childrenElements.add(newLetter);
|
|
}
|
|
}
|
|
|
|
public void setText(String text){
|
|
this.textCurrent = 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();
|
|
if(focused){
|
|
setColor(new Vector3f(1,0,0));
|
|
}
|
|
}
|
|
|
|
public void setColor(Vector3f color){
|
|
for(BitmapCharacter character : childrenElements){
|
|
character.setColor(color);
|
|
}
|
|
}
|
|
|
|
public String getText(){
|
|
return textCurrent;
|
|
}
|
|
|
|
@Override
|
|
public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) {
|
|
for(DrawableElement child : childrenElements){
|
|
child.draw(renderPipelineState, openGLState, parentFramebufferPointer, parentWidth, parentHeight);
|
|
}
|
|
}
|
|
|
|
public int getWidth() {
|
|
int minX = -1;
|
|
int maxX = -1;
|
|
for(BitmapCharacter child : childrenElements){
|
|
if(minX == -1){
|
|
minX = child.getPositionX();
|
|
} else if(child.getPositionX() < minX){
|
|
minX = child.getPositionX();
|
|
}
|
|
if(maxX == -1){
|
|
maxX = child.getPositionX() + child.getWidth();
|
|
} else if(child.getPositionX() + child.getWidth() > maxX){
|
|
maxX = child.getPositionX() + child.getWidth();
|
|
}
|
|
}
|
|
if(minX == -1){
|
|
minX = 0;
|
|
}
|
|
if(maxX == -1){
|
|
maxX = 0;
|
|
}
|
|
return maxX - minX;
|
|
}
|
|
|
|
public int getHeight() {
|
|
int minY = -1;
|
|
int maxY = -1;
|
|
for(BitmapCharacter child : childrenElements){
|
|
if(minY == -1){
|
|
minY = child.getPositionY();
|
|
} else if(child.getPositionY() < minY){
|
|
minY = child.getPositionY();
|
|
}
|
|
if(maxY == -1){
|
|
maxY = child.getPositionY() + child.getHeight();
|
|
} else if(child.getPositionY() + child.getHeight() > maxY){
|
|
maxY = child.getPositionY() + child.getHeight();
|
|
}
|
|
}
|
|
if(minY == -1){
|
|
minY = 0;
|
|
}
|
|
if(maxY == -1){
|
|
maxY = 0;
|
|
}
|
|
return maxY - minY;
|
|
}
|
|
|
|
public int getPositionX() {
|
|
int minX = -1;
|
|
for(BitmapCharacter child : childrenElements){
|
|
if(minX == -1){
|
|
minX = child.getPositionX();
|
|
} else if(child.getPositionX() < minX){
|
|
minX = child.getPositionX();
|
|
}
|
|
}
|
|
if(minX == -1){
|
|
minX = 0;
|
|
}
|
|
return minX;
|
|
}
|
|
|
|
public int getPositionY() {
|
|
int minY = -1;
|
|
for(BitmapCharacter child : childrenElements){
|
|
if(minY == -1){
|
|
minY = child.getPositionY();
|
|
} else if(child.getPositionY() < minY){
|
|
minY = child.getPositionY();
|
|
}
|
|
}
|
|
if(minY == -1){
|
|
minY = 0;
|
|
}
|
|
return minY;
|
|
}
|
|
|
|
public boolean getVisible() {
|
|
return visible;
|
|
}
|
|
|
|
public void setWidth(int width) {
|
|
this.width = width;
|
|
}
|
|
|
|
public void setHeight(int height) {
|
|
this.height = height;
|
|
}
|
|
|
|
public void setPositionX(int posX) {
|
|
int deltaX = posX - this.positionX;
|
|
this.positionX = posX;
|
|
for(Element child : childrenElements){
|
|
child.setPositionX(child.getPositionX() + deltaX);
|
|
}
|
|
}
|
|
|
|
public void setPositionY(int posY) {
|
|
int deltaY = posY - this.positionY;
|
|
this.positionY = posY;
|
|
for(Element child : childrenElements){
|
|
child.setPositionY(child.getPositionY() + deltaY);
|
|
}
|
|
}
|
|
|
|
public void setVisible(boolean draw) {
|
|
this.visible = draw;
|
|
}
|
|
|
|
public void setParentWidth(int width){
|
|
parentWidth = width;
|
|
}
|
|
|
|
public void setParentHeight(int height){
|
|
this.parentHeight = height;
|
|
}
|
|
|
|
public boolean handleEvent(Event event){
|
|
boolean propagate = true;
|
|
if(event instanceof MenuEvent){
|
|
MenuEvent menuEvent = (MenuEvent)event;
|
|
if(onMenuEventCallback != null){
|
|
propagate = onMenuEventCallback.execute(menuEvent);
|
|
} else {
|
|
//default behavior
|
|
if(menuEvent.getType() == MenuEventType.INCREMENT){
|
|
propagate = false;
|
|
if(options.size() > 0){
|
|
currentOption++;
|
|
if(currentOption > options.size() - 1){
|
|
currentOption = 0;
|
|
}
|
|
String newOption = options.get(currentOption);
|
|
setText(newOption);
|
|
if(onValueChange != null){
|
|
onValueChange.execute(new ValueChangeEvent(newOption));
|
|
}
|
|
}
|
|
} else if(menuEvent.getType() == MenuEventType.DECREMENT){
|
|
propagate = false;
|
|
if(options.size() > 0){
|
|
currentOption--;
|
|
if(currentOption < 0){
|
|
currentOption = options.size() - 1;
|
|
}
|
|
String newOption = options.get(currentOption);
|
|
setText(newOption);
|
|
if(onValueChange != null){
|
|
onValueChange.execute(new ValueChangeEvent(newOption));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if(event instanceof FocusEvent){
|
|
FocusEvent focusEvent = (FocusEvent) event;
|
|
if(focusEvent.isFocused()){
|
|
this.focused = true;
|
|
if(onFocusCallback != null){
|
|
propagate = onFocusCallback.execute(focusEvent);
|
|
} else {
|
|
//default behavior
|
|
propagate = false;
|
|
setColor(new Vector3f(1,0,0));
|
|
}
|
|
} else {
|
|
this.focused = false;
|
|
if(onLoseFocusCallback != null){
|
|
propagate = onLoseFocusCallback.execute(focusEvent);
|
|
} else {
|
|
//default behavior
|
|
propagate = false;
|
|
setColor(new Vector3f(1,1,1));
|
|
}
|
|
}
|
|
}
|
|
return propagate;
|
|
}
|
|
|
|
@Override
|
|
public void setOnMenuEventCallback(MenuEventCallback callback) {
|
|
onMenuEventCallback = callback;
|
|
}
|
|
|
|
@Override
|
|
public void setOnValueChangeCallback(ValueChangeEventCallback callback) {
|
|
onValueChange = callback;
|
|
}
|
|
|
|
@Override
|
|
public boolean isFocused() {
|
|
return focused;
|
|
}
|
|
|
|
@Override
|
|
public void setOnFocus(FocusEventCallback callback) {
|
|
onFocusCallback = callback;
|
|
}
|
|
|
|
@Override
|
|
public void setOnLoseFocus(FocusEventCallback callback) {
|
|
onLoseFocusCallback = callback;
|
|
}
|
|
|
|
}
|