Renderer/src/main/java/electrosphere/renderer/ui/elements/ToggleInput.java
austin ff44e78078
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
image-based frames for backing elements
2025-04-01 15:38:54 -04:00

229 lines
8.4 KiB
Java

package electrosphere.renderer.ui.elements;
import org.joml.Vector3f;
import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.framebuffer.Framebuffer;
import electrosphere.renderer.model.Material;
import electrosphere.renderer.model.Model;
import electrosphere.renderer.ui.elementtypes.ClickableElement;
import electrosphere.renderer.ui.elementtypes.ValueElement;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.Event;
import electrosphere.renderer.ui.events.ValueChangeEvent;
/**
* A toggle input
*/
public class ToggleInput extends StandardDrawableElement implements ClickableElement, ValueElement {
/**
* Click callback
*/
ClickEventCallback onClickCallback = null;
/**
* Value change callback
*/
ValueChangeEventCallback onValueChangeCallback = null;
/**
* The value of the toggle
*/
boolean value = false;
/**
* Material for drawing the circle
*/
static Material circleMat = null;
/**
* The width/height of the circle
*/
private static final float CIRCLE_WIDTH = 0.4f;
/**
* The offset from the center of the bar to place the circle
*/
private static final float CIRCLE_OFFSET_FROM_CENTER = 0.25f;
/**
* The color of the circle
*/
Vector3f circleColor = new Vector3f(0.8f,0.8f,0.8f);
/**
* Material for drawing the connecting bar between the circle positions
*/
static Material barMat = null;
/**
* The height of the bar relative to the total drawable height
*/
private static final float BAR_HEIGHT = 0.6f;
/**
* The color of the bar
*/
Vector3f barColor = new Vector3f(0.3f,0.3f,0.3f);
/**
* The default width of the toggle in pixels
*/
private static final int TOGGLE_PIXEL_WIDTH_DEFAULT = 60;
/**
* The default height of the toggle in pixels
*/
private static final int TOGGLE_PIXEL_HEIGHT_DEFAULT = 38;
/**
* Creates a toggle input
* @return The toggle input
*/
public static ToggleInput createToggleInput(){
return new ToggleInput();
}
/**
* Constructor
*/
private ToggleInput(){
//material work
if(circleMat == null){
circleMat = new Material();
circleMat.set_diffuse("Textures/ui/circle.png");
circleMat.set_specular("Textures/ui/circle.png");
}
if(barMat == null){
barMat = new Material();
barMat.set_diffuse("Textures/ui/square.png");
barMat.set_specular("Textures/ui/square.png");
}
this.setWidth(TOGGLE_PIXEL_WIDTH_DEFAULT);
this.setHeight(TOGGLE_PIXEL_HEIGHT_DEFAULT);
}
@Override
public void draw(
RenderPipelineState renderPipelineState,
OpenGLState openGLState,
Framebuffer framebuffer,
int framebufferPosX,
int framebufferPosY
){
framebuffer.bind(openGLState);
openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight());
float ndcWidth = (float)getWidth()/framebuffer.getWidth();
float ndcHeight = (float)getHeight()/framebuffer.getHeight();
float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth();
float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight();
Vector3f boxPosition = new Vector3f(ndcX,ndcY,0);
Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
//getInternalX() and getInternalY() are the top left corner of the drawable space
//getInternalWidth() and getInternalHeight() are the width and height of the drawable space
//the actual offset from the center (with appropriate sign based on value)
float circleOffsetActual = 0;
if(value){
circleColor.set(0.9f, 0.9f, 0.9f);
barColor.set(0.5f, 0.9f, 0.5f);
circleOffsetActual = CIRCLE_OFFSET_FROM_CENTER;
} else {
circleColor.set(0.9f, 0.9f, 0.9f);
barColor.set(0.9f, 0.5f, 0.5f);
circleOffsetActual = -CIRCLE_OFFSET_FROM_CENTER;
}
//ratio to adjust the circlewidth by to always show a circle and not a deformed oval
float circleRatio = getWidth() / (float)getHeight();
Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID);
if(planeModel != null){
//draw bar
ndcX = (float)(this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX) + (getWidth() * ((1.0f - CIRCLE_WIDTH)/2.0f)))/framebuffer.getWidth();
ndcY = (float)(this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY) + (getHeight() * ((1.0f - BAR_HEIGHT) / 2.0f)))/framebuffer.getHeight();
ndcWidth = (float)((getWidth()) - (getWidth() * ((1.0f - CIRCLE_WIDTH))))/framebuffer.getWidth();
ndcHeight = (float)(getHeight() * BAR_HEIGHT)/framebuffer.getHeight();
boxPosition = new Vector3f(ndcX,ndcY,0);
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
planeModel.getMeshes().get(0).setMaterial(barMat);
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
planeModel.pushUniformToMesh("plane", "tPosition", new Vector3f(0,0,0));
planeModel.pushUniformToMesh("plane", "tDimension", new Vector3f(1,1,0));
planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", barColor);
planeModel.drawUI();
//draw circle
ndcX = (float)(this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX) + (getWidth() * ((1.0f - CIRCLE_WIDTH) / 2.0f)) + (getWidth() * circleOffsetActual))/framebuffer.getWidth();
ndcY = (float)(this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY) + (getHeight() * ((1.0f - (CIRCLE_WIDTH * circleRatio)) / 2.0f)))/framebuffer.getHeight();
ndcWidth = (float)((getWidth() * CIRCLE_WIDTH))/framebuffer.getWidth();
ndcHeight = (float)(getHeight() * (CIRCLE_WIDTH * circleRatio))/framebuffer.getHeight();
boxPosition = new Vector3f(ndcX,ndcY,0);
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
planeModel.getMeshes().get(0).setMaterial(circleMat);
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
planeModel.pushUniformToMesh("plane", "tPosition", new Vector3f(0,0,0));
planeModel.pushUniformToMesh("plane", "tDimension", new Vector3f(1,1,0));
planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", circleColor);
planeModel.drawUI();
} else {
LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model!!", new Exception());
}
}
/**
* Handles an event
*/
public boolean handleEvent(Event event){
boolean propagate = true;
if(event instanceof ClickEvent){
ClickEvent clickEvent = (ClickEvent)event;
if(onClickCallback != null){
onClickCallback.execute(clickEvent);
} else {
Globals.elementService.focusElement(this);
this.value = !this.value;
Globals.elementService.fireEventNoPosition(new ValueChangeEvent(this.value), this);
propagate = false;
}
} else if(event instanceof ValueChangeEvent){
ValueChangeEvent valueEvent = (ValueChangeEvent)event;
if(this.onValueChangeCallback != null){
this.onValueChangeCallback.execute(valueEvent);
}
}
return propagate;
}
@Override
public void setOnValueChangeCallback(ValueChangeEventCallback callback) {
this.onValueChangeCallback = callback;
}
@Override
public void setOnClick(ClickEventCallback callback) {
this.onClickCallback = callback;
}
/**
* Sets the value of the toggle
* @param value The value to set the toggle to
*/
public void setValue(boolean value){
this.value = value;
}
}