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:
247
engine/app.cpp
247
engine/app.cpp
@@ -9,6 +9,39 @@ void App::create()
|
||||
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()
|
||||
{
|
||||
static const char* shader_v =
|
||||
@@ -56,52 +89,131 @@ void App::init()
|
||||
auto w = att::Width(10.f);
|
||||
printf("type: %d\n", att::value("Height"));
|
||||
|
||||
std::vector<std::unique_ptr<Shape>> s;
|
||||
auto y_root = YGNodeNew();
|
||||
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;
|
||||
auto ret = xml.LoadFile("data\\layout.xml");
|
||||
auto 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();
|
||||
}
|
||||
auto x_root = xml.RootElement();
|
||||
|
||||
YGNodeInsertChild(y_root, y_node, 0);
|
||||
printf("\n");
|
||||
child = child->NextSiblingElement();
|
||||
NodePair current = { y_root, x_root };
|
||||
stack.push(current);
|
||||
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();
|
||||
shader.create(shader_v, shader_f);
|
||||
shader_color.create(shader_color_v, shader_color_f);
|
||||
shader_uv.create(shader_v, shader_uv_f);
|
||||
plane.create<5>(50, 50);
|
||||
plane.create<5>(1, 1);
|
||||
circle.create<10>(25);
|
||||
circle2.create<10>(25, Circle::kUVMapping::Tube);
|
||||
circle3.create<10>(25, 12, Circle::kUVMapping::Tube);
|
||||
@@ -111,11 +223,10 @@ void App::init()
|
||||
if (!tex.load("data/uvs.jpg"))
|
||||
printf("error loading image\n");
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
glEnable(GL_TEXTURE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glPointSize(5);
|
||||
glLineWidth(1);
|
||||
glLineWidth(4);
|
||||
|
||||
//int n;
|
||||
//glGetIntegerv(GL_NUM_EXTENSIONS, &n);
|
||||
@@ -135,21 +246,15 @@ void App::init()
|
||||
|
||||
void App::update(float dt)
|
||||
{
|
||||
// static float theta = 0;
|
||||
// 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);
|
||||
glm::mat4 proj = glm::ortho(0.f, width, height, 0.f, -1.f, 1.f);
|
||||
|
||||
Shape* shapes[] = { &circle, &circle2, &circle3, &circle4, &plane, &rounded, &slice };
|
||||
|
||||
//glClearColor(red, 0, 0, 1);
|
||||
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
|
||||
/*
|
||||
auto s = glm::scale(glm::vec3(1.5));
|
||||
int h = 100;
|
||||
for (int i = 0; i < sizeof(shapes)/sizeof(Shape*); i++)
|
||||
@@ -184,6 +289,41 @@ void App::update(float dt)
|
||||
shapes[i]->draw_fill();
|
||||
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);
|
||||
//shader_color.use();
|
||||
//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);
|
||||
//circle3.draw_fill();
|
||||
}
|
||||
|
||||
void App::resize(float w, float h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
YGNodeStyleSetWidth(y_root, width);
|
||||
YGNodeStyleSetHeight(y_root, height);
|
||||
update_layout();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user