294 lines
7.6 KiB
C++
294 lines
7.6 KiB
C++
#pragma once
|
|
|
|
#include <XCEngine/UI/Types.h>
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace XCEngine {
|
|
namespace UI {
|
|
|
|
struct UIColor {
|
|
float r = 1.0f;
|
|
float g = 1.0f;
|
|
float b = 1.0f;
|
|
float a = 1.0f;
|
|
|
|
constexpr UIColor() = default;
|
|
constexpr UIColor(float red, float green, float blue, float alpha = 1.0f)
|
|
: r(red)
|
|
, g(green)
|
|
, b(blue)
|
|
, a(alpha) {
|
|
}
|
|
};
|
|
|
|
enum class UIDrawCommandType : std::uint8_t {
|
|
FilledRect = 0,
|
|
RectOutline,
|
|
FilledRectLinearGradient,
|
|
Line,
|
|
FilledTriangle,
|
|
FilledCircle,
|
|
CircleOutline,
|
|
Text,
|
|
Image,
|
|
PushClipRect,
|
|
PopClipRect
|
|
};
|
|
|
|
enum class UILinearGradientDirection : std::uint8_t {
|
|
Horizontal = 0,
|
|
Vertical
|
|
};
|
|
|
|
struct UIDrawCommand {
|
|
UIDrawCommandType type = UIDrawCommandType::FilledRect;
|
|
UIRect rect = {};
|
|
UIPoint position = {};
|
|
UIPoint uvMin = {};
|
|
UIPoint uvMax = UIPoint(1.0f, 1.0f);
|
|
UIColor color = {};
|
|
UIColor secondaryColor = {};
|
|
float thickness = 1.0f;
|
|
float rounding = 0.0f;
|
|
float radius = 0.0f;
|
|
float fontSize = 0.0f;
|
|
bool intersectWithCurrentClip = true;
|
|
UILinearGradientDirection gradientDirection = UILinearGradientDirection::Horizontal;
|
|
UITextureHandle texture = {};
|
|
std::string text;
|
|
};
|
|
|
|
class UIDrawList {
|
|
public:
|
|
UIDrawList() = default;
|
|
explicit UIDrawList(std::string debugName)
|
|
: m_debugName(std::move(debugName)) {
|
|
}
|
|
|
|
const std::string& GetDebugName() const {
|
|
return m_debugName;
|
|
}
|
|
|
|
void SetDebugName(std::string debugName) {
|
|
m_debugName = std::move(debugName);
|
|
}
|
|
|
|
void Clear() {
|
|
m_commands.clear();
|
|
}
|
|
|
|
bool Empty() const {
|
|
return m_commands.empty();
|
|
}
|
|
|
|
std::size_t GetCommandCount() const {
|
|
return m_commands.size();
|
|
}
|
|
|
|
const std::vector<UIDrawCommand>& GetCommands() const {
|
|
return m_commands;
|
|
}
|
|
|
|
UIDrawCommand& AddFilledRect(
|
|
const UIRect& rect,
|
|
const UIColor& color,
|
|
float rounding = 0.0f) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::FilledRect;
|
|
command.rect = rect;
|
|
command.color = color;
|
|
command.rounding = rounding;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& AddRectOutline(
|
|
const UIRect& rect,
|
|
const UIColor& color,
|
|
float thickness = 1.0f,
|
|
float rounding = 0.0f) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::RectOutline;
|
|
command.rect = rect;
|
|
command.color = color;
|
|
command.thickness = thickness;
|
|
command.rounding = rounding;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& AddFilledRectLinearGradient(
|
|
const UIRect& rect,
|
|
const UIColor& startColor,
|
|
const UIColor& endColor,
|
|
UILinearGradientDirection direction = UILinearGradientDirection::Horizontal,
|
|
float rounding = 0.0f) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::FilledRectLinearGradient;
|
|
command.rect = rect;
|
|
command.color = startColor;
|
|
command.secondaryColor = endColor;
|
|
command.rounding = rounding;
|
|
command.gradientDirection = direction;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& AddLine(
|
|
const UIPoint& start,
|
|
const UIPoint& end,
|
|
const UIColor& color,
|
|
float thickness = 1.0f) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::Line;
|
|
command.position = start;
|
|
command.uvMin = end;
|
|
command.color = color;
|
|
command.thickness = thickness;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& AddFilledTriangle(
|
|
const UIPoint& a,
|
|
const UIPoint& b,
|
|
const UIPoint& c,
|
|
const UIColor& color) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::FilledTriangle;
|
|
command.position = a;
|
|
command.uvMin = b;
|
|
command.uvMax = c;
|
|
command.color = color;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& AddFilledCircle(
|
|
const UIPoint& center,
|
|
float radius,
|
|
const UIColor& color) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::FilledCircle;
|
|
command.position = center;
|
|
command.radius = radius;
|
|
command.color = color;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& AddCircleOutline(
|
|
const UIPoint& center,
|
|
float radius,
|
|
const UIColor& color,
|
|
float thickness = 1.0f) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::CircleOutline;
|
|
command.position = center;
|
|
command.radius = radius;
|
|
command.color = color;
|
|
command.thickness = thickness;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& AddText(
|
|
const UIPoint& position,
|
|
std::string text,
|
|
const UIColor& color = {},
|
|
float fontSize = 0.0f) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::Text;
|
|
command.position = position;
|
|
command.color = color;
|
|
command.fontSize = fontSize;
|
|
command.text = std::move(text);
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& AddImage(
|
|
const UIRect& rect,
|
|
const UITextureHandle& texture,
|
|
const UIColor& tintColor = {},
|
|
const UIPoint& uvMin = {},
|
|
const UIPoint& uvMax = UIPoint(1.0f, 1.0f)) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::Image;
|
|
command.rect = rect;
|
|
command.texture = texture;
|
|
command.color = tintColor;
|
|
command.uvMin = uvMin;
|
|
command.uvMax = uvMax;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& PushClipRect(
|
|
const UIRect& rect,
|
|
bool intersectWithCurrentClip = true) {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::PushClipRect;
|
|
command.rect = rect;
|
|
command.intersectWithCurrentClip = intersectWithCurrentClip;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
UIDrawCommand& PopClipRect() {
|
|
UIDrawCommand command = {};
|
|
command.type = UIDrawCommandType::PopClipRect;
|
|
return AddCommand(std::move(command));
|
|
}
|
|
|
|
private:
|
|
UIDrawCommand& AddCommand(UIDrawCommand&& command) {
|
|
m_commands.push_back(std::move(command));
|
|
return m_commands.back();
|
|
}
|
|
|
|
std::string m_debugName;
|
|
std::vector<UIDrawCommand> m_commands;
|
|
};
|
|
|
|
class UIDrawData {
|
|
public:
|
|
void Clear() {
|
|
m_drawLists.clear();
|
|
}
|
|
|
|
bool Empty() const {
|
|
return m_drawLists.empty();
|
|
}
|
|
|
|
std::size_t GetDrawListCount() const {
|
|
return m_drawLists.size();
|
|
}
|
|
|
|
std::size_t GetTotalCommandCount() const {
|
|
std::size_t count = 0;
|
|
for (const UIDrawList& drawList : m_drawLists) {
|
|
count += drawList.GetCommandCount();
|
|
}
|
|
return count;
|
|
}
|
|
|
|
const std::vector<UIDrawList>& GetDrawLists() const {
|
|
return m_drawLists;
|
|
}
|
|
|
|
UIDrawList& EmplaceDrawList(std::string debugName = {}) {
|
|
m_drawLists.emplace_back(std::move(debugName));
|
|
return m_drawLists.back();
|
|
}
|
|
|
|
void AddDrawList(const UIDrawList& drawList) {
|
|
m_drawLists.push_back(drawList);
|
|
}
|
|
|
|
void AddDrawList(UIDrawList&& drawList) {
|
|
m_drawLists.push_back(std::move(drawList));
|
|
}
|
|
|
|
private:
|
|
std::vector<UIDrawList> m_drawLists;
|
|
};
|
|
|
|
} // namespace UI
|
|
} // namespace XCEngine
|