// Copyright (c) 2022 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma once #include "scene/components/ui/UICanvas.hpp" #include "display/Color.hpp" #include "util/array.hpp" #include "util/mathutils.hpp" #include "display/shader/Shader.hpp" #include "state/State.hpp" namespace Dawn { enum UIComponentAlign { UI_COMPONENT_ALIGN_START, UI_COMPONENT_ALIGN_MIDDLE, UI_COMPONENT_ALIGN_END, UI_COMPONENT_ALIGN_STRETCH }; class UIGrid; class UIComponent : public StateOwner { protected: // Calculated (and cached) values float_t width = 1; float_t height = 1; float_t relativeX = 0; float_t relativeY = 0; // Setting values UIComponentAlign alignX = UI_COMPONENT_ALIGN_START; UIComponentAlign alignY = UI_COMPONENT_ALIGN_START; glm::vec4 alignment = glm::vec4(0, 0, 32, 32); float_t z = 0; std::vector children; UIComponent *parent = nullptr; // Events Event eventAlignmentUpdated; // I currently don't support rotation or scale. Not because I can't but // because it's basically un-necessary. Unity does support rotation but // it doesn't affect how the alignment side of things work (similar to how // CSS would handle things) When I need to support these I will add the // code but right now it's not necessary /** * Updates the cached/stored values based on the setting internal values. * You should watchdog this if you intend to do something when values are * updated, e.g. if you need to resize a quad, or something. */ virtual void updatePositions(); /** * Intended to be overwritten by subclass. Called by the draw method to * ask this child to draw. * * @param projection Projection matrix of the camera. * @param view View matrix of the camera. * @param parent Matrix of the parent of this UI item. * @return The list of shader pass items. */ virtual std::vector getSelfPassItems( glm::mat4 projection, glm::mat4 view, glm::mat4 transform ) = 0; public: /** * Method used to calculate alignment dimensions. * * @param align Alignment value enumator. * @param position Output position floating point. * @param size Output size floating point. * @param outerSize Outer size (of the parent). * @param innerSize Inner size (of this element's content). * @param alignment Alignment settings. */ static void calculateDimensions( enum UIComponentAlign align, float_t *position, float_t *size, float_t outerSize, float_t innerSize, glm::vec2 alignment ); UICanvas *canvas; UIComponent(UICanvas *canvas); /** * Returns the calculated width, based on the internal alignment values. * * @return Width of the component. */ virtual float_t getWidth(); /** * Returns the calculated height, based on the internal alignment values. * * @return Height of the component. */ virtual float_t getHeight(); /** * Returns the internal width of the content within this element, e.g. * the content width. * * @return Content width. */ virtual float_t getContentWidth(); /** * Returns the internal height of the content within this element, e.g. * the content height. * * @return Content height. */ virtual float_t getContentHeight(); /** * Returns the X position, relative to this components' parent. * * @return Relative X position. */ float_t getRelativeX(); /** * Returns the Y position, relative to this components' parent. * * @return Relative Y position. */ float_t getRelativeY(); /** * Gets the game that this UI component belongs to. * * @return Game instance. */ DawnGame * getGame(); /** * Gets the scene that thsi UI Component belongs to. * * @return Scene instance. */ Scene * getScene(); /** * Updates the transformation for this component. * * @param xAlign X axis alignment method. * @param yAlign Y axis alignment method. * @param alignment Alignment parameters, changes depending on the align. * @param z Z position (relative to screen). */ virtual void setTransform( UIComponentAlign xAlign, UIComponentAlign yAlign, glm::vec4 alignment, float_t z ); /** * Returns the list of renderable shader pass items for this UI element. * This is basically how you get your UI item to draw, this is called by * the RenderPipeline. * * @param projection Projection matrix of the camera. * @param view View matrix of the camera. * @param parent Matrix of the parent of this UI item. * @return The list of shader pass items, including children. */ std::vector getPassItems( glm::mat4 projection, glm::mat4 view, glm::mat4 parent ); /** * Adds a child to this UI Component. * * @param child Child UI Component to add. */ virtual void addChild(UIComponent *child); /** * Removes a child from this UI Component. * * @param child Child to remove. */ virtual void removeChild(UIComponent *child); virtual ~UIComponent(); friend class UICanvas; friend class UIGrid; }; }