package electrosphere.renderer.ui.elements; import org.joml.Vector3f; import org.lwjgl.opengl.GL30; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.debug.DebugRendering; 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.HoverableElement; import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.events.FocusEvent; import electrosphere.renderer.ui.events.HoverEvent; import electrosphere.renderer.ui.events.MouseEvent; public class Button extends StandardContainerElement implements DrawableElement, FocusableElement, ClickableElement, HoverableElement { 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(); boolean visible = false; boolean focused = false; FocusEventCallback onFocusCallback; FocusEventCallback onLoseFocusCallback; ClickEventCallback clickCallback; HoverEventCallback hoverEventCallback; static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,1.0f,1.0f); public Button(){ super(); } /** * Creates a button with * @param text * @return */ public static Button createButton(String text, ClickableElement.ClickEventCallback callback){ Button rVal = new Button(); Label rValLabel = new Label(1.0f); rValLabel.setText(text); rVal.addChild(rValLabel); rVal.setOnClick(callback); return rVal; } public boolean getVisible() { return visible; } public void setVisible(boolean draw) { this.visible = draw; } @Override public boolean isFocused() { return focused; } void onFocus(FocusEvent event) { if(onFocusCallback != null){ onFocusCallback.execute(event); } else { for(Element child : childList){ if(child instanceof Label){ Label childLabel = (Label) child; childLabel.setColor(new Vector3f(1,0,0)); } } } } void onLoseFocus(FocusEvent event) { if(onLoseFocusCallback != null){ onLoseFocusCallback.execute(event); } else { for(Element child : childList){ if(child instanceof Label){ Label childLabel = (Label) child; childLabel.setColor(new Vector3f(1,1,1)); } } } } /** * Default hover event handling * @param event the hover event */ void onHoverEvent(HoverEvent event){ if(event.isHovered()){ for(Element child : childList){ if(child instanceof Label){ Label childLabel = (Label) child; childLabel.setColor(new Vector3f(1,0,0)); } } } else { for(Element child : childList){ if(child instanceof Label){ Label childLabel = (Label) child; childLabel.setColor(new Vector3f(1,1,1)); } } } } public void draw( RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentPosX, int parentPosY, int parentWidth, int parentHeight ) { // //Draw decorations float ndcWidth = (float)getWidth()/parentWidth; float ndcHeight = (float)getHeight()/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 GL30.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){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; drawableChild.draw( renderPipelineState, openGLState, parentFramebufferPointer, parentPosX + this.internalPositionX, parentPosY + this.internalPositionY, parentWidth, parentHeight ); } } if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_BUTTON){ DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); } } @Override public void setOnFocus(FocusEventCallback callback) { onFocusCallback = callback; } @Override public void setOnLoseFocus(FocusEventCallback callback) { onLoseFocusCallback = callback; } @Override public void setOnClick(ClickEventCallback callback) { clickCallback = callback; } public boolean handleEvent(Event event){ if(event instanceof MouseEvent){ return false; } if(event instanceof FocusEvent){ FocusEvent focusEvent = (FocusEvent) event; if(focusEvent.isFocused()){ this.focused = true; onFocus(focusEvent); } else { this.focused = false; onLoseFocus(focusEvent); } return false; } if(event instanceof ClickEvent){ if(clickCallback != null){ clickCallback.execute((ClickEvent)event); } } if(event instanceof HoverEvent){ if(hoverEventCallback != null){ hoverEventCallback.execute((HoverEvent)event); } else { //default hover handling onHoverEvent((HoverEvent)event); } } return true; } @Override public void setOnHoverCallback(HoverEventCallback callback) { this.hoverEventCallback = callback; } }