UI
This commit is contained in:
@ -1,20 +1,20 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIEmpty.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UIEmpty::UIEmpty(UICanvas *canvas) : UIComponent(canvas) {
|
||||
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> UIEmpty::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
return std::vector<struct ShaderPassItem>();
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIEmpty.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UIEmpty::UIEmpty(UICanvas *canvas) : UIComponent(canvas) {
|
||||
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> UIEmpty::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
return std::vector<struct ShaderPassItem>();
|
||||
}
|
@ -1,21 +1,21 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "UIComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIEmpty : public UIComponent {
|
||||
protected:
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
public:
|
||||
UIEmpty(UICanvas *canvas);
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "UIComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIEmpty : public UIComponent {
|
||||
protected:
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
public:
|
||||
UIEmpty(UICanvas *canvas);
|
||||
};
|
||||
}
|
@ -1,130 +1,130 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIGrid.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UIGrid::UIGrid(UICanvas *canvas) : UIComponent(canvas) {
|
||||
|
||||
}
|
||||
|
||||
void UIGrid::updatePositions() {
|
||||
UIComponent::updatePositions();
|
||||
|
||||
this->sizeCol = (
|
||||
this->width - (this->gutterX * (this->columns - 1))
|
||||
) / this->columns;
|
||||
this->sizeRow = (
|
||||
this->height - (this->gutterY * (this->rows - 1))
|
||||
) / this->rows;
|
||||
|
||||
auto it = this->gridChildren.begin();
|
||||
while(it != this->gridChildren.end()) {
|
||||
this->alignChild(it->first, it->second);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> UIGrid::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
return std::vector<struct ShaderPassItem>();
|
||||
}
|
||||
|
||||
void UIGrid::onChildAligned(UIComponent *child) {
|
||||
if(this->alignmentListenerLocked) return;
|
||||
assertNotNull(child);
|
||||
assertMapHasKey(this->gridChildren, child);
|
||||
this->alignmentListenerLocked = true;
|
||||
this->alignChild(child, this->gridChildren[child]);
|
||||
this->alignmentListenerLocked = false;
|
||||
}
|
||||
|
||||
void UIGrid::alignChild(UIComponent *child, struct UIGridPosition pos) {
|
||||
assertNotNull(child);
|
||||
|
||||
float_t gridX = (this->sizeCol * pos.x) + (this->gutterX * pos.x);
|
||||
float_t gridY = (this->sizeRow * pos.y) + (this->gutterY * pos.y);
|
||||
|
||||
// Hack for when content width is undefined.
|
||||
child->width = this->sizeCol;
|
||||
child->height = this->sizeRow;
|
||||
|
||||
// Alignment
|
||||
float_t x, y, sizeX, sizeY;
|
||||
UIComponent::calculateDimensions(
|
||||
pos.alignX,
|
||||
&x,
|
||||
&sizeX,
|
||||
this->sizeCol,
|
||||
child->getContentWidth(),
|
||||
glm::vec2(0, 0)
|
||||
);
|
||||
UIComponent::calculateDimensions(
|
||||
pos.alignY,
|
||||
&y,
|
||||
&sizeY,
|
||||
this->sizeRow,
|
||||
child->getContentHeight(),
|
||||
glm::vec2(0, 0)
|
||||
);
|
||||
|
||||
child->setTransform(
|
||||
UI_COMPONENT_ALIGN_START, UI_COMPONENT_ALIGN_START,
|
||||
glm::vec4(gridX + x, gridY + y, sizeX, sizeY),
|
||||
0.0f
|
||||
);
|
||||
}
|
||||
|
||||
void UIGrid::setGridSize(
|
||||
int32_t columns, int32_t rows,
|
||||
float_t gutterX, float_t gutterY
|
||||
) {
|
||||
this->rows = rows;
|
||||
this->columns = columns;
|
||||
this->gutterX = gutterX;
|
||||
this->gutterY = gutterY;
|
||||
|
||||
// TODO: Need to fix children here.
|
||||
|
||||
this->gridChildren.clear();
|
||||
this->updatePositions();
|
||||
}
|
||||
|
||||
void UIGrid::addToGrid(
|
||||
UIComponent *ui,
|
||||
int32_t x, int32_t y,
|
||||
enum UIComponentAlign alignX, enum UIComponentAlign alignY
|
||||
) {
|
||||
assertTrue(x >= 0 && x < this->columns);
|
||||
assertTrue(y >= 0 && y < this->rows);
|
||||
this->addChild(ui);
|
||||
struct UIGridPosition pos;
|
||||
pos.x = x;
|
||||
pos.y = y;
|
||||
pos.alignX = alignX;
|
||||
pos.alignY = alignY;
|
||||
this->gridChildren[ui] = pos;
|
||||
this->alignChild(ui, pos);
|
||||
|
||||
// Re-Add event listener
|
||||
ui->eventAlignmentUpdated.addListener(this, &UIGrid::onChildAligned);
|
||||
}
|
||||
|
||||
int32_t UIGrid::getRows() {
|
||||
return this->rows;
|
||||
}
|
||||
|
||||
int32_t UIGrid::getColumns() {
|
||||
return this->columns;
|
||||
}
|
||||
|
||||
void UIGrid::removeChild(UIComponent *component) {
|
||||
UIComponent::removeChild(component);
|
||||
assertUnreachable();
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIGrid.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UIGrid::UIGrid(UICanvas *canvas) : UIComponent(canvas) {
|
||||
|
||||
}
|
||||
|
||||
void UIGrid::updatePositions() {
|
||||
UIComponent::updatePositions();
|
||||
|
||||
this->sizeCol = (
|
||||
this->width - (this->gutterX * (this->columns - 1))
|
||||
) / this->columns;
|
||||
this->sizeRow = (
|
||||
this->height - (this->gutterY * (this->rows - 1))
|
||||
) / this->rows;
|
||||
|
||||
auto it = this->gridChildren.begin();
|
||||
while(it != this->gridChildren.end()) {
|
||||
this->alignChild(it->first, it->second);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> UIGrid::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
return std::vector<struct ShaderPassItem>();
|
||||
}
|
||||
|
||||
void UIGrid::onChildAligned(UIComponent *child) {
|
||||
if(this->alignmentListenerLocked) return;
|
||||
assertNotNull(child);
|
||||
assertMapHasKey(this->gridChildren, child);
|
||||
this->alignmentListenerLocked = true;
|
||||
this->alignChild(child, this->gridChildren[child]);
|
||||
this->alignmentListenerLocked = false;
|
||||
}
|
||||
|
||||
void UIGrid::alignChild(UIComponent *child, struct UIGridPosition pos) {
|
||||
assertNotNull(child);
|
||||
|
||||
float_t gridX = (this->sizeCol * pos.x) + (this->gutterX * pos.x);
|
||||
float_t gridY = (this->sizeRow * pos.y) + (this->gutterY * pos.y);
|
||||
|
||||
// Hack for when content width is undefined.
|
||||
child->width = this->sizeCol;
|
||||
child->height = this->sizeRow;
|
||||
|
||||
// Alignment
|
||||
float_t x, y, sizeX, sizeY;
|
||||
UIComponent::calculateDimensions(
|
||||
pos.alignX,
|
||||
&x,
|
||||
&sizeX,
|
||||
this->sizeCol,
|
||||
child->getContentWidth(),
|
||||
glm::vec2(0, 0)
|
||||
);
|
||||
UIComponent::calculateDimensions(
|
||||
pos.alignY,
|
||||
&y,
|
||||
&sizeY,
|
||||
this->sizeRow,
|
||||
child->getContentHeight(),
|
||||
glm::vec2(0, 0)
|
||||
);
|
||||
|
||||
child->setTransform(
|
||||
UI_COMPONENT_ALIGN_START, UI_COMPONENT_ALIGN_START,
|
||||
glm::vec4(gridX + x, gridY + y, sizeX, sizeY),
|
||||
0.0f
|
||||
);
|
||||
}
|
||||
|
||||
void UIGrid::setGridSize(
|
||||
int32_t columns, int32_t rows,
|
||||
float_t gutterX, float_t gutterY
|
||||
) {
|
||||
this->rows = rows;
|
||||
this->columns = columns;
|
||||
this->gutterX = gutterX;
|
||||
this->gutterY = gutterY;
|
||||
|
||||
// TODO: Need to fix children here.
|
||||
|
||||
this->gridChildren.clear();
|
||||
this->updatePositions();
|
||||
}
|
||||
|
||||
void UIGrid::addToGrid(
|
||||
UIComponent *ui,
|
||||
int32_t x, int32_t y,
|
||||
enum UIComponentAlign alignX, enum UIComponentAlign alignY
|
||||
) {
|
||||
assertTrue(x >= 0 && x < this->columns);
|
||||
assertTrue(y >= 0 && y < this->rows);
|
||||
this->addChild(ui);
|
||||
struct UIGridPosition pos;
|
||||
pos.x = x;
|
||||
pos.y = y;
|
||||
pos.alignX = alignX;
|
||||
pos.alignY = alignY;
|
||||
this->gridChildren[ui] = pos;
|
||||
this->alignChild(ui, pos);
|
||||
|
||||
// Re-Add event listener
|
||||
ui->eventAlignmentUpdated.addListener(this, &UIGrid::onChildAligned);
|
||||
}
|
||||
|
||||
int32_t UIGrid::getRows() {
|
||||
return this->rows;
|
||||
}
|
||||
|
||||
int32_t UIGrid::getColumns() {
|
||||
return this->columns;
|
||||
}
|
||||
|
||||
void UIGrid::removeChild(UIComponent *component) {
|
||||
UIComponent::removeChild(component);
|
||||
assertUnreachable();
|
||||
}
|
@ -1,83 +1,83 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "UIComponent.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct UIGridPosition {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
enum UIComponentAlign alignX;
|
||||
enum UIComponentAlign alignY;
|
||||
};
|
||||
|
||||
|
||||
class UIGrid : public UIComponent {
|
||||
private:
|
||||
int32_t rows = 1;
|
||||
int32_t columns = 1;
|
||||
float_t gutterX = 0;
|
||||
float_t gutterY = 0;
|
||||
float_t sizeRow, sizeCol;
|
||||
std::map<UIComponent*, struct UIGridPosition> gridChildren;
|
||||
bool_t alignmentListenerLocked = false;
|
||||
|
||||
/**
|
||||
* Internal method to update the alignment of a child.
|
||||
*
|
||||
* @param child Child UI component.
|
||||
* @param pos Positional information of the child UI item..
|
||||
*/
|
||||
void alignChild(UIComponent *child, struct UIGridPosition pos);
|
||||
|
||||
void onChildAligned(UIComponent *child);
|
||||
|
||||
protected:
|
||||
void updatePositions() override;
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
public:
|
||||
UIGrid(UICanvas *canvas);
|
||||
|
||||
/**
|
||||
* Sets the dimensions of the grid.
|
||||
*
|
||||
* @param columns Count of columns in the grid.
|
||||
* @param rows Count of rows in the grid.
|
||||
* @param gutterX Gutter spacing between the cells of the grid.
|
||||
* @param gutterY Gutter spacing between the cells of the grid.
|
||||
*/
|
||||
void setGridSize(
|
||||
int32_t columns, int32_t rows,
|
||||
float_t gutterX, float_t gutterY
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds a UI component to the grid.
|
||||
*
|
||||
* @param component Component to add to the grid.
|
||||
* @param column Column Position.
|
||||
* @param row Row Position.
|
||||
* @param alignX X alignment of the component within the cell.
|
||||
* @param alignY Y alignment of the component within the cell.
|
||||
*/
|
||||
void addToGrid(
|
||||
UIComponent *ui,
|
||||
int32_t x, int32_t y,
|
||||
enum UIComponentAlign alignX, enum UIComponentAlign alignY
|
||||
);
|
||||
|
||||
int32_t getRows();
|
||||
int32_t getColumns();
|
||||
|
||||
void removeChild(UIComponent *component) override;
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "UIComponent.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct UIGridPosition {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
enum UIComponentAlign alignX;
|
||||
enum UIComponentAlign alignY;
|
||||
};
|
||||
|
||||
|
||||
class UIGrid : public UIComponent {
|
||||
private:
|
||||
int32_t rows = 1;
|
||||
int32_t columns = 1;
|
||||
float_t gutterX = 0;
|
||||
float_t gutterY = 0;
|
||||
float_t sizeRow, sizeCol;
|
||||
std::map<UIComponent*, struct UIGridPosition> gridChildren;
|
||||
bool_t alignmentListenerLocked = false;
|
||||
|
||||
/**
|
||||
* Internal method to update the alignment of a child.
|
||||
*
|
||||
* @param child Child UI component.
|
||||
* @param pos Positional information of the child UI item..
|
||||
*/
|
||||
void alignChild(UIComponent *child, struct UIGridPosition pos);
|
||||
|
||||
void onChildAligned(UIComponent *child);
|
||||
|
||||
protected:
|
||||
void updatePositions() override;
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
public:
|
||||
UIGrid(UICanvas *canvas);
|
||||
|
||||
/**
|
||||
* Sets the dimensions of the grid.
|
||||
*
|
||||
* @param columns Count of columns in the grid.
|
||||
* @param rows Count of rows in the grid.
|
||||
* @param gutterX Gutter spacing between the cells of the grid.
|
||||
* @param gutterY Gutter spacing between the cells of the grid.
|
||||
*/
|
||||
void setGridSize(
|
||||
int32_t columns, int32_t rows,
|
||||
float_t gutterX, float_t gutterY
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds a UI component to the grid.
|
||||
*
|
||||
* @param component Component to add to the grid.
|
||||
* @param column Column Position.
|
||||
* @param row Row Position.
|
||||
* @param alignX X alignment of the component within the cell.
|
||||
* @param alignY Y alignment of the component within the cell.
|
||||
*/
|
||||
void addToGrid(
|
||||
UIComponent *ui,
|
||||
int32_t x, int32_t y,
|
||||
enum UIComponentAlign alignX, enum UIComponentAlign alignY
|
||||
);
|
||||
|
||||
int32_t getRows();
|
||||
int32_t getColumns();
|
||||
|
||||
void removeChild(UIComponent *component) override;
|
||||
};
|
||||
}
|
@ -1,125 +1,125 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "event/Event.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
#include "util/memory.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIMenuItem {
|
||||
public:
|
||||
/**
|
||||
* Called when the item is selected (Accepted) on.
|
||||
*/
|
||||
virtual void onItemSelected() = 0;
|
||||
|
||||
/**
|
||||
* Called when either the mouse or the user controller input is removed
|
||||
* off this item.
|
||||
*/
|
||||
virtual void onItemOver() = 0;
|
||||
|
||||
/**
|
||||
* Called when either the mouth or the user controller input is put over
|
||||
* this item.
|
||||
*/
|
||||
virtual void onItemOff() = 0;
|
||||
|
||||
/**
|
||||
* Returns whether the UI item can be hovered overed or not.
|
||||
* @return Whether it can be overed or not.
|
||||
*/
|
||||
virtual bool_t canBeOvered() = 0;
|
||||
|
||||
/**
|
||||
* Returns whether or not the item can be selected or not.
|
||||
* @return Whether it can be selected or not.
|
||||
*/
|
||||
virtual bool_t canBeSelected() = 0;
|
||||
};
|
||||
|
||||
struct UIMenu {
|
||||
private:
|
||||
UICanvas *canvas;
|
||||
int32_t x = -1;
|
||||
int32_t y = -1;
|
||||
int32_t rows = 1;
|
||||
int32_t columns = 1;
|
||||
UIMenuItem **items = nullptr;
|
||||
|
||||
protected:
|
||||
/** Invoked by UICanvas when this menu has been made inactive. */
|
||||
void onInactive();
|
||||
/** Invoked by UICanvas when this menu has been made active. */
|
||||
void onActive();
|
||||
/** Invoked by UICanvas every tick this menu is active. */
|
||||
void onTick();
|
||||
|
||||
public:
|
||||
Event<> eventMenuActive;
|
||||
Event<> eventMenuInactive;
|
||||
Event<int32_t, int32_t, int32_t, int32_t> eventCursorChange;
|
||||
Event<UIMenuItem*> eventItemSelected;
|
||||
|
||||
/**
|
||||
* Construct a new UI Menu Host.
|
||||
*
|
||||
* @param canvas Canvas that this menu belongs to.
|
||||
* @param columns Iniitial size of the menu X axis.
|
||||
* @param rows Initial size of the menu Y axis.
|
||||
*/
|
||||
UIMenu(UICanvas *canvas, int32_t columns, int32_t rows);
|
||||
|
||||
/**
|
||||
* Sets the size of the UI Menu.
|
||||
*
|
||||
* @param columns How many columns in the menu.
|
||||
* @param rows How many rows in the menu.
|
||||
*/
|
||||
void setSize(int32_t columns, int32_t rows);
|
||||
|
||||
/**
|
||||
* Returns the UI Item at the given position.
|
||||
*
|
||||
* @param x X coordinate of the item to get.
|
||||
* @param y Y coordinate of the item to get.
|
||||
* @return The pointer to the menu item, or null if invalid.
|
||||
*/
|
||||
UIMenuItem * getItem(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Sets the position of the cursor in the grid.
|
||||
*
|
||||
* @param x X position of the cursor.
|
||||
* @param y Y position of the cursor.
|
||||
*/
|
||||
void setPosition(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Move the cursor relative to the current position.
|
||||
*
|
||||
* @param x X position to move relative.
|
||||
* @param y Y position to move relative.
|
||||
*/
|
||||
void moveRelative(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Adds/Sets an item onto the menu.
|
||||
*
|
||||
* @param x X coordinate to set the item.
|
||||
* @param y Y coordinate to set the item.
|
||||
* @param item Item to set.
|
||||
*/
|
||||
void setItem(int32_t x, int32_t y, UIMenuItem *item);
|
||||
|
||||
/**
|
||||
* Cleans up the menu items, doesn't free the children themselves.
|
||||
*/
|
||||
~UIMenu();
|
||||
|
||||
friend class UICanvas;
|
||||
};
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "event/Event.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
#include "util/memory.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIMenuItem {
|
||||
public:
|
||||
/**
|
||||
* Called when the item is selected (Accepted) on.
|
||||
*/
|
||||
virtual void onItemSelected() = 0;
|
||||
|
||||
/**
|
||||
* Called when either the mouse or the user controller input is removed
|
||||
* off this item.
|
||||
*/
|
||||
virtual void onItemOver() = 0;
|
||||
|
||||
/**
|
||||
* Called when either the mouth or the user controller input is put over
|
||||
* this item.
|
||||
*/
|
||||
virtual void onItemOff() = 0;
|
||||
|
||||
/**
|
||||
* Returns whether the UI item can be hovered overed or not.
|
||||
* @return Whether it can be overed or not.
|
||||
*/
|
||||
virtual bool_t canBeOvered() = 0;
|
||||
|
||||
/**
|
||||
* Returns whether or not the item can be selected or not.
|
||||
* @return Whether it can be selected or not.
|
||||
*/
|
||||
virtual bool_t canBeSelected() = 0;
|
||||
};
|
||||
|
||||
struct UIMenu {
|
||||
private:
|
||||
UICanvas *canvas;
|
||||
int32_t x = -1;
|
||||
int32_t y = -1;
|
||||
int32_t rows = 1;
|
||||
int32_t columns = 1;
|
||||
UIMenuItem **items = nullptr;
|
||||
|
||||
protected:
|
||||
/** Invoked by UICanvas when this menu has been made inactive. */
|
||||
void onInactive();
|
||||
/** Invoked by UICanvas when this menu has been made active. */
|
||||
void onActive();
|
||||
/** Invoked by UICanvas every tick this menu is active. */
|
||||
void onTick();
|
||||
|
||||
public:
|
||||
Event<> eventMenuActive;
|
||||
Event<> eventMenuInactive;
|
||||
Event<int32_t, int32_t, int32_t, int32_t> eventCursorChange;
|
||||
Event<UIMenuItem*> eventItemSelected;
|
||||
|
||||
/**
|
||||
* Construct a new UI Menu Host.
|
||||
*
|
||||
* @param canvas Canvas that this menu belongs to.
|
||||
* @param columns Iniitial size of the menu X axis.
|
||||
* @param rows Initial size of the menu Y axis.
|
||||
*/
|
||||
UIMenu(UICanvas *canvas, int32_t columns, int32_t rows);
|
||||
|
||||
/**
|
||||
* Sets the size of the UI Menu.
|
||||
*
|
||||
* @param columns How many columns in the menu.
|
||||
* @param rows How many rows in the menu.
|
||||
*/
|
||||
void setSize(int32_t columns, int32_t rows);
|
||||
|
||||
/**
|
||||
* Returns the UI Item at the given position.
|
||||
*
|
||||
* @param x X coordinate of the item to get.
|
||||
* @param y Y coordinate of the item to get.
|
||||
* @return The pointer to the menu item, or null if invalid.
|
||||
*/
|
||||
UIMenuItem * getItem(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Sets the position of the cursor in the grid.
|
||||
*
|
||||
* @param x X position of the cursor.
|
||||
* @param y Y position of the cursor.
|
||||
*/
|
||||
void setPosition(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Move the cursor relative to the current position.
|
||||
*
|
||||
* @param x X position to move relative.
|
||||
* @param y Y position to move relative.
|
||||
*/
|
||||
void moveRelative(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Adds/Sets an item onto the menu.
|
||||
*
|
||||
* @param x X coordinate to set the item.
|
||||
* @param y Y coordinate to set the item.
|
||||
* @param item Item to set.
|
||||
*/
|
||||
void setItem(int32_t x, int32_t y, UIMenuItem *item);
|
||||
|
||||
/**
|
||||
* Cleans up the menu items, doesn't free the children themselves.
|
||||
*/
|
||||
~UIMenu();
|
||||
|
||||
friend class UICanvas;
|
||||
};
|
||||
}
|
@ -35,7 +35,6 @@ add_subdirectory(save)
|
||||
add_subdirectory(scene)
|
||||
add_subdirectory(state)
|
||||
add_subdirectory(time)
|
||||
add_subdirectory(ui)
|
||||
|
||||
if(DAWN_VISUAL_NOVEL)
|
||||
add_subdirectory(visualnovel)
|
||||
|
@ -153,14 +153,16 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
assertUnreachable();
|
||||
}
|
||||
|
||||
auto itChild = canvas->children.begin();
|
||||
while(itChild != canvas->children.end()) {
|
||||
vectorAppend(&shaderPassItems, (*itChild)->getPassItems(
|
||||
projection, view, model
|
||||
));
|
||||
++itChild;
|
||||
}
|
||||
++itCanvas;
|
||||
auto children = canvas->item.chil
|
||||
|
||||
// auto itChild = canvas->children.begin();
|
||||
// while(itChild != canvas->children.end()) {
|
||||
// vectorAppend(&shaderPassItems, (*itChild)->getPassItems(
|
||||
// projection, view, model
|
||||
// ));
|
||||
// ++itChild;
|
||||
// }
|
||||
// ++itCanvas;
|
||||
}
|
||||
|
||||
// Debug Lines
|
||||
|
@ -9,8 +9,7 @@
|
||||
#include "scene/components/display/MeshRenderer.hpp"
|
||||
#include "scene/components/display/Camera.hpp"
|
||||
#include "scene/components/scene/SubSceneController.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
|
||||
#include "scene/components/ui/UIComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class RenderManager;
|
||||
|
@ -4,9 +4,7 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UICanvas.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
#include "ui/UIMenu.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
@ -15,71 +13,11 @@ UICanvas * UICanvas::create(Scene *scene) {
|
||||
return item->addComponent<UICanvas>();
|
||||
}
|
||||
|
||||
UICanvas::UICanvas(SceneItem *item) :
|
||||
SceneItemComponent(item),
|
||||
camera(nullptr),
|
||||
currentMenu(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
float_t UICanvas::getWidth() {
|
||||
if(this->camera == nullptr) {
|
||||
return this->getGame()->renderManager.getBackBuffer()->getWidth();
|
||||
}
|
||||
return this->camera->getRenderTarget()->getWidth();
|
||||
}
|
||||
|
||||
float_t UICanvas::getHeight() {
|
||||
if(this->camera == nullptr) {
|
||||
return this->getGame()->renderManager.getBackBuffer()->getHeight();
|
||||
}
|
||||
return this->camera->getRenderTarget()->getHeight();
|
||||
}
|
||||
|
||||
void UICanvas::setCurrentMenu(struct UIMenu *menu) {
|
||||
UICanvas::UICanvas(SceneItem *item) : SceneItemComponent(item) {
|
||||
}
|
||||
|
||||
void UICanvas::onStart() {
|
||||
useEffectWithTeardown([&]{
|
||||
if(this->camera == nullptr) return evtCamResize = [&]{};
|
||||
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
(*it)->updatePositions();
|
||||
++it;
|
||||
}
|
||||
|
||||
return evtCamResize = useEvent([&](float_t w, float_t h){
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
(*it)->updatePositions();
|
||||
++it;
|
||||
}
|
||||
}, camera->eventRenderTargetResized);
|
||||
}, camera);
|
||||
|
||||
useEffectWithTeardown([&]{
|
||||
if(currentMenu != nullptr) currentMenu->onActive();
|
||||
|
||||
return [&] {
|
||||
if(currentMenu == nullptr) currentMenu->onInactive();
|
||||
};
|
||||
}, this->currentMenu);
|
||||
|
||||
// Scene Update
|
||||
useEvent([&](float_t delta){
|
||||
if(this->currentMenu == nullptr) return;
|
||||
this->currentMenu->onTick();
|
||||
}, getScene()->eventSceneUpdate);
|
||||
|
||||
// Find Camera if we need to.
|
||||
if(camera == nullptr) camera = this->getScene()->findComponent<Camera>();
|
||||
}
|
||||
|
||||
void UICanvas::onDispose() {
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
delete *it;
|
||||
++it;
|
||||
}
|
||||
}
|
@ -15,19 +15,8 @@ namespace Dawn {
|
||||
UI_DRAW_TYPE_CAMERA_OVERLAY
|
||||
};
|
||||
|
||||
class UIComponent;
|
||||
struct UIMenu;
|
||||
|
||||
class UICanvas : public SceneItemComponent {
|
||||
protected:
|
||||
std::function<void()> evtCamResize;
|
||||
|
||||
void onRenderTargetResize(float_t w, float_t h);
|
||||
|
||||
public:
|
||||
StateProperty<struct UIMenu*> currentMenu;
|
||||
StateProperty<Camera*> camera;
|
||||
|
||||
/**
|
||||
* Creates a UI Canvas Scene Item Element, and attaches it to the provided
|
||||
* scene.
|
||||
@ -38,8 +27,8 @@ namespace Dawn {
|
||||
static UICanvas * create(Scene *scene);
|
||||
|
||||
//======================================================================//
|
||||
std::vector<UIComponent*> children;
|
||||
UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE;
|
||||
|
||||
enum UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE;
|
||||
|
||||
/**
|
||||
* Constructs the UI Canvas Scene Item Component.
|
||||
@ -48,65 +37,6 @@ namespace Dawn {
|
||||
*/
|
||||
UICanvas(SceneItem *item);
|
||||
|
||||
/**
|
||||
* Construct and append a UI item to this UI Canvas.
|
||||
*
|
||||
* @tparam Type of the UI Item.
|
||||
* @return Pointer to the created UI Item.
|
||||
*/
|
||||
template<class T>
|
||||
T * addElement() {
|
||||
auto item = new T(this);
|
||||
this->children.push_back(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a UI Element attached to this canvas.
|
||||
*
|
||||
* @tparam Type of the UI item to find.
|
||||
* @return Pointer to first matching element of type T.
|
||||
*/
|
||||
template<class T>
|
||||
T * findElement() {
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
auto castedAs = dynamic_cast<T*>(*it);
|
||||
if(castedAs != nullptr) return castedAs;
|
||||
++it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of the root UI Canvas size. In future I may allow
|
||||
* this to be dynamic, right now it uses the render canvas however.
|
||||
*
|
||||
* @return Width of the UI Canvas.
|
||||
*/
|
||||
float_t getWidth();
|
||||
|
||||
/**
|
||||
* Returns the height of this UI Canvas element.
|
||||
*
|
||||
* @return Height of the UI Canvas.
|
||||
*/
|
||||
float_t getHeight();
|
||||
|
||||
/**
|
||||
* Returns the currently active menu for this UI Canvas.
|
||||
*
|
||||
* @return The currently active menu, or nullptr if there is none.
|
||||
*/
|
||||
struct UIMenu * getCurrentMenu();
|
||||
|
||||
/**
|
||||
* Sets the currently active menu, and ticks it appropriately.
|
||||
*
|
||||
* @param menu Menu to set as the current active menu.
|
||||
*/
|
||||
void setCurrentMenu(struct UIMenu *menu);
|
||||
|
||||
void onStart() override;
|
||||
void onDispose() override;
|
||||
};
|
||||
|
12
src/dawn/scene/components/ui/UIComponent.cpp
Normal file
12
src/dawn/scene/components/ui/UIComponent.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIComponent.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UIComponent::UIComponent(SceneItem *item) : SceneItemComponent(item) {
|
||||
|
||||
}
|
20
src/dawn/scene/components/ui/UIComponent.hpp
Normal file
20
src/dawn/scene/components/ui/UIComponent.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "UICanvas.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIComponent : public SceneItemComponent {
|
||||
private:
|
||||
UICanvas *canvas = nullptr;
|
||||
|
||||
public:
|
||||
UIComponent(SceneItem *item);
|
||||
|
||||
friend class UICanvas;
|
||||
};
|
||||
}
|
49
src/dawn/scene/components/ui/UILabel.cpp
Normal file
49
src/dawn/scene/components/ui/UILabel.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UILabel.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UILabel::UILabel(SceneItem *item) :
|
||||
UIComponent(item),
|
||||
text(""),
|
||||
fontSize(10.0f),
|
||||
font(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void UILabel::updateMesh() {
|
||||
if(!this->needsRebuffering || !this->hasText) return;
|
||||
if(((Font*)this->font) == nullptr || !this->font->isReady()) return;
|
||||
|
||||
// float_t width = this->width;
|
||||
// if(width == 0) width = -1;
|
||||
|
||||
// std::string text = this->getGame()->localeManager.getString(key);
|
||||
this->font->buffer(
|
||||
this->text,
|
||||
this->fontSize,
|
||||
-1,
|
||||
&this->mesh,
|
||||
&this->measure
|
||||
);
|
||||
this->needsRebuffering = false;
|
||||
}
|
||||
|
||||
void UILabel::onStart() {
|
||||
useEffect([&]{
|
||||
hasText = ((std::string)text).size() > 0;
|
||||
needsRebuffering = true;
|
||||
}, text);
|
||||
|
||||
useEffect([&]{
|
||||
needsRebuffering = true;
|
||||
}, fontSize);
|
||||
|
||||
useEffect([&]{
|
||||
needsRebuffering = true;
|
||||
}, font);
|
||||
}
|
32
src/dawn/scene/components/ui/UILabel.hpp
Normal file
32
src/dawn/scene/components/ui/UILabel.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "UIComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UILabel : public UIComponent {
|
||||
private:
|
||||
bool_t needsRebuffering = true;
|
||||
bool_t hasText = false;
|
||||
|
||||
Mesh mesh;
|
||||
|
||||
void updateMesh();
|
||||
|
||||
public:
|
||||
StateProperty<std::string> text;
|
||||
StateProperty<float_t> fontSize;
|
||||
StateProperty<Font*> font;
|
||||
struct Color textColor = COLOR_MAGENTA;
|
||||
struct FontMeasure measure;
|
||||
int32_t startQuad = 0;
|
||||
int32_t quadCount = -1;
|
||||
|
||||
UILabel(SceneItem *item);
|
||||
|
||||
void onStart() override;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user