Files
XCEngine/engine/include/XCEngine/UI/DrawData.h

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