fixed layout parser adding stack based recursion, code needs being cleaned up but layout works quite well now, added code draw while resizing
This commit is contained in:
@@ -1,5 +1,13 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<layout>
|
<layout>
|
||||||
<rect width="10" height="10" />
|
<flex dir="row" wrap="1" width="100%">
|
||||||
<circle div="10" width="100%" inner_radius="10" outer_radius="50" />
|
<plane height="100" width="50%" min-width="500"/>
|
||||||
|
<plane height="100%" width="50%" wrap="1" dir="col">
|
||||||
|
<plane height="150" width="100%" />
|
||||||
|
<plane height="50%" width="50%">
|
||||||
|
<plane height="30" width="45" />
|
||||||
|
<plane height="30" width="45" />
|
||||||
|
</plane>
|
||||||
|
</plane>
|
||||||
|
</flex>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
247
engine/app.cpp
247
engine/app.cpp
@@ -9,6 +9,39 @@ void App::create()
|
|||||||
height = 800;
|
height = 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::update_layout()
|
||||||
|
{
|
||||||
|
YGNodeCalculateLayout(y_root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||||
|
std::stack<YGNodeRef> y_stack;
|
||||||
|
y_stack.push(y_root);
|
||||||
|
auto y_current = y_root;
|
||||||
|
while (y_current)
|
||||||
|
{
|
||||||
|
y_stack.pop();
|
||||||
|
auto ctx = reinterpret_cast<glm::vec2*>(YGNodeGetContext(y_current));
|
||||||
|
if (!ctx)
|
||||||
|
{
|
||||||
|
float x = YGNodeLayoutGetLeft(y_current);
|
||||||
|
float y = YGNodeLayoutGetTop(y_current);
|
||||||
|
ctx = new glm::vec2(x, y);
|
||||||
|
YGNodeSetContext(y_current, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = YGNodeGetChildCount(y_current);
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
auto y_child = YGNodeGetChild(y_current, i);
|
||||||
|
auto ctx_child = reinterpret_cast<glm::vec2*>(YGNodeGetContext(y_child));
|
||||||
|
if (!ctx_child) ctx_child = new glm::vec2();
|
||||||
|
ctx_child->x = ctx->x + YGNodeLayoutGetLeft(y_child);
|
||||||
|
ctx_child->y = ctx->y + YGNodeLayoutGetTop(y_child);
|
||||||
|
YGNodeSetContext(y_child, ctx_child);
|
||||||
|
y_stack.emplace(y_child);
|
||||||
|
}
|
||||||
|
y_current = y_stack.size() ? y_stack.top() : nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void App::init()
|
void App::init()
|
||||||
{
|
{
|
||||||
static const char* shader_v =
|
static const char* shader_v =
|
||||||
@@ -56,52 +89,131 @@ void App::init()
|
|||||||
auto w = att::Width(10.f);
|
auto w = att::Width(10.f);
|
||||||
printf("type: %d\n", att::value("Height"));
|
printf("type: %d\n", att::value("Height"));
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Shape>> s;
|
y_root = YGNodeNew();
|
||||||
auto y_root = YGNodeNew();
|
YGNodeStyleSetWidth(y_root, width);
|
||||||
|
YGNodeStyleSetHeight(y_root, height);
|
||||||
|
YGNodeStyleSetFlexDirection(y_root, YGFlexDirectionRow);
|
||||||
|
YGNodeStyleSetFlexWrap(y_root, YGWrapWrap);
|
||||||
|
//YGNodeStyleSetJustifyContent(y_root, YGJustifyFlexStart);
|
||||||
|
|
||||||
|
using NodePair = std::pair<YGNodeRef, tinyxml2::XMLElement*>;
|
||||||
|
std::stack<NodePair> stack;
|
||||||
|
|
||||||
tinyxml2::XMLDocument xml;
|
tinyxml2::XMLDocument xml;
|
||||||
auto ret = xml.LoadFile("data\\layout.xml");
|
auto ret = xml.LoadFile("data\\layout.xml");
|
||||||
auto root = xml.RootElement();
|
auto x_root = xml.RootElement();
|
||||||
auto child = root->FirstChildElement();
|
|
||||||
while (child)
|
|
||||||
{
|
|
||||||
printf("Element %s: ", child->Name());
|
|
||||||
auto attr = child->FirstAttribute();
|
|
||||||
auto y_node = YGNodeNew();
|
|
||||||
std::unique_ptr<Shape> shape = std::make_unique<Plane>();
|
|
||||||
while (attr)
|
|
||||||
{
|
|
||||||
const auto ka = att::value(attr->Name());
|
|
||||||
printf("%s=%s ", attr->Name(), attr->Value());
|
|
||||||
switch (ka)
|
|
||||||
{
|
|
||||||
case att::kAttribute::Width:
|
|
||||||
if (strchr(attr->Value(), '%'))
|
|
||||||
YGNodeStyleSetWidthPercent(y_node, attr->FloatValue());
|
|
||||||
else
|
|
||||||
YGNodeStyleSetWidth(y_node, attr->FloatValue());
|
|
||||||
shape->attribs[ka] = std::make_unique<att::Width>(attr->FloatValue());
|
|
||||||
break;
|
|
||||||
case att::kAttribute::Height:
|
|
||||||
if (strchr(attr->Value(), '%'))
|
|
||||||
YGNodeStyleSetHeightPercent(y_node, attr->FloatValue());
|
|
||||||
else
|
|
||||||
YGNodeStyleSetHeight(y_node, attr->FloatValue());
|
|
||||||
shape->attribs[ka] = std::make_unique<att::Height>(attr->FloatValue());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
attr = attr->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
YGNodeInsertChild(y_root, y_node, 0);
|
NodePair current = { y_root, x_root };
|
||||||
printf("\n");
|
stack.push(current);
|
||||||
child = child->NextSiblingElement();
|
while (current.first && current.second)
|
||||||
|
{
|
||||||
|
stack.pop();
|
||||||
|
auto y_root = current.first;
|
||||||
|
auto child = current.second->FirstChildElement();
|
||||||
|
YGNodeStyleSetPosition(y_root, YGEdgeAll, 0);
|
||||||
|
YGNodeStyleSetPadding(y_root, YGEdgeAll, 0);
|
||||||
|
YGNodeStyleSetMargin(y_root, YGEdgeAll, 0);
|
||||||
|
YGNodeStyleSetPositionType(y_root, YGPositionTypeRelative);
|
||||||
|
YGNodeStyleSetPosition(y_root, YGEdgeAll, 0);
|
||||||
|
YGNodeStyleSetPadding(y_root, YGEdgeAll, 0);
|
||||||
|
YGNodeStyleSetMargin(y_root, YGEdgeAll, 0);
|
||||||
|
while (child)
|
||||||
|
{
|
||||||
|
printf("Element %s: ", child->Name());
|
||||||
|
auto y_node = YGNodeNew();
|
||||||
|
stack.emplace(y_node, child);
|
||||||
|
auto attr = child->FirstAttribute();
|
||||||
|
if (strcmp("plane", child->Name()) == 0)
|
||||||
|
{
|
||||||
|
auto shape = std::make_unique<Plane>();
|
||||||
|
shape->create<5>(100.f, 100.f);
|
||||||
|
shape->y_node = y_node;
|
||||||
|
shapes_list.push_back(std::move(shape));
|
||||||
|
YGNodeSetContext(y_node, shape.get());
|
||||||
|
}
|
||||||
|
while (attr)
|
||||||
|
{
|
||||||
|
const auto ka = att::value(attr->Name());
|
||||||
|
printf("%s=%s ", attr->Name(), attr->Value());
|
||||||
|
switch (ka)
|
||||||
|
{
|
||||||
|
case att::kAttribute::Width:
|
||||||
|
if (strchr(attr->Value(), '%'))
|
||||||
|
YGNodeStyleSetWidthPercent(y_node, attr->FloatValue());
|
||||||
|
else
|
||||||
|
YGNodeStyleSetWidth(y_node, attr->FloatValue());
|
||||||
|
break;
|
||||||
|
case att::kAttribute::MinWidth:
|
||||||
|
if (strchr(attr->Value(), '%'))
|
||||||
|
YGNodeStyleSetMinWidthPercent(y_node, attr->FloatValue());
|
||||||
|
else
|
||||||
|
YGNodeStyleSetMinWidth(y_node, attr->FloatValue());
|
||||||
|
break;
|
||||||
|
case att::kAttribute::MaxWidth:
|
||||||
|
YGNodeStyleSetMaxWidth(y_node, attr->FloatValue());
|
||||||
|
break;
|
||||||
|
case att::kAttribute::Height:
|
||||||
|
if (strchr(attr->Value(), '%'))
|
||||||
|
YGNodeStyleSetHeightPercent(y_node, attr->FloatValue());
|
||||||
|
else
|
||||||
|
YGNodeStyleSetHeight(y_node, attr->FloatValue());
|
||||||
|
break;
|
||||||
|
case att::kAttribute::MinHeight:
|
||||||
|
YGNodeStyleSetMinHeight(y_node, attr->FloatValue());
|
||||||
|
break;
|
||||||
|
case att::kAttribute::MaxHeight:
|
||||||
|
YGNodeStyleSetMaxHeight(y_node, attr->FloatValue());
|
||||||
|
break;
|
||||||
|
case att::kAttribute::Grow:
|
||||||
|
YGNodeStyleSetFlexGrow(y_node, attr->FloatValue());
|
||||||
|
break;
|
||||||
|
case att::kAttribute::Shrink:
|
||||||
|
YGNodeStyleSetFlexShrink(y_node, attr->FloatValue());
|
||||||
|
break;
|
||||||
|
case att::kAttribute::FlexDir:
|
||||||
|
{
|
||||||
|
YGFlexDirection dir = YGFlexDirectionRow;
|
||||||
|
if (strcmp("col", attr->Value()) == 0)
|
||||||
|
dir = YGFlexDirectionColumn;
|
||||||
|
else if (strcmp("col-reverse", attr->Value()) == 0)
|
||||||
|
dir = YGFlexDirectionColumnReverse;
|
||||||
|
else if (strcmp("row", attr->Value()) == 0)
|
||||||
|
dir = YGFlexDirectionRow;
|
||||||
|
else if (strcmp("row-reverse", attr->Value()) == 0)
|
||||||
|
dir = YGFlexDirectionRowReverse;
|
||||||
|
YGNodeStyleSetFlexDirection(y_node, dir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case att::kAttribute::FlexWrap:
|
||||||
|
YGNodeStyleSetFlexWrap(y_node, attr->IntValue() ? YGWrapWrap : YGWrapNoWrap);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
attr = attr->Next();
|
||||||
|
}
|
||||||
|
int n = YGNodeGetChildCount(y_root);
|
||||||
|
YGNodeInsertChild(y_root, y_node, n);
|
||||||
|
child = child->NextSiblingElement();
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
current = stack.size() ? stack.top() : NodePair{nullptr, nullptr};
|
||||||
|
}
|
||||||
|
|
||||||
|
update_layout();
|
||||||
|
|
||||||
|
for (auto& s : shapes_list)
|
||||||
|
{
|
||||||
|
float w = YGNodeLayoutGetWidth(s->y_node);
|
||||||
|
float h = YGNodeLayoutGetHeight(s->y_node);
|
||||||
|
float x = YGNodeLayoutGetLeft(s->y_node);
|
||||||
|
float y = YGNodeLayoutGetTop(s->y_node);
|
||||||
|
printf("layout w=%f h=%f x=%f y=%f\n", w, h, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
sampler.create();
|
sampler.create();
|
||||||
shader.create(shader_v, shader_f);
|
shader.create(shader_v, shader_f);
|
||||||
shader_color.create(shader_color_v, shader_color_f);
|
shader_color.create(shader_color_v, shader_color_f);
|
||||||
shader_uv.create(shader_v, shader_uv_f);
|
shader_uv.create(shader_v, shader_uv_f);
|
||||||
plane.create<5>(50, 50);
|
plane.create<5>(1, 1);
|
||||||
circle.create<10>(25);
|
circle.create<10>(25);
|
||||||
circle2.create<10>(25, Circle::kUVMapping::Tube);
|
circle2.create<10>(25, Circle::kUVMapping::Tube);
|
||||||
circle3.create<10>(25, 12, Circle::kUVMapping::Tube);
|
circle3.create<10>(25, 12, Circle::kUVMapping::Tube);
|
||||||
@@ -111,11 +223,10 @@ void App::init()
|
|||||||
if (!tex.load("data/uvs.jpg"))
|
if (!tex.load("data/uvs.jpg"))
|
||||||
printf("error loading image\n");
|
printf("error loading image\n");
|
||||||
|
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
glEnable(GL_TEXTURE);
|
glEnable(GL_TEXTURE);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glPointSize(5);
|
glPointSize(5);
|
||||||
glLineWidth(1);
|
glLineWidth(4);
|
||||||
|
|
||||||
//int n;
|
//int n;
|
||||||
//glGetIntegerv(GL_NUM_EXTENSIONS, &n);
|
//glGetIntegerv(GL_NUM_EXTENSIONS, &n);
|
||||||
@@ -135,21 +246,15 @@ void App::init()
|
|||||||
|
|
||||||
void App::update(float dt)
|
void App::update(float dt)
|
||||||
{
|
{
|
||||||
// static float theta = 0;
|
glm::mat4 proj = glm::ortho(0.f, width, height, 0.f, -1.f, 1.f);
|
||||||
// theta += M_PI * 0.5f * dt;
|
|
||||||
// float red = fabsf(sinf(theta));
|
|
||||||
|
|
||||||
// glm::mat4 proj = glm::perspective(glm::radians(85.f), 1.f, .1f, 100.f);
|
|
||||||
// glm::mat4 model = glm::translate(glm::vec3(0, 0, 0));
|
|
||||||
// glm::mat4 view = glm::lookAt(glm::vec3(sinf(theta), 0, 1), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
|
|
||||||
|
|
||||||
glm::mat4 proj = glm::ortho(0.f, (float)width, (float)height, 0.f, -1.f, 1.f);
|
|
||||||
|
|
||||||
Shape* shapes[] = { &circle, &circle2, &circle3, &circle4, &plane, &rounded, &slice };
|
Shape* shapes[] = { &circle, &circle2, &circle3, &circle4, &plane, &rounded, &slice };
|
||||||
|
|
||||||
//glClearColor(red, 0, 0, 1);
|
//glClearColor(red, 0, 0, 1);
|
||||||
|
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
/*
|
||||||
auto s = glm::scale(glm::vec3(1.5));
|
auto s = glm::scale(glm::vec3(1.5));
|
||||||
int h = 100;
|
int h = 100;
|
||||||
for (int i = 0; i < sizeof(shapes)/sizeof(Shape*); i++)
|
for (int i = 0; i < sizeof(shapes)/sizeof(Shape*); i++)
|
||||||
@@ -184,6 +289,41 @@ void App::update(float dt)
|
|||||||
shapes[i]->draw_fill();
|
shapes[i]->draw_fill();
|
||||||
tex.unbind();
|
tex.unbind();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
tex.bind();
|
||||||
|
sampler.bind(0);
|
||||||
|
shader.use();
|
||||||
|
shader.u_int("tex", 0);
|
||||||
|
shader_color.use();
|
||||||
|
shader_color.u_vec4("col", { 0, 0, 1, 1 });
|
||||||
|
|
||||||
|
for (auto& s : shapes_list)
|
||||||
|
{
|
||||||
|
float w = YGNodeLayoutGetWidth(s->y_node);
|
||||||
|
float h = YGNodeLayoutGetHeight(s->y_node);
|
||||||
|
float x = YGNodeLayoutGetLeft(s->y_node);
|
||||||
|
float y = YGNodeLayoutGetTop(s->y_node);
|
||||||
|
auto loc = reinterpret_cast<glm::vec2*>(YGNodeGetContext(s->y_node));
|
||||||
|
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
|
||||||
|
glm::mat4 pivot = glm::translate(glm::vec3(.5f, .5f, 0.f));
|
||||||
|
glm::mat4 scale = glm::scale(glm::vec3(w, h, 1.f));
|
||||||
|
glm::mat4 pos = glm::translate(glm::vec3(*loc, 0));
|
||||||
|
auto mvp = proj * pos * scale * pivot;
|
||||||
|
|
||||||
|
shader_uv.use();
|
||||||
|
shader.u_mat4("mvp", mvp);
|
||||||
|
plane.draw_fill();
|
||||||
|
|
||||||
|
shader_color.use();
|
||||||
|
shader_color.u_mat4("mvp", mvp);
|
||||||
|
plane.draw_stroke();
|
||||||
|
}
|
||||||
|
tex.unbind();
|
||||||
|
sampler.unbind();
|
||||||
|
|
||||||
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
//shader_color.use();
|
//shader_color.use();
|
||||||
//shader_color.u_mat4("mvp", proj * glm::translate(glm::vec3{width/2, height/2, 0.f}) * glm::scale(glm::vec3(8)));
|
//shader_color.u_mat4("mvp", proj * glm::translate(glm::vec3{width/2, height/2, 0.f}) * glm::scale(glm::vec3(8)));
|
||||||
@@ -203,3 +343,12 @@ void App::update(float dt)
|
|||||||
//glLineWidth(2);
|
//glLineWidth(2);
|
||||||
//circle3.draw_fill();
|
//circle3.draw_fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::resize(float w, float h)
|
||||||
|
{
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
YGNodeStyleSetWidth(y_root, width);
|
||||||
|
YGNodeStyleSetHeight(y_root, height);
|
||||||
|
update_layout();
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,15 +11,19 @@ class App
|
|||||||
Shader shader_color;
|
Shader shader_color;
|
||||||
Shader shader_uv;
|
Shader shader_uv;
|
||||||
Plane plane;
|
Plane plane;
|
||||||
|
std::vector<std::unique_ptr<Shape>> shapes_list;
|
||||||
Circle circle, circle2, circle3, circle4;
|
Circle circle, circle2, circle3, circle4;
|
||||||
Rounded rounded;
|
Rounded rounded;
|
||||||
Slice9 slice;
|
Slice9 slice;
|
||||||
Texture2D tex;
|
Texture2D tex;
|
||||||
|
YGNodeRef y_root;
|
||||||
public:
|
public:
|
||||||
static App I;
|
static App I;
|
||||||
int width;
|
float width;
|
||||||
int height;
|
float height;
|
||||||
void init();
|
void init();
|
||||||
void create();
|
void create();
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
void resize(float w, float h);
|
||||||
|
void update_layout();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ int main()
|
|||||||
PIXELFORMATDESCRIPTOR pfd;
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
|
||||||
App::I.create();
|
App::I.create();
|
||||||
RECT clientRect = { 0, 0, App::I.width, App::I.height };
|
RECT clientRect = { 0, 0, (int)App::I.width, (int)App::I.height };
|
||||||
|
|
||||||
// Inizialize data structures to zero
|
// Inizialize data structures to zero
|
||||||
memset(&wc, 0, sizeof(wc));
|
memset(&wc, 0, sizeof(wc));
|
||||||
@@ -288,7 +288,7 @@ int main()
|
|||||||
wglDeleteContext(hRC);
|
wglDeleteContext(hRC);
|
||||||
DestroyWindow(hWnd);
|
DestroyWindow(hWnd);
|
||||||
|
|
||||||
hWnd = CreateWindow(wc.lpszClassName, L"New Engine", WS_OVERLAPPEDWINDOW,
|
hWnd = CreateWindow(wc.lpszClassName, L"UI Layout Engine", WS_OVERLAPPEDWINDOW,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, clientRect.right - clientRect.left,
|
CW_USEDEFAULT, CW_USEDEFAULT, clientRect.right - clientRect.left,
|
||||||
clientRect.bottom - clientRect.top, 0, 0, hInst, 0);
|
clientRect.bottom - clientRect.top, 0, 0, hInst, 0);
|
||||||
|
|
||||||
@@ -350,6 +350,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
break;
|
break;
|
||||||
|
case WM_SIZE:
|
||||||
|
App::I.resize((float)LOWORD(lp), (float)HIWORD(lp));
|
||||||
|
App::I.update(0.f);
|
||||||
|
SwapBuffers(hDC);
|
||||||
|
break;
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
keys[wp] = true;
|
keys[wp] = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <OpenGL/gl.h>
|
|
||||||
#include <OpenGL/gl3.h>
|
#include <OpenGL/gl3.h>
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
@@ -13,6 +12,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <stack>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#define GLM_FORCE_RADIANS
|
#define GLM_FORCE_RADIANS
|
||||||
#define GLM_FORCE_SWIZZLE
|
#define GLM_FORCE_SWIZZLE
|
||||||
#define GLM_FORCE_MESSAGES
|
//#define GLM_FORCE_MESSAGES
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
@@ -30,4 +30,3 @@
|
|||||||
|
|
||||||
#include <tinyxml2.h>
|
#include <tinyxml2.h>
|
||||||
#include <yoga/Yoga.h>
|
#include <yoga/Yoga.h>
|
||||||
#include <yoga/Yoga.h>
|
|
||||||
|
|||||||
@@ -2,7 +2,12 @@
|
|||||||
|
|
||||||
namespace att
|
namespace att
|
||||||
{
|
{
|
||||||
enum class kAttribute : uint8_t { Width, Height, Divisions, InnerRadius, OuterRadius };
|
enum class kAttribute : uint8_t {
|
||||||
|
Width, MinWidth, MaxWidth,
|
||||||
|
Height, MinHeight, MaxHeight,
|
||||||
|
Divisions, InnerRadius, OuterRadius,
|
||||||
|
Grow, Shrink, FlexDir, FlexWrap
|
||||||
|
};
|
||||||
|
|
||||||
struct AttributeBase
|
struct AttributeBase
|
||||||
{
|
{
|
||||||
@@ -14,11 +19,10 @@ namespace att
|
|||||||
template<kAttribute T, typename V>
|
template<kAttribute T, typename V>
|
||||||
struct Attribute : public AttributeBase
|
struct Attribute : public AttributeBase
|
||||||
{
|
{
|
||||||
using type = V;
|
|
||||||
static const kAttribute static_id = T;
|
static const kAttribute static_id = T;
|
||||||
V value;
|
V value;
|
||||||
Attribute() : value{ 0 }, { id = static_id; }
|
Attribute() : value{0} { id = static_id; }
|
||||||
Attribute(type v) : value(v) { id = static_id; }
|
Attribute(V v) : value(v) { id = static_id; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct typemap
|
struct typemap
|
||||||
@@ -29,10 +33,18 @@ namespace att
|
|||||||
static constexpr typemap map[] =
|
static constexpr typemap map[] =
|
||||||
{
|
{
|
||||||
{ "width", kAttribute::Width },
|
{ "width", kAttribute::Width },
|
||||||
|
{ "min-width", kAttribute::MinWidth },
|
||||||
|
{ "max-width", kAttribute::MaxWidth },
|
||||||
{ "height", kAttribute::Height },
|
{ "height", kAttribute::Height },
|
||||||
|
{ "min-height", kAttribute::MinHeight },
|
||||||
|
{ "max-height", kAttribute::MaxHeight },
|
||||||
{ "divisions", kAttribute::Divisions },
|
{ "divisions", kAttribute::Divisions },
|
||||||
{ "inner_radius", kAttribute::InnerRadius },
|
{ "inner-radius", kAttribute::InnerRadius },
|
||||||
{ "outer_radius", kAttribute::OuterRadius },
|
{ "outer-radius", kAttribute::OuterRadius },
|
||||||
|
{ "grow", kAttribute::Grow },
|
||||||
|
{ "shrink", kAttribute::Shrink },
|
||||||
|
{ "dir", kAttribute::FlexDir },
|
||||||
|
{ "wrap", kAttribute::FlexWrap },
|
||||||
};
|
};
|
||||||
constexpr int map_size = sizeof(map) / sizeof(typemap) - 1;
|
constexpr int map_size = sizeof(map) / sizeof(typemap) - 1;
|
||||||
constexpr bool same(const char* a, const char* b)
|
constexpr bool same(const char* a, const char* b)
|
||||||
@@ -51,18 +63,26 @@ namespace att
|
|||||||
|
|
||||||
//constexpr const char* string(kAttribute a) { return names[(int)a]; }
|
//constexpr const char* string(kAttribute a) { return names[(int)a]; }
|
||||||
|
|
||||||
template<kAttribute T, typename V>
|
// template<kAttribute T, typename V>
|
||||||
constexpr const char* string(const Attribute<T, V> a) { return names[(int)a.id]; }
|
// constexpr const char* string(const Attribute<T, V> a) { return names[(int)a.id]; }
|
||||||
|
|
||||||
#define DECLARE_ATTRIBUTE(N,T) \
|
#define DECLARE_ATTRIBUTE(N,T) \
|
||||||
struct N : public Attribute<kAttribute::N,T> \
|
struct N : public Attribute<kAttribute::N,T> \
|
||||||
{ using Attribute<kAttribute::N,T>::Attribute; };
|
{ using Attribute<kAttribute::N,T>::Attribute; };
|
||||||
|
|
||||||
DECLARE_ATTRIBUTE(Width, float);
|
DECLARE_ATTRIBUTE(Width, float);
|
||||||
|
DECLARE_ATTRIBUTE(MinWidth, float);
|
||||||
|
DECLARE_ATTRIBUTE(MaxWidth, float);
|
||||||
DECLARE_ATTRIBUTE(Height, float);
|
DECLARE_ATTRIBUTE(Height, float);
|
||||||
|
DECLARE_ATTRIBUTE(MinHeight, float);
|
||||||
|
DECLARE_ATTRIBUTE(MaxHeight, float);
|
||||||
DECLARE_ATTRIBUTE(Divisions, int);
|
DECLARE_ATTRIBUTE(Divisions, int);
|
||||||
DECLARE_ATTRIBUTE(InnerRadius, float);
|
DECLARE_ATTRIBUTE(InnerRadius, float);
|
||||||
DECLARE_ATTRIBUTE(OuterRadius, float);
|
DECLARE_ATTRIBUTE(OuterRadius, float);
|
||||||
|
DECLARE_ATTRIBUTE(Grow, float);
|
||||||
|
DECLARE_ATTRIBUTE(Shrink, float);
|
||||||
|
DECLARE_ATTRIBUTE(FlexDir, int);
|
||||||
|
DECLARE_ATTRIBUTE(FlexWrap, int);
|
||||||
|
|
||||||
#undef DECLARE_ATTRIBUTE
|
#undef DECLARE_ATTRIBUTE
|
||||||
}
|
}
|
||||||
@@ -76,6 +96,8 @@ protected:
|
|||||||
GLvoid* ioff[2];
|
GLvoid* ioff[2];
|
||||||
struct vertex_t { glm::vec4 pos; glm::vec2 uvs; };
|
struct vertex_t { glm::vec4 pos; glm::vec2 uvs; };
|
||||||
public:
|
public:
|
||||||
|
YGNodeRef y_node;
|
||||||
|
float x, y;
|
||||||
att::AttrubutesMap attribs;
|
att::AttrubutesMap attribs;
|
||||||
bool create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize);
|
bool create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize);
|
||||||
void draw_fill() const;
|
void draw_fill() const;
|
||||||
@@ -126,12 +148,20 @@ public:
|
|||||||
create_impl(w.value, h.value, div, idx.get(), vertices.get());
|
create_impl(w.value, h.value, div, idx.get(), vertices.get());
|
||||||
return create_buffers(idx.get(), vertices.get(), sizeof(idx), sizeof(vertices));
|
return create_buffers(idx.get(), vertices.get(), sizeof(idx), sizeof(vertices));
|
||||||
}
|
}
|
||||||
|
template<typename T>
|
||||||
|
T get_attribute(T def_val)
|
||||||
|
{
|
||||||
|
auto ret = attribs.find(def_val.id);
|
||||||
|
if (ret == attribs.end())
|
||||||
|
return def_val;
|
||||||
|
return *reinterpret_cast<T*>(ret->second.get());
|
||||||
|
}
|
||||||
bool create_attrib() override
|
bool create_attrib() override
|
||||||
{
|
{
|
||||||
const att::Width* w = reinterpret_cast<att::Width*>(attribs[att::kAttribute::Width].get());
|
const auto w = get_attribute(att::Width(0));
|
||||||
const att::Height* h = reinterpret_cast<att::Height*>(attribs[att::kAttribute::Height].get());
|
const auto h = get_attribute(att::Height(0));
|
||||||
const att::Divisions* div = reinterpret_cast<att::Divisions*>(attribs[att::kAttribute::Height].get());
|
const auto d = get_attribute(att::Divisions(1));
|
||||||
return create(*div, *w, *h);
|
return create(d, w, h);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ bool Texture2D::create(int width, int height, GLint format, const uint8_t* data)
|
|||||||
}
|
}
|
||||||
bool Texture2D::create(const Image& img)
|
bool Texture2D::create(const Image& img)
|
||||||
{
|
{
|
||||||
static GLint formats[] = { GL_R, GL_RG, GL_RGB, GL_RGBA };
|
static GLint formats[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
|
||||||
return create(img.width, img.height, formats[img.comp - 1], img.data());
|
return create(img.width, img.height, formats[img.comp - 1], img.data());
|
||||||
}
|
}
|
||||||
bool Texture2D::load(std::string filename)
|
bool Texture2D::load(std::string filename)
|
||||||
|
|||||||
Reference in New Issue
Block a user