277 lines
9.3 KiB
Java
277 lines
9.3 KiB
Java
package electrosphere.renderer.ui.elements;
|
|
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
|
|
import org.joml.Vector2f;
|
|
import org.joml.Vector3f;
|
|
|
|
import electrosphere.logger.LoggerInterface;
|
|
import electrosphere.main.Globals;
|
|
import electrosphere.renderer.Material;
|
|
import electrosphere.renderer.Model;
|
|
import electrosphere.renderer.framebuffer.Framebuffer;
|
|
import electrosphere.renderer.framebuffer.FramebufferUtils;
|
|
import electrosphere.renderer.ui.ContainerElement;
|
|
import electrosphere.renderer.ui.DrawableElement;
|
|
import electrosphere.renderer.ui.Element;
|
|
import electrosphere.renderer.ui.events.Event;
|
|
|
|
import static org.lwjgl.opengl.GL11.*;
|
|
import static org.lwjgl.opengl.GL30.*;
|
|
|
|
public class ScrollableContainer implements DrawableElement, ContainerElement {
|
|
|
|
boolean focused = false;
|
|
List<Element> childList = new LinkedList<Element>();
|
|
|
|
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;
|
|
|
|
Framebuffer widgetBuffer;
|
|
Material customMat = new Material();
|
|
Vector3f boxPosition = new Vector3f();
|
|
Vector3f boxDimensions = new Vector3f();
|
|
Vector3f texPosition = new Vector3f(0,1,0);
|
|
Vector3f texScale = new Vector3f(1,-1,0);
|
|
|
|
|
|
public ScrollableContainer(int positionX, int positionY, int width, int height){
|
|
widgetBuffer = FramebufferUtils.generateTextureFramebuffer(width, height);
|
|
// widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
|
|
customMat.setTexturePointer(widgetBuffer.getTexturePointer());
|
|
// customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer());
|
|
float ndcX = (float)positionX/Globals.WINDOW_WIDTH;
|
|
float ndcY = (float)positionY/Globals.WINDOW_HEIGHT;
|
|
float ndcWidth = (float)width/Globals.WINDOW_WIDTH;
|
|
float ndcHeight = (float)height/Globals.WINDOW_HEIGHT;
|
|
this.width = width;
|
|
this.height = height;
|
|
boxPosition = new Vector3f(ndcX,ndcY,0);
|
|
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
public int getWidth() {
|
|
return width;
|
|
}
|
|
|
|
@Override
|
|
public int getHeight() {
|
|
return height;
|
|
}
|
|
|
|
@Override
|
|
public int getPositionX() {
|
|
return positionX;
|
|
}
|
|
|
|
@Override
|
|
public int getPositionY() {
|
|
return positionY;
|
|
}
|
|
|
|
@Override
|
|
public void setWidth(int width) {
|
|
// TODO Auto-generated method stub
|
|
this.width = width;
|
|
}
|
|
|
|
@Override
|
|
public void setHeight(int height) {
|
|
// TODO Auto-generated method stub
|
|
this.height = height;
|
|
}
|
|
|
|
@Override
|
|
public void setPositionX(int positionX) {
|
|
// TODO Auto-generated method stub
|
|
this.positionX = positionX;
|
|
}
|
|
|
|
@Override
|
|
public void setPositionY(int positionY) {
|
|
// TODO Auto-generated method stub
|
|
this.positionY = positionY;
|
|
}
|
|
|
|
@Override
|
|
public void setParentWidth(int width) {
|
|
// TODO Auto-generated method stub
|
|
parentWidth = width;
|
|
float ndcX = (float)positionX/parentWidth;
|
|
float ndcY = (float)positionY/parentHeight;
|
|
float ndcWidth = (float)width/parentWidth;
|
|
float ndcHeight = (float)height/parentHeight;
|
|
boxPosition = new Vector3f(ndcX,ndcY,0);
|
|
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
|
}
|
|
|
|
@Override
|
|
public void setParentHeight(int height) {
|
|
// TODO Auto-generated method stub
|
|
parentHeight = height;
|
|
float ndcX = (float)positionX/parentWidth;
|
|
float ndcY = (float)positionY/parentHeight;
|
|
float ndcWidth = (float)width/parentWidth;
|
|
float ndcHeight = (float)height/parentHeight;
|
|
boxPosition = new Vector3f(ndcX,ndcY,0);
|
|
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
public void addChild(Element child) {
|
|
childList.add(child);
|
|
if(child instanceof DrawableElement){
|
|
DrawableElement drawableChild = (DrawableElement) child;
|
|
drawableChild.setParentWidth(width);
|
|
drawableChild.setParentHeight(height);
|
|
drawableChild.setVisible(false);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public List<Element> getChildren() {
|
|
return childList;
|
|
}
|
|
|
|
@Override
|
|
public void removeChild(Element child) {
|
|
childList.remove(child);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
public boolean handleEvent(Event event) {
|
|
// TODO Auto-generated method stub
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean getVisible() {
|
|
// TODO Auto-generated method stub
|
|
return visible;
|
|
}
|
|
|
|
@Override
|
|
public void setVisible(boolean visible) {
|
|
// TODO Auto-generated method stub
|
|
this.visible = visible;
|
|
}
|
|
|
|
//recursively check if focused element is child of input element or is input element
|
|
boolean containsFocusedElement(Element parent){
|
|
Element focusedElement = Globals.elementManager.getFocusedElement();
|
|
if(parent == focusedElement){
|
|
return true;
|
|
} else if(parent instanceof ContainerElement){
|
|
ContainerElement container = (ContainerElement)parent;
|
|
for(Element child : container.getChildren()){
|
|
if(containsFocusedElement(child)){
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void draw(int parentFramebufferPointer, int parentWidth, int parentHeight) {
|
|
//figure out if currently focused element is a child or subchild of this container
|
|
if(containsFocusedElement(this)){
|
|
//if it is, if it is offscreen, calculate offset to put it onscreen
|
|
Element focused = Globals.elementManager.getFocusedElement();
|
|
if(
|
|
focused.getPositionX() + focused.getWidth() > this.width ||
|
|
focused.getPositionY() + focused.getHeight() > this.height ||
|
|
focused.getPositionX() < 0 ||
|
|
focused.getPositionY() < 0
|
|
){
|
|
int neededOffsetX = 0;
|
|
int neededOffsetY = 0;
|
|
//basically if we're offscreen negative, pull to positive
|
|
//if we're offscreen positive and we're not as large as the screen, pull from the positive into focus
|
|
//if we are larger than the screen, set position to 0
|
|
if(focused.getPositionX() < 0){
|
|
neededOffsetX = -focused.getPositionX();
|
|
} else if(focused.getPositionX() + focused.getWidth() > this.width){
|
|
if(focused.getWidth() > this.width){
|
|
neededOffsetX = -focused.getPositionX();
|
|
} else {
|
|
neededOffsetX = -((focused.getPositionX() - this.width) + focused.getWidth());
|
|
}
|
|
}
|
|
if(focused.getPositionY() < 0){
|
|
neededOffsetY = -focused.getPositionY();
|
|
} else if(focused.getPositionY() + focused.getHeight() > this.height){
|
|
if(focused.getHeight() > this.height){
|
|
neededOffsetY = -focused.getPositionY();
|
|
} else {
|
|
neededOffsetY = -((focused.getPositionY() - this.height) + focused.getHeight());
|
|
// System.out.println(focused.getPositionY() + " " + this.height + " " + focused.getHeight());
|
|
}
|
|
}
|
|
//apply offset to all children
|
|
for(Element child : childList){
|
|
int newX = child.getPositionX() + neededOffsetX;
|
|
int newY = child.getPositionY() + neededOffsetY;
|
|
child.setPositionX(newX);
|
|
child.setPositionY(newY);
|
|
// System.out.println(currentX + " " + currentY);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
widgetBuffer.bind();
|
|
// Globals.renderingEngine.setViewportSize(width, height);
|
|
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
for(Element child : childList){
|
|
if(child instanceof DrawableElement){
|
|
DrawableElement drawableChild = (DrawableElement) child;
|
|
drawableChild.draw(widgetBuffer.getFramebufferPointer(),width,height);
|
|
}
|
|
}
|
|
//this call binds the screen as the "texture" we're rendering to
|
|
//have to call before actually rendering
|
|
glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
|
|
Globals.renderingEngine.setViewportSize(parentWidth, parentHeight);
|
|
|
|
Model planeModel = Globals.assetManager.fetchModel(Globals.planeModelID);
|
|
if(planeModel != null){
|
|
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
|
|
planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
|
|
planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
|
|
planeModel.pushUniformToMesh("plane", "tDimension", texScale);
|
|
planeModel.meshes.get(0).setMaterial(customMat);
|
|
planeModel.drawUI();
|
|
} else {
|
|
LoggerInterface.loggerRenderer.ERROR("ScrollableContainer unable to find plane model!!", new Exception());
|
|
}
|
|
}
|
|
|
|
}
|