added margin and padding support, some fixes: yoga needs many values to be initialized properly

This commit is contained in:
2017-01-23 22:13:36 +00:00
parent e556cf4c61
commit 5268f65777
5 changed files with 189 additions and 75 deletions

View File

@@ -1,13 +1,34 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<layout> <layout>
<flex dir="row" wrap="1" width="100%"> <flex dir="col" wrap="0" width="100%" height="100%" pad="10">
<plane height="100" width="50%" min-width="500"/> <!-- toolbar -->
<plane height="100%" width="50%" wrap="1" dir="col"> <plane height="50" width="100%" pad="5" dir="row">
<plane width="50" margin="0 5 0 0"></plane>
<plane width="50" margin="0 5 0 0"></plane>
<plane width="50" margin="0 5 0 0"></plane>
<separator width="10" />
<plane width="50" margin="0 5 0 0"></plane>
<plane width="50" margin="0 5 0 0"></plane>
<plane width="50" margin="0 5 0 0"></plane>
<separator width="10" />
<plane width="50" margin="0 5 0 0"></plane>
<plane width="50" margin="0 5 0 0"></plane>
<plane width="50" margin="0 5 0 0"></plane>
</plane>
<plane grow="1" dir="row" wrap="1" height="0">
<plane width="200" height="100%"></plane>
<plane width="1" grow="1" height="100%" pad="30" wrap="1">
<plane></plane>
</plane>
</plane>
<!-- status bar -->
<plane height="30" width="100%" />
<!--<plane height="100%" width="50%" wrap="1" dir="col">
<plane height="150" width="100%" /> <plane height="150" width="100%" />
<plane height="50%" width="50%"> <plane height="50%" width="50%">
<plane height="30" width="45" /> <plane height="30" width="45" />
<plane height="30" width="45" /> <plane height="30" width="45" />
</plane> </plane>
</plane> </plane>-->
</flex> </flex>
</layout> </layout>

View File

