Dawn/src/dawn/ui/UIComponent.hpp

203 lines
6.0 KiB
C++

// 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 "scene/Scene.hpp"
#include "display/Color.hpp"
#include "util/array.hpp"
#include "util/mathutils.hpp"
#include "display/shader/Shader.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 {
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<UIComponent*> children;
UIComponent *parent = nullptr;
// Events
Event<UIComponent*> 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<struct ShaderPassItem> 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<struct ShaderPassItem> 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;
};
}