Yoga layout working
This commit is contained in:
@@ -12,6 +12,7 @@ void Logger::Log(std::string log)
|
||||
time_t now = time(0);
|
||||
strftime(buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime(&now));
|
||||
std::string msg = "["+ std::string(buff) + "]" + std::string(" - ") + log;
|
||||
printf((msg + "\n").c_str());
|
||||
logs.push_back(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
enum LOG_TYPE
|
||||
{
|
||||
VERBOSE,
|
||||
DEBUG,
|
||||
WARNING,
|
||||
CRITICAL
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "Renderer2D.h"
|
||||
#include "GL/glew.h"
|
||||
|
||||
#include "../Core/Maths.h"
|
||||
Ref<Shader> Renderer2D::UIShader;
|
||||
unsigned int Renderer2D::VAO;
|
||||
unsigned int Renderer2D::VBO;
|
||||
@@ -10,7 +10,7 @@ Matrix4 Renderer2D::Projection;
|
||||
void Renderer2D::Init()
|
||||
{
|
||||
UIShader = CreateRef<Shader>("resources/Shaders/ui.shader");
|
||||
Projection = glm::ortho(0.f, 1920.f, 0.0f, 1080.f, -0.5f, 100.0f);
|
||||
Projection = glm::ortho(0.f, 1920.f, 1080.f, 0.f, -0.5f, 100.0f);
|
||||
|
||||
float quad_Vertices[] = {
|
||||
// positions // texture Coords
|
||||
@@ -35,8 +35,10 @@ void Renderer2D::Init()
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
}
|
||||
|
||||
void Renderer2D::BeginDraw()
|
||||
void Renderer2D::BeginDraw(Vector2 size)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
Projection = glm::ortho(0.f, size.x, size.y, 0.f, -0.5f, 1000.0f);
|
||||
UIShader->Bind();
|
||||
UIShader->SetUniformMat4f("projection", Projection);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public:
|
||||
static Matrix4 Projection;
|
||||
|
||||
static void Init();
|
||||
static void BeginDraw();
|
||||
static void BeginDraw(Vector2 size);
|
||||
static void DrawRect();
|
||||
static void EndDraw();
|
||||
};
|
||||
@@ -143,12 +143,20 @@ void Scene::Update(Timestep ts)
|
||||
auto [transform, rb] = ccGroup.get<TransformComponent, CharacterControllerComponent>(e);
|
||||
rb.SyncWithTransform(m_Registry.get<TransformComponent>(e));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Scene::EditorUpdate(Timestep ts)
|
||||
{
|
||||
m_EditorCamera->Update(ts);
|
||||
|
||||
for (auto i : m_Interfaces)
|
||||
{
|
||||
//i->Calculate(1280,720);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +217,14 @@ void Scene::DrawShadows()
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::DrawInterface(Vector2 screensize)
|
||||
{
|
||||
for (auto i : m_Interfaces)
|
||||
{
|
||||
i->Draw(screensize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Scene::Draw()
|
||||
{
|
||||
@@ -339,10 +355,7 @@ void Scene::Draw()
|
||||
PhysicsManager::Get()->DrawDebug();
|
||||
}
|
||||
|
||||
for (auto i : m_Interfaces)
|
||||
{
|
||||
i->Draw();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Scene::EditorDraw()
|
||||
@@ -355,10 +368,7 @@ void Scene::EditorDraw()
|
||||
// env->ProceduralSkybox->Draw(m_EditorCamera);
|
||||
//}
|
||||
|
||||
for (auto i : m_Interfaces)
|
||||
{
|
||||
i->Draw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -510,10 +520,7 @@ void Scene::EditorDraw()
|
||||
}
|
||||
}*/
|
||||
|
||||
for (auto i : m_Interfaces)
|
||||
{
|
||||
i->Draw();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<Entity> Scene::GetAllEntities() {
|
||||
@@ -619,6 +626,12 @@ bool Scene::SaveAs(const std::string& path)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scene::ReloadInterfaces()
|
||||
{
|
||||
for (auto& i : m_Interfaces)
|
||||
i->Reload();
|
||||
}
|
||||
|
||||
void Scene::AddInterface(Ref<UI::UserInterface> interface)
|
||||
{
|
||||
this->m_Interfaces.push_back(interface);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "EditorCamera.h"
|
||||
#include "../Resource/Serializable.h"
|
||||
#include "src/UI/UserInterface.h"
|
||||
|
||||
#include "../Core/Maths.h"
|
||||
class Entity;
|
||||
class Scene : public ISerializable
|
||||
{
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
|
||||
// TODO: Maybe move this to Renderer::DrawScene() ?
|
||||
void DrawShadows();
|
||||
void DrawInterface(Vector2 screensize);
|
||||
void Draw();
|
||||
void EditorDraw();
|
||||
|
||||
@@ -64,6 +65,7 @@ public:
|
||||
bool Save();
|
||||
bool SaveAs(const std::string& path);
|
||||
|
||||
void ReloadInterfaces();
|
||||
void AddInterface(Ref<UI::UserInterface> interface);
|
||||
|
||||
json Serialize() override;
|
||||
|
||||
@@ -1,6 +1,223 @@
|
||||
#pragma once
|
||||
#include <src/Vendors/pugixml/pugixml.hpp>
|
||||
#include <iostream>
|
||||
#include <src/UI/Canvas.h>
|
||||
#include <src/UI/Rect.h>
|
||||
#include <regex>
|
||||
#include<iostream>
|
||||
#include <src/Core/Logger.h>
|
||||
|
||||
class InterfaceParser
|
||||
{
|
||||
static Ref<Canvas> Root;
|
||||
|
||||
private:
|
||||
|
||||
public:
|
||||
static Ref<Canvas> Parse(const std::string path)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_file(path.c_str());
|
||||
|
||||
std::string name = doc.first_child().name();
|
||||
if (name != "Canvas")
|
||||
{
|
||||
Logger::Log("InterfaceParser error: First child should be a canvas - " + path);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Root = CreateCanvas(doc.first_child());
|
||||
|
||||
Iterate(doc.first_child(), Root);
|
||||
return Root;
|
||||
}
|
||||
|
||||
static void Iterate(const pugi::xml_node& xml_node, Ref<Node> node)
|
||||
{
|
||||
for (auto& e : xml_node.children())
|
||||
{
|
||||
std::string type = e.name();
|
||||
if (type == "Canvas")
|
||||
{
|
||||
Ref<Canvas> canvas = CreateCanvas(e);
|
||||
node->Childrens.push_back(canvas);
|
||||
Iterate(e, canvas);
|
||||
}
|
||||
else if (type == "Rect")
|
||||
{
|
||||
Ref<Node> newNode = CreateNode(e);
|
||||
node->Childrens.push_back(newNode);
|
||||
Iterate(e, newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Ref<Node> CreateNode(const pugi::xml_node& xml_node)
|
||||
{
|
||||
Ref<Node> node = CreateRef<Node>();
|
||||
for (auto& a : xml_node.attributes())
|
||||
{
|
||||
std::string name = a.name();
|
||||
if (name == "height")
|
||||
node->Height = GetUnit(a.value());
|
||||
if (name == "width")
|
||||
node->Width = GetUnit(a.value());
|
||||
if (name == "margin")
|
||||
node->Margin = GetVec4Unit(a.value());
|
||||
if (name == "padding")
|
||||
node->Padding = GetVec4Unit(a.value());
|
||||
if (name == "border")
|
||||
node->Border = GetVec4Unit(a.value());
|
||||
if (name == "position")
|
||||
node->Position = GetVec4Unit(a.value());
|
||||
if (name == "color")
|
||||
node->BackgroundColor = GetColor(a.value());
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static Layout::LayoutUnit GetUnit(const std::string& value)
|
||||
{
|
||||
std::regex only_number("[0-9]+");
|
||||
std::regex not_number("[^0-9]+");
|
||||
|
||||
// is percentage
|
||||
std::smatch match_value;
|
||||
if (std::regex_search(value.begin(), value.end(), match_value, only_number))
|
||||
{
|
||||
std::smatch match_type;
|
||||
if (std::regex_search(value.begin(), value.end(), match_type, not_number))
|
||||
{
|
||||
float value = std::stof(match_value[0]);
|
||||
|
||||
if (match_type[0] == "%")
|
||||
{
|
||||
return Layout::LayoutUnit{
|
||||
value,
|
||||
Layout::Unit::PERCENT
|
||||
};
|
||||
}
|
||||
else if (match_type[0] == "px")
|
||||
{
|
||||
return Layout::LayoutUnit{
|
||||
value,
|
||||
Layout::Unit::PIXEL
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<std::string> split(std::string const& str, const char delim)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
size_t start;
|
||||
size_t end = 0;
|
||||
|
||||
while ((start = str.find_first_not_of(delim, end)) != std::string::npos)
|
||||
{
|
||||
end = str.find(delim, start);
|
||||
result.push_back(str.substr(start, end - start));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Layout::LayoutVec4 GetVec4Unit(const std::string& value)
|
||||
{
|
||||
std::regex regex("[0-9]+[^ ]+");
|
||||
std::smatch match_value;
|
||||
Layout::LayoutVec4 result;
|
||||
|
||||
std::vector<std::string> splits = split(value, ' ');
|
||||
int idx = 0;
|
||||
for (auto& s : splits)
|
||||
{
|
||||
if (std::regex_search(value.begin(), value.end(), match_value, regex))
|
||||
{
|
||||
if (idx == 0)
|
||||
{
|
||||
result.Left = GetUnit(s);
|
||||
}
|
||||
else if (idx == 1)
|
||||
{
|
||||
result.Right = GetUnit(s);
|
||||
}
|
||||
else if (idx == 2)
|
||||
{
|
||||
result.Top = GetUnit(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Bottom = GetUnit(s);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static Color GetColor(const std::string& value)
|
||||
{
|
||||
std::regex regex("[0-9]+[^ ]+");
|
||||
std::smatch match_value;
|
||||
Color result;
|
||||
|
||||
std::vector<std::string> splits = split(value, ' ');
|
||||
int idx = 0;
|
||||
for (auto& s : splits)
|
||||
{
|
||||
if (std::regex_search(value.begin(), value.end(), match_value, regex))
|
||||
{
|
||||
if (idx == 0)
|
||||
{
|
||||
result.r = std::stof(s);
|
||||
}
|
||||
else if (idx == 1)
|
||||
{
|
||||
result.g = std::stof(s);
|
||||
}
|
||||
else if (idx == 2)
|
||||
{
|
||||
result.b = std::stof(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.a = std::stof(s);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static Ref<Canvas> CreateCanvas(const pugi::xml_node& xml_node)
|
||||
{
|
||||
Ref<Canvas> node = CreateRef<Canvas>();
|
||||
for (auto& a : xml_node.attributes())
|
||||
{
|
||||
std::string name = a.name();
|
||||
if (name == "height")
|
||||
node->Height = GetUnit(a.value());
|
||||
if (name == "width")
|
||||
node->Width = GetUnit(a.value());
|
||||
if (name == "margin")
|
||||
node->Margin = GetVec4Unit(a.value());
|
||||
if (name == "padding")
|
||||
node->Padding = GetVec4Unit(a.value());
|
||||
if (name == "border")
|
||||
node->Border = GetVec4Unit(a.value());
|
||||
if (name == "position")
|
||||
node->Position = GetVec4Unit(a.value());
|
||||
if (name == "color")
|
||||
node->BackgroundColor = GetColor(a.value());
|
||||
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
}
|
||||
};
|
||||
@@ -12,9 +12,9 @@ Node::Node()
|
||||
FlexDirection = Layout::FlexDirection::ROW;
|
||||
FlexWrap = Layout::FlexWrap::WRAP;
|
||||
FlexGrow = 0.f;
|
||||
FlexShrink = 0.f;
|
||||
FlexBasis = 0.f;
|
||||
AspectRatio = 0.f;
|
||||
FlexShrink = 1.f;
|
||||
FlexBasis = 10.f;
|
||||
AspectRatio = 1.f;
|
||||
AlignItems = Layout::AlignItems::FLEX_START;
|
||||
SelfAlign = Layout::AlignItems::FLEX_START;
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "../Core/Core.h"
|
||||
#include "yoga/Yoga.h"
|
||||
#include "../Rendering/Renderer2D.h"
|
||||
#include "../Core/Logger.h"
|
||||
namespace Layout
|
||||
{
|
||||
enum class LayoutDirection
|
||||
{
|
||||
LTR, RTL
|
||||
LTR = 2, RTL = 3
|
||||
};
|
||||
|
||||
enum class FlexWrap
|
||||
@@ -35,7 +38,7 @@ namespace Layout
|
||||
|
||||
enum class PositionType
|
||||
{
|
||||
RELATIVE, ABSOLUTE
|
||||
STATIC, RELATIVE, ABSOLUTE
|
||||
};
|
||||
|
||||
enum Unit
|
||||
@@ -63,20 +66,25 @@ namespace Layout
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
std::vector<Ref<Node>> Childrens;
|
||||
Ref<Node*> Parent;
|
||||
YGNodeRef YogaNode;
|
||||
std::vector<Ref<Node>> Childrens = std::vector<Ref<Node>>();
|
||||
|
||||
Layout::PositionType PositionType;
|
||||
Layout::LayoutVec4 Position;
|
||||
|
||||
Layout::LayoutUnit With, MaxWidth, MinWidth;
|
||||
Layout::LayoutUnit Width, MaxWidth, MinWidth;
|
||||
Layout::LayoutUnit Height, MaxHeight, MinHeight;
|
||||
|
||||
Layout::LayoutVec4 Margin;
|
||||
Layout::LayoutVec4 Padding;
|
||||
Layout::LayoutVec4 Border;
|
||||
|
||||
Color BackgroundColor;
|
||||
|
||||
Layout::LayoutDirection Direction;
|
||||
|
||||
Layout::FlexDirection FlexDirection;
|
||||
Layout::FlexDirection FlexDirection = Layout::FlexDirection::ROW;
|
||||
|
||||
Layout::FlexWrap FlexWrap;
|
||||
float FlexGrow;
|
||||
@@ -88,5 +96,220 @@ public:
|
||||
Layout::AlignItems SelfAlign;
|
||||
|
||||
Node();
|
||||
};
|
||||
|
||||
void SetMargin()
|
||||
{
|
||||
switch (Margin.Left.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetMargin(YogaNode, YGEdgeLeft, Margin.Left.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetMarginPercent(YogaNode, YGEdgeLeft, Margin.Left.Value);
|
||||
break;
|
||||
case Layout::Unit::AUTO:
|
||||
YGNodeStyleSetMarginAuto(YogaNode, YGEdgeLeft);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Margin.Right.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetMargin(YogaNode, YGEdgeRight, Margin.Right.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetMarginPercent(YogaNode, YGEdgeRight, Margin.Right.Value);
|
||||
break;
|
||||
case Layout::Unit::AUTO:
|
||||
YGNodeStyleSetMarginAuto(YogaNode, YGEdgeRight);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Margin.Top.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetMargin(YogaNode, YGEdgeTop, Margin.Top.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetMarginPercent(YogaNode, YGEdgeTop, Margin.Top.Value);
|
||||
break;
|
||||
case Layout::Unit::AUTO:
|
||||
YGNodeStyleSetMarginAuto(YogaNode, YGEdgeTop);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Margin.Bottom.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetMargin(YogaNode, YGEdgeBottom, Margin.Bottom.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetMarginPercent(YogaNode, YGEdgeBottom, Margin.Bottom.Value);
|
||||
break;
|
||||
case Layout::Unit::AUTO:
|
||||
YGNodeStyleSetMarginAuto(YogaNode, YGEdgeTop);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetPadding()
|
||||
{
|
||||
switch (Padding.Left.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetPadding(YogaNode, YGEdgeLeft, Padding.Left.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetPaddingPercent(YogaNode, YGEdgeLeft, Padding.Left.Value);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Padding.Right.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetPadding(YogaNode, YGEdgeRight, Padding.Right.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetPaddingPercent(YogaNode, YGEdgeRight, Padding.Right.Value);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Padding.Top.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetPadding(YogaNode, YGEdgeTop, Padding.Top.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetPaddingPercent(YogaNode, YGEdgeTop, Padding.Top.Value);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Padding.Bottom.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetPadding(YogaNode, YGEdgeBottom, Padding.Bottom.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetPaddingPercent(YogaNode, YGEdgeBottom, Padding.Bottom.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetBorder()
|
||||
{
|
||||
switch (Border.Left.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetBorder(YogaNode, YGEdgeLeft, Border.Left.Value);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Border.Right.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetBorder(YogaNode, YGEdgeRight, Border.Right.Value);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Border.Top.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetBorder(YogaNode, YGEdgeTop, Border.Top.Value);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Border.Bottom.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetBorder(YogaNode, YGEdgeBottom, Border.Bottom.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetYogaLayout()
|
||||
{
|
||||
switch (Width.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetWidth(YogaNode, Width.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetWidthPercent(YogaNode, Width.Value);
|
||||
break;
|
||||
case Layout::Unit::AUTO:
|
||||
YGNodeStyleSetWidthAuto(YogaNode);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Height.Unit)
|
||||
{
|
||||
case Layout::Unit::PIXEL:
|
||||
YGNodeStyleSetHeight(YogaNode, Height.Value);
|
||||
break;
|
||||
case Layout::Unit::PERCENT:
|
||||
YGNodeStyleSetHeightPercent(YogaNode, Height.Value);
|
||||
break;
|
||||
case Layout::Unit::AUTO:
|
||||
YGNodeStyleSetHeightAuto(YogaNode);
|
||||
break;
|
||||
}
|
||||
|
||||
SetMargin();
|
||||
SetPadding();
|
||||
SetBorder();
|
||||
|
||||
YGNodeStyleSetFlexWrap(YogaNode, YGWrapWrap);
|
||||
YGNodeStyleSetFlexDirection(YogaNode, YGFlexDirectionRow);
|
||||
YGNodeStyleSetJustifyContent(YogaNode, YGJustifyFlexStart);
|
||||
}
|
||||
|
||||
void Draw(float z, Vector2 offset)
|
||||
{
|
||||
Color color = this->BackgroundColor;
|
||||
Renderer2D::UIShader->SetUniform4f("background_color",
|
||||
color.r / 255.f,
|
||||
color.g / 255.f,
|
||||
color.b / 255.f,
|
||||
color.a / 255.f);
|
||||
|
||||
// Get transform
|
||||
Matrix4 transform = Matrix4(1.0f);
|
||||
|
||||
float width = YGNodeLayoutGetWidth(YogaNode);
|
||||
float height = YGNodeLayoutGetHeight(YogaNode);
|
||||
float padding = YGNodeLayoutGetPadding(YogaNode, YGEdgeLeft);
|
||||
float left = YGNodeLayoutGetLeft(YogaNode); //+ offset.x;
|
||||
float top = YGNodeLayoutGetTop(YogaNode);// +offset.y;
|
||||
|
||||
|
||||
float parentLeft = 0.0f;
|
||||
float parentTop = 0.0f;
|
||||
auto parent = YGNodeGetParent(YogaNode);
|
||||
if (parent)
|
||||
{
|
||||
parentLeft = YGNodeLayoutGetLeft(YGNodeGetParent(YogaNode));
|
||||
parentTop = YGNodeLayoutGetTop(YGNodeGetParent(YogaNode));
|
||||
float parentPaddingTop = YGNodeLayoutGetPadding(parent, YGEdgeTop);
|
||||
float parentPaddingLeft = YGNodeLayoutGetPadding(parent, YGEdgeTop);
|
||||
// Overflow hidden.
|
||||
float parentwidth = YGNodeLayoutGetWidth(parent);
|
||||
if (parentwidth - YGNodeLayoutGetMargin(YogaNode, YGEdgeLeft) < width )
|
||||
width = parentwidth - parentPaddingLeft;
|
||||
float parentHeight = YGNodeLayoutGetHeight(parent);
|
||||
if (parentHeight < height)
|
||||
height = parentHeight - YGNodeLayoutGetMargin(YogaNode, YGEdgeTop) - parentPaddingTop;
|
||||
}
|
||||
|
||||
transform = glm::translate(transform, Vector3(left + parentLeft, top + parentTop, 0.f));
|
||||
|
||||
|
||||
Vector3 scale = Vector3(width, height, 0);
|
||||
transform = glm::scale(transform, scale);
|
||||
|
||||
//Logger::Log("Left: " + std::to_string(left) + " Top:" + std::to_string(top));
|
||||
Renderer2D::UIShader->SetUniformMat4f("model", transform);
|
||||
|
||||
Renderer2D::DrawRect();
|
||||
}
|
||||
};
|
||||
@@ -1,55 +1,45 @@
|
||||
#include "UserInterface.h"
|
||||
#include "yoga/Yoga.h"
|
||||
|
||||
#include <src/Vendors/pugixml/pugixml.hpp>
|
||||
#include "Stylesheet.h"
|
||||
#include "yoga/YGConfig.h"
|
||||
#include "InterfaceParser.h"
|
||||
namespace UI
|
||||
{
|
||||
struct simple_walker : pugi::xml_tree_walker
|
||||
{
|
||||
virtual bool for_each(pugi::xml_node& node)
|
||||
{
|
||||
for (int i = 0; i < depth(); ++i) std::cout << " "; // indentation
|
||||
|
||||
std::cout << node.type() << ": name='" << node.name() << "', value='" << node.value() << "'\n";
|
||||
|
||||
return true; // continue traversal
|
||||
}
|
||||
};
|
||||
|
||||
UserInterface::UserInterface(const std::string& name)
|
||||
{
|
||||
m_Name = name;
|
||||
pugi::xml_document doc;
|
||||
|
||||
// Parse xml document
|
||||
pugi::xml_parse_result result = doc.load_file("resources/Interface/Testing.interface");
|
||||
std::cout << "Load result: " << result.description() << ", mesh name: " << doc.child("Canvas").attribute("size").value() << std::endl;
|
||||
|
||||
auto childrends = doc.child("Canvas").children();
|
||||
simple_walker walker;
|
||||
doc.traverse(walker);
|
||||
Logger::Log("Hello");
|
||||
Root = InterfaceParser::Parse("resources/Interface/Testing.interface");
|
||||
|
||||
// Create engine structure from document
|
||||
if (!Root)
|
||||
{
|
||||
Logger::Log("Failed to generate interface structure");
|
||||
}
|
||||
|
||||
yoga_config = YGConfigNew();
|
||||
yoga_config->useWebDefaults = true;
|
||||
CreateYogaLayout();
|
||||
}
|
||||
|
||||
// Convert engine structure to yoga
|
||||
UserInterface::~UserInterface()
|
||||
{
|
||||
YGConfigFree(yoga_config);
|
||||
if (yoga_root)
|
||||
YGNodeFreeRecursive(yoga_root);
|
||||
}
|
||||
|
||||
void UserInterface::Reload()
|
||||
{
|
||||
Root = InterfaceParser::Parse("resources/Interface/Testing.interface");
|
||||
if (!Root)
|
||||
{
|
||||
Logger::Log("Failed to generate interface structure");
|
||||
}
|
||||
|
||||
// Calculate layout
|
||||
|
||||
|
||||
// Load css styling
|
||||
|
||||
//Ref<StyleSheet> stylesheet = StyleSheet::New("resources/Interface/Testing.css");
|
||||
// Iterate through css file
|
||||
|
||||
// Create style sheet data structure
|
||||
|
||||
// When rendering load styles to shader
|
||||
|
||||
// Render
|
||||
|
||||
yoga_config = YGConfigNew();
|
||||
yoga_config->useWebDefaults = true;
|
||||
CreateYogaLayout();
|
||||
}
|
||||
|
||||
Ref<UserInterface> UserInterface::New(const std::string& name)
|
||||
@@ -57,17 +47,68 @@ namespace UI
|
||||
return CreateRef<UserInterface>(name);
|
||||
}
|
||||
|
||||
void UserInterface::Calculate()
|
||||
void UserInterface::Calculate(int available_width, int available_height)
|
||||
{
|
||||
|
||||
YGNodeRef root = Root->YogaNode;
|
||||
YGNodeCalculateLayout(root, available_width, available_height, YGDirectionLTR);
|
||||
}
|
||||
|
||||
void UserInterface::Draw()
|
||||
void UserInterface::CreateYogaLayout()
|
||||
{
|
||||
Renderer2D::BeginDraw();
|
||||
for (auto r : m_Rects)
|
||||
yoga_root = YGNodeNewWithConfig(yoga_config);
|
||||
Root->YogaNode = yoga_root;
|
||||
Root->SetYogaLayout();
|
||||
CreateYogaLayoutRecursive(Root, yoga_root);
|
||||
}
|
||||
|
||||
|
||||
void UserInterface::CreateYogaLayoutRecursive(Ref<Node> node, YGNodeRef yoga_node)
|
||||
{
|
||||
if(node->Childrens.size() > 0)
|
||||
YGNodeCalculateLayout(yoga_node, YGNodeLayoutGetWidth(yoga_node), YGNodeLayoutGetHeight(yoga_node), YGDirectionLTR);
|
||||
int index = 0;
|
||||
for (auto& n : node->Childrens)
|
||||
{
|
||||
r->Draw();
|
||||
YGNodeRef newYogaNode = YGNodeNew();
|
||||
n->YogaNode = newYogaNode;
|
||||
n->SetYogaLayout();
|
||||
YGNodeInsertChild(yoga_node, newYogaNode, index);
|
||||
CreateYogaLayoutRecursive(n, newYogaNode);
|
||||
index++;
|
||||
}
|
||||
|
||||
Logger::Log(std::to_string(YGNodeGetChildCount(yoga_node)));
|
||||
}
|
||||
|
||||
void UserInterface::Draw(Vector2 size)
|
||||
{
|
||||
Calculate(size.x, size.y);
|
||||
Renderer2D::BeginDraw(size);
|
||||
|
||||
float leftOffset = YGNodeLayoutGetLeft(Root->YogaNode);
|
||||
float topOffset = YGNodeLayoutGetTop(Root->YogaNode);
|
||||
|
||||
DrawRecursive(Root, 0, Vector2(leftOffset, topOffset));
|
||||
}
|
||||
|
||||
void UserInterface::DrawRecursive(Ref<Node> node, float z, Vector2 offset)
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
node->Draw(z, offset);
|
||||
|
||||
if (node->Childrens.size() <= 0)
|
||||
return;
|
||||
|
||||
offset.x += YGNodeLayoutGetLeft(Root->YogaNode);
|
||||
|
||||
if(!YGNodeLayoutGetHadOverflow(Root->YogaNode))
|
||||
offset.y += YGNodeLayoutGetTop(Root->YogaNode);
|
||||
|
||||
for (auto& c : node->Childrens)
|
||||
{
|
||||
DrawRecursive(c, z + 1, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,57 +2,36 @@
|
||||
#include <src/Core/Timestep.h>
|
||||
#include <src/Rendering/Framebuffer.h>
|
||||
#include <src/UI/Rect.h>
|
||||
|
||||
#include "yoga/Yoga.h"
|
||||
#include "Node.h"
|
||||
#include <src/UI/Canvas.h>
|
||||
#include "../Core/Maths.h"
|
||||
namespace UI
|
||||
{
|
||||
class UserInterface
|
||||
{
|
||||
private:
|
||||
std::vector<Ref<Rect>> m_Rects;
|
||||
Ref<FrameBuffer> m_Framebuffer; // Texture of the interface.
|
||||
std::string m_Name;
|
||||
|
||||
Ref<Canvas> Root;
|
||||
YGConfigRef yoga_config;
|
||||
YGNodeRef yoga_root;
|
||||
public:
|
||||
const int Width = 1920;
|
||||
const int Height = 1080;
|
||||
|
||||
UserInterface(const std::string& name);
|
||||
~UserInterface();
|
||||
|
||||
void Reload();
|
||||
|
||||
static Ref<UserInterface> New(const std::string& name);
|
||||
void Calculate();
|
||||
void Draw();
|
||||
void Calculate(int available_width, int available_height);
|
||||
|
||||
void CreateYogaLayout();
|
||||
void CreateYogaLayoutRecursive(Ref<Node> node, YGNodeRef yoga_node);
|
||||
void Draw(Vector2 size);
|
||||
void DrawRecursive(Ref<Node> node, float z, Vector2 offset);
|
||||
void Update(Timestep ts);
|
||||
|
||||
std::vector<Ref<Rect>> GetRects()
|
||||
{
|
||||
return m_Rects;
|
||||
}
|
||||
|
||||
void AddRect(Ref<Rect> rect)
|
||||
{
|
||||
m_Rects.push_back(rect);
|
||||
}
|
||||
|
||||
Ref<Rect> GetRectByID(const std::string& id)
|
||||
{
|
||||
for (auto r : m_Rects)
|
||||
{
|
||||
if (r->GetID() == id)
|
||||
return r;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<Ref<Rect>> GetRectsByGroup(const std::string& group)
|
||||
{
|
||||
std::vector<Ref<Rect>> rects = std::vector<Ref<Rect>>();
|
||||
for (auto r : m_Rects)
|
||||
{
|
||||
if(r->HasGroup(group))
|
||||
rects.push_back(r);
|
||||
}
|
||||
return rects;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -360,7 +360,6 @@ WIN_EXPORT float YGRoundValueToPixelGrid(
|
||||
YG_EXTERN_C_END
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -244,6 +244,8 @@ void Window::Draw()
|
||||
m_Scene->Draw();
|
||||
else
|
||||
m_Scene->EditorDraw();
|
||||
|
||||
m_Scene->DrawInterface(m_Framebuffer->GetSize());
|
||||
}
|
||||
m_Framebuffer->Unbind();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user