@@ -18,12 +18,14 @@ void App::update_layout()
while (y_current) while (y_current)
{ {
y_stack.pop(); y_stack.pop();
auto ctx = reinterpret_cast<glm::vec2*>(YGNodeGetContext(y_current)); auto ctx = reinterpret_cast<glm::vec4*>(YGNodeGetContext(y_current));
if (!ctx) if (!ctx)
{ {
float x = YGNodeLayoutGetLeft(y_current); float x = YGNodeLayoutGetLeft(y_current);
float y = YGNodeLayoutGetTop(y_current); float y = YGNodeLayoutGetTop(y_current);
ctx = new glm::vec2(x, y); float w = YGNodeLayoutGetWidth(y_current);
float h = YGNodeLayoutGetHeight(y_current);
ctx = new glm::vec4(x, y, w, h);
YGNodeSetContext(y_current, ctx); YGNodeSetContext(y_current, ctx);
} }
@@ -31,10 +33,20 @@ void App::update_layout()
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
{ {
auto y_child = YGNodeGetChild(y_current, i); auto y_child = YGNodeGetChild(y_current, i);
auto ctx_child = reinterpret_cast<glm::vec2*>(YGNodeGetContext(y_child)); auto ctx_child = reinterpret_cast<glm::vec4*>(YGNodeGetContext(y_child));
if (!ctx_child) ctx_child = new glm::vec2(); if (!ctx_child) ctx_child = new glm::vec4();
ctx_child->x = ctx->x + YGNodeLayoutGetLeft(y_child); float x = YGNodeLayoutGetLeft(y_child);
ctx_child->y = ctx->y + YGNodeLayoutGetTop(y_child); float y = YGNodeLayoutGetTop(y_child);
float w = YGNodeLayoutGetWidth(y_child);
float h = YGNodeLayoutGetHeight(y_child);
float pt = 0;//YGNodeLayoutGetPadding(y_current, YGEdgeTop);
float pr = 0;//YGNodeLayoutGetPadding(y_current, YGEdgeRight);
float pb = 0;//YGNodeLayoutGetPadding(y_current, YGEdgeBottom);
float pl = 0;//YGNodeLayoutGetPadding(y_current, YGEdgeLeft);
ctx_child->x = ctx->x + x + pl;
ctx_child->y = ctx->y + y + pt;
ctx_child->z = w - (pl + pr);
ctx_child->w = h - (pt + pb);
YGNodeSetContext(y_child, ctx_child); YGNodeSetContext(y_child, ctx_child);
y_stack.emplace(y_child); y_stack.emplace(y_child);
} }
@@ -42,58 +54,31 @@ void App::update_layout()
} }
} }
void App::init() void App::load_layout()
{ {
static const char* shader_v = struct stat tmp_info;
"#version 150\n" if (stat("data/layout.xml", &tmp_info) != 0)
"uniform mat4 mvp;" return;
"in vec4 pos;" if (tmp_info.st_mtime <= g_file_info.st_mtime)
"in vec2 uvs;" return;
"out vec3 uv;" g_file_info = tmp_info;
"void main(){"
" uv = vec3(uvs, pos.w);"
" gl_Position = mvp * vec4(pos.xyz, 1.f);"
"}";
static const char* shader_f =
"#version 150\n"
"uniform sampler2D tex;"
"in vec3 uv;"
"out vec4 frag;"
"void main(){"
//" frag = texture(tex, uv.xy/uv.z);"
" frag = texture(tex, uv.xy);"
"}";
static const char* shader_uv_f =
"#version 150\n"
"uniform sampler2D tex;"
"in vec3 uv;"
"out vec4 frag;"
"void main(){"
" frag = vec4(uv.xy,0,1);"
"}";
static const char* shader_color_v =
"#version 150\n"
"uniform mat4 mvp;"
"in vec4 pos;"
"void main(){"
" gl_Position = mvp * pos;"
"}";
static const char* shader_color_f =
"#version 150\n"
"uniform vec4 col;"
"out vec4 frag;"
"void main(){"
" frag = col;"
"}";
auto w = att::Width(10.f); if (y_root)
printf("type: %d\n", att::value("Height")); YGNodeFreeRecursive(y_root);
shapes_list.clear();
y_root = YGNodeNew(); y_root = YGNodeNew();
YGNodeStyleSetWidth(y_root, width); YGNodeStyleSetWidth(y_root, width);
//YGNodeStyleSetWidthPercent(y_root, 100);
YGNodeStyleSetHeight(y_root, height); YGNodeStyleSetHeight(y_root, height);
//YGNodeStyleSetHeightPercent(y_root, 100);
YGNodeStyleSetFlexDirection(y_root, YGFlexDirectionRow); YGNodeStyleSetFlexDirection(y_root, YGFlexDirectionRow);
YGNodeStyleSetFlexWrap(y_root, YGWrapWrap); YGNodeStyleSetFlexWrap(y_root, YGWrapWrap);
YGNodeStyleSetPadding(y_root, YGEdgeAll, 0);
YGNodeStyleSetPadding(y_root, YGEdgeTop, 0);
YGNodeStyleSetPadding(y_root, YGEdgeRight, 0);
YGNodeStyleSetPadding(y_root, YGEdgeBottom, 0);
YGNodeStyleSetPadding(y_root, YGEdgeLeft, 0);
//YGNodeStyleSetJustifyContent(y_root, YGJustifyFlexStart); //YGNodeStyleSetJustifyContent(y_root, YGJustifyFlexStart);
using NodePair = std::pair<YGNodeRef, tinyxml2::XMLElement*>; using NodePair = std::pair<YGNodeRef, tinyxml2::XMLElement*>;
@@ -110,13 +95,8 @@ void App::init()
stack.pop(); stack.pop();
auto y_root = current.first; auto y_root = current.first;
auto child = current.second->FirstChildElement(); auto child = current.second->FirstChildElement();
YGNodeStyleSetPosition(y_root, YGEdgeAll, 0); //YGNodeStyleSetPosition(y_root, YGEdgeAll, 0);
YGNodeStyleSetPadding(y_root, YGEdgeAll, 0); //YGNodeStyleSetPositionType(y_root, YGPositionTypeRelative);
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) while (child)
{ {
printf("Element %s: ", child->Name()); printf("Element %s: ", child->Name());
@@ -126,11 +106,26 @@ void App::init()
if (strcmp("plane", child->Name()) == 0) if (strcmp("plane", child->Name()) == 0)
{ {
auto shape = std::make_unique<Plane>(); auto shape = std::make_unique<Plane>();
shape->create<5>(100.f, 100.f); //shape->create<5>(100.f, 100.f);
shape->y_node = y_node; shape->y_node = y_node;
shapes_list.push_back(std::move(shape)); shapes_list.push_back(std::move(shape));
YGNodeSetContext(y_node, shape.get()); YGNodeSetContext(y_node, shape.get());
} }
YGNodeStyleSetWidth(y_node, 0);
YGNodeStyleSetWidthPercent(y_node, 100);
YGNodeStyleSetHeight(y_node, 0);
YGNodeStyleSetHeightPercent(y_node, 100);
YGNodeStyleSetPadding(y_node, YGEdgeAll, 0);
YGNodeStyleSetPadding(y_node, YGEdgeTop, 0);
YGNodeStyleSetPadding(y_node, YGEdgeRight, 0);
YGNodeStyleSetPadding(y_node, YGEdgeBottom, 0);
YGNodeStyleSetPadding(y_node, YGEdgeLeft, 0);
YGNodeStyleSetPosition(y_node, YGEdgeAll, 0);
YGNodeStyleSetPosition(y_node, YGEdgeTop, 0);
YGNodeStyleSetPosition(y_node, YGEdgeRight, 0);
YGNodeStyleSetPosition(y_node, YGEdgeBottom, 0);
YGNodeStyleSetPosition(y_node, YGEdgeLeft, 0);
while (attr) while (attr)
{ {
const auto ka = att::value(attr->Name()); const auto ka = att::value(attr->Name());
@@ -187,6 +182,48 @@ void App::init()
case att::kAttribute::FlexWrap: case att::kAttribute::FlexWrap:
YGNodeStyleSetFlexWrap(y_node, attr->IntValue() ? YGWrapWrap : YGWrapNoWrap); YGNodeStyleSetFlexWrap(y_node, attr->IntValue() ? YGWrapWrap : YGWrapNoWrap);
break; break;
case att::kAttribute::Padding:
{
glm::vec4 pad;
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
if (n == 1)
{
YGNodeStyleSetPadding(y_node, YGEdgeTop, pad.x);
YGNodeStyleSetPadding(y_node, YGEdgeRight, pad.x);
YGNodeStyleSetPadding(y_node, YGEdgeBottom, pad.x);
YGNodeStyleSetPadding(y_node, YGEdgeLeft, pad.x);
}
else
{
YGNodeStyleSetPadding(y_node, YGEdgeTop, pad.x);
YGNodeStyleSetPadding(y_node, YGEdgeRight, pad.y);
YGNodeStyleSetPadding(y_node, YGEdgeBottom, pad.z);
YGNodeStyleSetPadding(y_node, YGEdgeLeft, pad.w);
}
break;
}
case att::kAttribute::Margin:
{
glm::vec4 pad;
int n = sscanf(attr->Value(), "%f %f %f %f", &pad.x, &pad.y, &pad.z, &pad.w);
if (n == 1)
{
YGNodeStyleSetMargin(y_node, YGEdgeTop, pad.x);
YGNodeStyleSetMargin(y_node, YGEdgeRight, pad.x);
YGNodeStyleSetMargin(y_node, YGEdgeBottom, pad.x);
YGNodeStyleSetMargin(y_node, YGEdgeLeft, pad.x);
}
else
{
YGNodeStyleSetMargin(y_node, YGEdgeTop, pad.x);
YGNodeStyleSetMargin(y_node, YGEdgeRight, pad.y);
YGNodeStyleSetMargin(y_node, YGEdgeBottom, pad.z);
YGNodeStyleSetMargin(y_node, YGEdgeLeft, pad.w);
}
break;
}
default:
break;
} }
attr = attr->Next(); attr = attr->Next();
} }
@@ -197,8 +234,54 @@ void App::init()
} }
current = stack.size() ? stack.top() : NodePair{ nullptr, nullptr }; current = stack.size() ? stack.top() : NodePair{ nullptr, nullptr };
} }
update_layout(); update_layout();
}
void App::init()
{
static const char* shader_v =
"#version 150\n"
"uniform mat4 mvp;"
"in vec4 pos;"
"in vec2 uvs;"
"out vec3 uv;"
"void main(){"
" uv = vec3(uvs, pos.w);"
" gl_Position = mvp * vec4(pos.xyz, 1.f);"
"}";
static const char* shader_f =
"#version 150\n"
"uniform sampler2D tex;"
"in vec3 uv;"
"out vec4 frag;"
"void main(){"
//" frag = texture(tex, uv.xy/uv.z);"
" frag = texture(tex, uv.xy);"
"}";
static const char* shader_uv_f =
"#version 150\n"
"uniform sampler2D tex;"
"in vec3 uv;"
"out vec4 frag;"
"void main(){"
" frag = vec4(uv.xy,0,1);"
"}";
static const char* shader_color_v =
"#version 150\n"
"uniform mat4 mvp;"
"in vec4 pos;"
"void main(){"
" gl_Position = mvp * pos;"
"}";
static const char* shader_color_f =
"#version 150\n"
"uniform vec4 col;"
"out vec4 frag;"
"void main(){"
" frag = col;"
"}";
load_layout();
for (auto& s : shapes_list) for (auto& s : shapes_list)
{ {
@@ -248,12 +331,14 @@ void App::update(float dt)
{ {
glm::mat4 proj = glm::ortho(0.f, width, 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 }; //Shape* shapes[] = { &circle, &circle2, &circle3, &circle4, &plane, &rounded, &slice };
//glClearColor(red, 0, 0, 1); glClearColor(.1f, .1f, .1f, 1.f);
glViewport(0, 0, (GLsizei)width, (GLsizei)height); glViewport(0, 0, (GLsizei)width, (GLsizei)height);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
load_layout();
/* /*
auto s = glm::scale(glm::vec3(1.5)); auto s = glm::scale(glm::vec3(1.5));
int h = 100; int h = 100;
@@ -296,7 +381,7 @@ void App::update(float dt)
shader.use(); shader.use();
shader.u_int("tex", 0); shader.u_int("tex", 0);
shader_color.use(); shader_color.use();
shader_color.u_vec4("col", { 0, 0, 1, 1 }); shader_color.u_vec4("col", { .3f, .3f, .3f, 1 });
for (auto& s : shapes_list) for (auto& s : shapes_list)
{ {
@@ -304,18 +389,18 @@ void App::update(float dt)
float h = YGNodeLayoutGetHeight(s->y_node); float h = YGNodeLayoutGetHeight(s->y_node);
float x = YGNodeLayoutGetLeft(s->y_node); float x = YGNodeLayoutGetLeft(s->y_node);
float y = YGNodeLayoutGetTop(s->y_node); float y = YGNodeLayoutGetTop(s->y_node);
auto loc = reinterpret_cast<glm::vec2*>(YGNodeGetContext(s->y_node)); auto layout = *reinterpret_cast<glm::vec4*>(YGNodeGetContext(s->y_node));
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glm::mat4 pivot = glm::translate(glm::vec3(.5f, .5f, 0.f)); glm::mat4 pivot = glm::translate(glm::vec3(.5f, .5f, 0.f));
glm::mat4 scale = glm::scale(glm::vec3(w, h, 1.f)); glm::mat4 scale = glm::scale(glm::vec3(layout.zw(), 1.f));
glm::mat4 pos = glm::translate(glm::vec3(*loc, 0)); glm::mat4 pos = glm::translate(glm::vec3(layout.xy(), 0));
auto mvp = proj * pos * scale * pivot; auto mvp = proj * pos * scale * pivot;
shader_uv.use(); //shader_uv.use();
shader.u_mat4("mvp", mvp); //shader_uv.u_mat4("mvp", mvp);
plane.draw_fill(); //plane.draw_fill();
shader_color.use(); shader_color.use();
shader_color.u_mat4("mvp", mvp); shader_color.u_mat4("mvp", mvp);

View File

@@ -16,7 +16,8 @@ class App
Rounded rounded; Rounded rounded;
Slice9 slice; Slice9 slice;
Texture2D tex; Texture2D tex;
YGNodeRef y_root; YGNodeRef y_root { nullptr };
struct stat g_file_info { 0 };
public: public:
static App I; static App I;
float width; float width;
@@ -26,4 +27,5 @@ public:
void update(float dt); void update(float dt);
void resize(float w, float h); void resize(float w, float h);
void update_layout(); void update_layout();
void load_layout();
}; };

View File

@@ -227,6 +227,7 @@ int main()
wc.lpfnWndProc = (WNDPROC)WndProc; wc.lpfnWndProc = (WNDPROC)WndProc;
wc.lpszClassName = className; wc.lpszClassName = className;
wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc); RegisterClass(&wc);

View File

@@ -6,7 +6,8 @@ namespace att
Width, MinWidth, MaxWidth, Width, MinWidth, MaxWidth,
Height, MinHeight, MaxHeight, Height, MinHeight, MaxHeight,
Divisions, InnerRadius, OuterRadius, Divisions, InnerRadius, OuterRadius,
Grow, Shrink, FlexDir, FlexWrap Grow, Shrink, FlexDir, FlexWrap,
Padding, Margin
}; };
struct AttributeBase struct AttributeBase
@@ -45,6 +46,8 @@ namespace att
{ "shrink", kAttribute::Shrink }, { "shrink", kAttribute::Shrink },
{ "dir", kAttribute::FlexDir }, { "dir", kAttribute::FlexDir },
{ "wrap", kAttribute::FlexWrap }, { "wrap", kAttribute::FlexWrap },
{ "pad", kAttribute::Padding },
{ "margin", kAttribute::Margin},
}; };
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)
@@ -83,6 +86,8 @@ namespace att
DECLARE_ATTRIBUTE(Shrink, float); DECLARE_ATTRIBUTE(Shrink, float);
DECLARE_ATTRIBUTE(FlexDir, int); DECLARE_ATTRIBUTE(FlexDir, int);
DECLARE_ATTRIBUTE(FlexWrap, int); DECLARE_ATTRIBUTE(FlexWrap, int);
DECLARE_ATTRIBUTE(Padding, glm::vec4);
DECLARE_ATTRIBUTE(Margin, glm::vec4);
#undef DECLARE_ATTRIBUTE #undef DECLARE_ATTRIBUTE
} }