From 6b99697e821d85c0bd6046111b547ca60a3eaaff Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 4 Nov 2022 00:29:13 +0900 Subject: [PATCH] [ui] Get flowed views working with ECS I'm not particularly happy with the way onresize is handled, but at this stage a better way of dealing with resizing views and getting the child views to flow correctly hasn't come to mind. However, the system should at least be usable. --- include/QF/ui/view.h | 20 ++ libs/ui/test/Makemodule.am | 8 +- libs/ui/test/test-flow-size.c | 94 ++++--- libs/ui/test/test-flow.c | 93 ++++--- libs/ui/view.c | 464 ++++++++++++---------------------- 5 files changed, 307 insertions(+), 372 deletions(-) diff --git a/include/QF/ui/view.h b/include/QF/ui/view.h index f5ded1ccf..9370e3659 100644 --- a/include/QF/ui/view.h +++ b/include/QF/ui/view.h @@ -127,6 +127,15 @@ view_t View_New (ecs_registry_t *reg, view_t parent); void View_SetParent (view_t view, view_t parent); void View_UpdateHierarchy (view_t view); +void view_flow_right_down (view_t view, view_pos_t len); +void view_flow_right_up (view_t view, view_pos_t len); +void view_flow_left_down (view_t view, view_pos_t len); +void view_flow_left_up (view_t view, view_pos_t len); +void view_flow_down_right (view_t view, view_pos_t len); +void view_flow_up_right (view_t view, view_pos_t len); +void view_flow_down_left (view_t view, view_pos_t len); +void view_flow_up_left (view_t view, view_pos_t len); + VIEWINLINE hierref_t *View_GetRef (view_t view); VIEWINLINE int View_Valid (view_t view); @@ -140,6 +149,7 @@ VIEWINLINE view_pos_t View_GetAbs (view_t view); VIEWINLINE view_pos_t View_GetRel (view_t view); VIEWINLINE void View_SetLen (view_t view, int x, int y); VIEWINLINE view_pos_t View_GetLen (view_t view); +VIEWINLINE viewcont_t* View_Control (view_t view); VIEWINLINE void View_SetGravity (view_t view, grav_t grav); VIEWINLINE grav_t View_GetGravity (view_t view); VIEWINLINE void View_SetVisible (view_t view, int visible); @@ -279,6 +289,16 @@ View_GetLen (view_t view) return len[ref->index]; } +VIEWINLINE +viewcont_t * +View_Control (view_t view) +{ + __auto_type ref = View_GetRef (view); + hierarchy_t *h = ref->hierarchy; + viewcont_t *cont = h->components[view_control]; + return &cont[ref->index]; +} + VIEWINLINE void View_SetGravity (view_t view, grav_t grav) diff --git a/libs/ui/test/Makemodule.am b/libs/ui/test/Makemodule.am index 70972e981..e5827dcea 100644 --- a/libs/ui/test/Makemodule.am +++ b/libs/ui/test/Makemodule.am @@ -1,13 +1,11 @@ libs_ui_tests = \ + libs/ui/test/test-flow \ + libs/ui/test/test-flow-size \ libs/ui/test/test-passage \ libs/ui/test/test-txtbuffer \ libs/ui/test/test-vrect -libs_ui_xfail_tests = \ - libs/ui/test/test-flow \ - libs/ui/test/test-flow-size - -TESTS += $(libs_ui_tests) $(libs_ui_xfail_tests) +TESTS += $(libs_ui_tests) XFAIL_TESTS += $(libs_ui_xfail_tests) diff --git a/libs/ui/test/test-flow-size.c b/libs/ui/test/test-flow-size.c index 88e304653..31e322fb7 100644 --- a/libs/ui/test/test-flow-size.c +++ b/libs/ui/test/test-flow-size.c @@ -4,7 +4,21 @@ #include #include "QF/ui/view.h" -#if 0 + +static ecs_registry_t *test_reg; + +enum { + test_href, +}; + +static const component_t test_components[] = { + [test_href] = { + .size = sizeof (hierref_t), + .create = 0,//create_href, + .name = "href", + }, +}; + typedef struct { struct { int xlen, ylen; @@ -194,50 +208,66 @@ static testdata_t up_left_views[] = { #define up_left_count array_size(up_left_views) static void -print_view (view_t *view) +print_view (view_t view) { + view_t parent = View_GetParent (view); + view_pos_t pos = View_GetPos (view); + view_pos_t len = View_GetLen (view); + view_pos_t rel = View_GetRel (view); + view_pos_t abs = View_GetAbs (view); printf ("%s[%3d %3d %3d %3d %3d %3d %3d %3d]\n", - view->parent ? " " : "****", - view->xpos, view->ypos, view->xlen, view->ylen, - view->xrel, view->yrel, view->xabs, view->yabs); - view_draw (view); + View_Valid (parent) ? " " : "****", + pos.x, pos.y, len.x, len.y, rel.x, rel.y, abs.x, abs.y); } static int -test_flow (testdata_t *child_views, int count, void (*flow) (view_t *)) +test_flow (testdata_t *child_views, int count, void (flow) (view_t, view_pos_t)) { - view_t *flow_view = view_new (0, 0, 256, 256, grav_northwest); - flow_view->setgeometry = flow; - flow_view->flow_size = 1; - flow_view->draw = print_view; + view_t flow_view = View_New (test_reg, nullview); + View_SetPos (flow_view, 0, 0); + View_SetLen (flow_view, 256, 256); + View_SetGravity (flow_view, grav_northwest); + View_SetOnResize (flow_view, flow); + View_Control (flow_view)->flow_size = 1; for (int i = 0; i < count; i++) { testdata_t *td = &child_views[i]; - view_t *child = view_new (0, 0, td->xlen, td->ylen, grav_flow); - child->bol_suppress = td->bol_suppress; - child->draw = print_view; - view_add (flow_view, child); + view_t child = View_New (test_reg, flow_view); + View_SetPos (child, 0, 0); + View_SetLen (child, td->xlen, td->ylen); + View_SetGravity (child, grav_flow); + View_Control (child)->bol_suppress = td->bol_suppress; } - view_move (flow_view, 8, 16); - int ret = 0; + View_SetPos (flow_view, 8, 16); + View_UpdateHierarchy (flow_view); - for (int i = 0; i < flow_view->num_children; i++) { + int ret = 0; + __auto_type ref = View_GetRef (flow_view); + hierarchy_t *h = ref->hierarchy; + uint32_t *childIndex = h->childIndex; + uint32_t *childCount = h->childCount; + uint32_t *ent = h->ent; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *rel = h->components[view_rel]; + view_pos_t *abs = h->components[view_abs]; + for (uint32_t i = 0; i < childCount[ref->index]; i++) { testdata_t *td = &child_views[i]; - view_t *child = flow_view->children[i]; - if (child->xpos != td->expect.xpos - || child->ypos != td->expect.ypos - || child->xrel != td->expect.xrel - || child->yrel != td->expect.yrel - || child->xabs != td->expect.xabs - || child->yabs != td->expect.yabs) { + uint32_t child = childIndex[ref->index] + i; + if (pos[child].x != td->expect.xpos + || pos[child].y != td->expect.ypos + || rel[child].x != td->expect.xrel + || rel[child].y != td->expect.yrel + || abs[child].x != td->expect.xabs + || abs[child].y != td->expect.yabs) { ret = 1; printf ("child %d misflowed:\n" " [%3d %3d %3d %3d %3d %3d]\n", i, td->expect.xpos, td->expect.ypos, td->expect.xrel, td->expect.yrel, td->expect.xabs, td->expect.yabs); - print_view (child); + print_view ((view_t) { .reg = test_reg, .id = ent[child], + .comp = flow_view.comp}); } } return ret; @@ -248,6 +278,10 @@ main (void) { int ret = 0; + test_reg = ECS_NewRegistry (); + ECS_RegisterComponents (test_reg, test_components, 1); + test_reg->href_comp = test_href; + if (test_flow (right_down_views, right_down_count, view_flow_right_down)) { printf ("right-down failed\n"); ret = 1; @@ -283,11 +317,3 @@ main (void) } return ret; } -#endif - -int -main (void) -{ - printf ("FIXME: redo for ECS\n"); - return 1; -} diff --git a/libs/ui/test/test-flow.c b/libs/ui/test/test-flow.c index 520331857..831a35677 100644 --- a/libs/ui/test/test-flow.c +++ b/libs/ui/test/test-flow.c @@ -4,7 +4,21 @@ #include #include "QF/ui/view.h" -#if 0 + +static ecs_registry_t *test_reg; + +enum { + test_href, +}; + +static const component_t test_components[] = { + [test_href] = { + .size = sizeof (hierref_t), + .create = 0,//create_href, + .name = "href", + }, +}; + typedef struct { struct { int xlen, ylen; @@ -194,49 +208,66 @@ static testdata_t up_left_views[] = { #define up_left_count array_size(up_left_views) static void -print_view (view_t *view) +print_view (view_t view) { + view_t parent = View_GetParent (view); + view_pos_t pos = View_GetPos (view); + view_pos_t len = View_GetLen (view); + view_pos_t rel = View_GetRel (view); + view_pos_t abs = View_GetAbs (view); printf ("%s[%3d %3d %3d %3d %3d %3d %3d %3d]\n", - view->parent ? " " : "****", - view->xpos, view->ypos, view->xlen, view->ylen, - view->xrel, view->yrel, view->xabs, view->yabs); - view_draw (view); + View_Valid (parent) ? " " : "****", + pos.x, pos.y, len.x, len.y, rel.x, rel.y, abs.x, abs.y); } static int -test_flow (testdata_t *child_views, int count, void (*flow) (view_t *)) +test_flow (testdata_t *child_views, int count, + void (*flow) (view_t, view_pos_t)) { - view_t *flow_view = view_new (0, 0, 256, 256, grav_northwest); - flow_view->setgeometry = flow; - flow_view->draw = print_view; + view_t flow_view = View_New (test_reg, nullview); + View_SetPos (flow_view, 0, 0); + View_SetLen (flow_view, 256, 256); + View_SetGravity (flow_view, grav_northwest); + View_SetOnResize (flow_view, flow); for (int i = 0; i < count; i++) { testdata_t *td = &child_views[i]; - view_t *child = view_new (0, 0, td->xlen, td->ylen, grav_flow); - child->bol_suppress = td->bol_suppress; - child->draw = print_view; - view_add (flow_view, child); + view_t child = View_New (test_reg, flow_view); + View_SetPos (child, 0, 0); + View_SetLen (child, td->xlen, td->ylen); + View_SetGravity (child, grav_flow); + View_Control (child)->bol_suppress = td->bol_suppress; } - view_move (flow_view, 8, 16); - int ret = 0; + View_SetPos (flow_view, 8, 16); + View_UpdateHierarchy (flow_view); - for (int i = 0; i < flow_view->num_children; i++) { + int ret = 0; + __auto_type ref = View_GetRef (flow_view); + hierarchy_t *h = ref->hierarchy; + uint32_t *childIndex = h->childIndex; + uint32_t *childCount = h->childCount; + uint32_t *ent = h->ent; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *rel = h->components[view_rel]; + view_pos_t *abs = h->components[view_abs]; + for (uint32_t i = 0; i < childCount[ref->index]; i++) { testdata_t *td = &child_views[i]; - view_t *child = flow_view->children[i]; - if (child->xpos != td->expect.xpos - || child->ypos != td->expect.ypos - || child->xrel != td->expect.xrel - || child->yrel != td->expect.yrel - || child->xabs != td->expect.xabs - || child->yabs != td->expect.yabs) { + uint32_t child = childIndex[ref->index] + i; + if (pos[child].x != td->expect.xpos + || pos[child].y != td->expect.ypos + || rel[child].x != td->expect.xrel + || rel[child].y != td->expect.yrel + || abs[child].x != td->expect.xabs + || abs[child].y != td->expect.yabs) { ret = 1; printf ("child %d misflowed:\n" " [%3d %3d %3d %3d %3d %3d]\n", i, td->expect.xpos, td->expect.ypos, td->expect.xrel, td->expect.yrel, td->expect.xabs, td->expect.yabs); - print_view (child); + print_view ((view_t) { .reg = test_reg, .id = ent[child], + .comp = flow_view.comp}); } } return ret; @@ -247,6 +278,10 @@ main (void) { int ret = 0; + test_reg = ECS_NewRegistry (); + ECS_RegisterComponents (test_reg, test_components, 1); + test_reg->href_comp = test_href; + if (test_flow (right_down_views, right_down_count, view_flow_right_down)) { printf ("right-down failed\n"); ret = 1; @@ -282,11 +317,3 @@ main (void) } return ret; } -#endif - -int -main (void) -{ - printf ("FIXME: redo for ECS\n"); - return 1; -} diff --git a/libs/ui/view.c b/libs/ui/view.c index ddd572737..712c237e9 100644 --- a/libs/ui/view.c +++ b/libs/ui/view.c @@ -173,10 +173,17 @@ View_UpdateHierarchy (view_t view) uint32_t *id = h->ent; if (abs[0].x != pos[0].x || abs[0].y != pos[0].y) { - modified[0] = 1; + modified[0] |= 1; abs[0] = pos[0]; rel[0] = pos[0]; } + if (oldlen[0].x != len[0].x || oldlen[0].y != len[0].y) { + modified[0] |= 2; + if (onresize[0]) { + view_t v = { .reg = view.reg, .id = id[0], .comp = view.comp }; + onresize[0] (v, len[0]); + } + } for (uint32_t i = 1; i < h->num_objects; i++) { uint32_t par = parent[i]; if (!(modified[i] & 2) && (modified[par] & 2) @@ -191,6 +198,11 @@ View_UpdateHierarchy (view_t view) if (cont[i].resize_y) { len[i].y += dy; } + if (onresize[i]) { + view_t v = { .reg = view.reg, .id = id[i], + .comp = view.comp }; + onresize[i] (v, len[i]); + } } if (modified[i] || modified[par]) { modified[i] |= 1; // propogate motion modifications @@ -239,16 +251,12 @@ View_UpdateHierarchy (view_t view) } } for (uint32_t i = 0; i < h->num_objects; i++) { - if ((modified[i] & 2) && onresize[i]) { - view_t v = { .reg = view.reg, .id = id[i], .comp = view.comp }; - onresize[i] (v, len[i]); - } if (modified[i] & 2) { oldlen[i] = len[i]; } if ((modified[i] & 1) && onmove[i]) { view_t v = { .reg = view.reg, .id = id[i], .comp = view.comp }; - onresize[i] (v, abs[i]); + onmove[i] (v, abs[i]); } modified[i] = 0; } @@ -289,213 +297,6 @@ View_SetParent (view_t view, view_t parent) modified[ref->index] = 1; View_UpdateHierarchy (view); } -#if 0 -static void -setgeometry (view_t *view) -{ - int i; - view_t *par = view->parent; - - if (!par) { - view->xabs = view->xrel = view->xpos; - view->yabs = view->yrel = view->ypos; - if (view->setgeometry) - view->setgeometry (view); - for (i = 0; i < view->num_children; i++) - setgeometry (view->children[i]); - return; - } - - switch (view->gravity) { - case grav_center: - view->xrel = view->xpos + (par->xlen - view->xlen) / 2; - view->yrel = view->ypos + (par->ylen - view->ylen) / 2; - break; - case grav_north: - view->xrel = view->xpos + (par->xlen - view->xlen) / 2; - view->yrel = view->ypos; - break; - case grav_northeast: - view->xrel = par->xlen - view->xpos - view->xlen; - view->yrel = view->ypos; - break; - case grav_east: - view->xrel = par->xlen - view->xpos - view->xlen; - view->yrel = view->ypos + (par->ylen - view->ylen) / 2; - break; - case grav_southeast: - view->xrel = par->xlen - view->xpos - view->xlen; - view->yrel = par->ylen - view->ypos - view->ylen; - break; - case grav_south: - view->xrel = view->xpos + (par->xlen - view->xlen) / 2; - view->yrel = par->ylen - view->ypos - view->ylen; - break; - case grav_southwest: - view->xrel = view->xpos; - view->yrel = par->ylen - view->ypos - view->ylen; - break; - case grav_west: - view->xrel = view->xpos; - view->yrel = view->ypos + (par->ylen - view->ylen) / 2; - break; - case grav_northwest: - view->xrel = view->xpos; - view->yrel = view->ypos; - break; - case grav_flow: - break; - } - view->xabs = par->xabs + view->xrel; - view->yabs = par->yabs + view->yrel; - if (view->setgeometry) - view->setgeometry (view); - for (i = 0; i < view->num_children; i++) - setgeometry (view->children[i]); -} - -VISIBLE view_t * -view_new_data (int xp, int yp, int xl, int yl, grav_t grav, void *data) -{ - view_t *view = calloc (1, sizeof (view_t)); - view->xpos = xp; - view->ypos = yp; - view->xlen = xl; - view->ylen = yl; - view->gravity = grav; - view->visible = 1; - view->draw = view_draw; - view->data = data; - setgeometry (view); - return view; -} - -VISIBLE view_t * -view_new (int xp, int yp, int xl, int yl, grav_t grav) -{ - return view_new_data (xp, yp, xl, yl, grav, 0); -} - -VISIBLE void -view_insert (view_t *par, view_t *view, int pos) -{ - view->parent = par; - if (pos < 0) - pos = par->num_children + 1 + pos; - if (pos < 0) - pos = 0; - if (pos > par->num_children) - pos = par->num_children; - if (par->num_children == par->max_children) { - par->max_children += 8; - par->children = realloc (par->children, - par->max_children * sizeof (view_t *)); - memset (par->children + par->num_children, 0, - (par->max_children - par->num_children) * sizeof (view_t *)); - } - memmove (par->children + pos + 1, par->children + pos, - (par->num_children - pos) * sizeof (view_t *)); - par->num_children++; - par->children[pos] = view; - setgeometry (view); -} - -VISIBLE void -view_add (view_t *par, view_t *view) -{ - view_insert (par, view, -1); -} - -VISIBLE void -view_remove (view_t *par, view_t *view) -{ - int i; - - for (i = 0; i < par->num_children; i++) { - if (par->children[i] == view) { - memmove (par->children + i, par->children + i + 1, - (par->num_children - i - 1) * sizeof (view_t *)); - par->children [--par->num_children] = 0; - break; - } - } -} - -VISIBLE void -view_delete (view_t *view) -{ - if (view->parent) - view_remove (view->parent, view); - while (view->num_children) - view_delete (view->children[0]); - free (view->children); - free (view); -} - -VISIBLE void -view_draw (view_t *view) -{ - int i; - - for (i = 0; i < view->num_children; i++) { - view_t *v = view->children[i]; - if (v->visible && v->draw) - v->draw (v); - } -} - -static void -_resize (view_t *view, int xl, int yl) -{ - int i, xd, yd; - - xd = xl - view->xlen; - yd = yl - view->ylen; - view->xlen = xl; - view->ylen = yl; - for (i = 0; i < view->num_children; i++) { - view_t *v = view->children[i]; - - if (v->resize_x && v->resize_y) { - _resize (v, v->xlen + xd, v->ylen + yd); - } else if (v->resize_x) { - _resize (v, v->xlen + xd, v->ylen); - } else if (v->resize_y) { - _resize (v, v->xlen, v->ylen + yd); - } - } -} - -VISIBLE void -view_resize (view_t *view, int xl, int yl) -{ - _resize (view, xl, yl); - setgeometry (view); -} - -VISIBLE void -view_move (view_t *view, int xp, int yp) -{ - view->xpos = xp; - view->ypos = yp; - setgeometry (view); -} - -VISIBLE void -view_setgeometry (view_t *view, int xp, int yp, int xl, int yl) -{ - view->xpos = xp; - view->ypos = yp; - _resize (view, xl, yl); - setgeometry (view); -} - -VISIBLE void -view_setgravity (view_t *view, grav_t grav) -{ - view->gravity = grav; - setgeometry (view); -} typedef struct flowline_s { struct flowline_s *next; @@ -514,224 +315,287 @@ typedef struct flowline_s { } while (0) static void -flow_right (view_t *view, void (*set_rows) (view_t *, flowline_t *)) +flow_right (view_t view, void (*set_rows) (view_t, flowline_t *)) { - flowline_t flowline = {}; + __auto_type ref = View_GetRef (view); + hierarchy_t *h = ref->hierarchy; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *len = h->components[view_len]; + viewcont_t *cont = h->components[view_control]; + uint32_t vind = ref->index; + + flowline_t flowline = { .first_child = h->childIndex[ref->index] }; flowline_t *line = &flowline; - for (int i = 0; i < view->num_children; i++) { - view_t *child = view->children[i]; - if (line->cursor && line->cursor + child->xlen > view->xlen) { - NEXT_LINE(line, i); + for (uint32_t i = 0; i < h->childCount[vind]; i++) { + uint32_t child = h->childIndex[vind] + i; + if (line->cursor && line->cursor + len[child].x > len[vind].x) { + NEXT_LINE(line, child); } - child->xpos = line->cursor; - if (child->xpos || !child->bol_suppress) { - line->cursor += child->xlen; + pos[child].x = line->cursor; + if (pos[child].x || !cont[child].bol_suppress) { + line->cursor += len[child].x; } - line->height = max (child->ylen, line->height); + line->height = max (len[child].y, line->height); line->child_count++; } set_rows (view, &flowline); } static void -flow_left (view_t *view, void (*set_rows) (view_t *, flowline_t *)) +flow_left (view_t view, void (*set_rows) (view_t, flowline_t *)) { - flowline_t flowline = {}; + __auto_type ref = View_GetRef (view); + hierarchy_t *h = ref->hierarchy; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *len = h->components[view_len]; + viewcont_t *cont = h->components[view_control]; + uint32_t vind = ref->index; + + flowline_t flowline = { .first_child = h->childIndex[ref->index] }; flowline_t *line = &flowline; - line->cursor = view->xlen; - for (int i = 0; i < view->num_children; i++) { - view_t *child = view->children[i]; - if (line->cursor < view->xlen && line->cursor - child->xlen < 0) { - NEXT_LINE(line, i); - line->cursor = view->xlen; + line->cursor = len[vind].x; + for (uint32_t i = 0; i < h->childCount[vind]; i++) { + uint32_t child = h->childIndex[ref->index] + i; + if (line->cursor < len[vind].x && line->cursor - len[child].x < 0) { + NEXT_LINE(line, child); + line->cursor = len[vind].x; } - if (child->xpos < view->xlen || !child->bol_suppress) { - line->cursor -= child->xlen; + if (pos[child].x < len[vind].x || !cont[child].bol_suppress) { + line->cursor -= len[child].x; } - child->xpos = line->cursor; - line->height = max (child->ylen, line->height); + pos[child].x = line->cursor; + line->height = max (len[child].y, line->height); line->child_count++; } set_rows (view, &flowline); } static void -flow_down (view_t *view, void (*set_rows) (view_t *, flowline_t *)) +flow_down (view_t view, void (*set_rows) (view_t, flowline_t *)) { - flowline_t flowline = {}; + __auto_type ref = View_GetRef (view); + hierarchy_t *h = ref->hierarchy; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *len = h->components[view_len]; + viewcont_t *cont = h->components[view_control]; + uint32_t vind = ref->index; + + flowline_t flowline = { .first_child = h->childIndex[ref->index] }; flowline_t *line = &flowline; - for (int i = 0; i < view->num_children; i++) { - view_t *child = view->children[i]; - if (line->cursor && line->cursor + child->ylen > view->ylen) { - NEXT_LINE(line, i); + for (uint32_t i = 0; i < h->childCount[vind]; i++) { + uint32_t child = h->childIndex[vind] + i; + if (line->cursor && line->cursor + len[child].y > len[vind].y) { + NEXT_LINE(line, child); } - child->ypos = line->cursor; - if (child->ypos || !child->bol_suppress) { - line->cursor += child->ylen; + pos[child].y = line->cursor; + if (pos[child].y || !cont[child].bol_suppress) { + line->cursor += len[child].y; } - line->height = max (child->xlen, line->height); + line->height = max (len[child].x, line->height); line->child_count++; } set_rows (view, &flowline); } static void -flow_up (view_t *view, void (*set_rows) (view_t *, flowline_t *)) +flow_up (view_t view, void (*set_rows) (view_t, flowline_t *)) { - flowline_t flowline = {}; + __auto_type ref = View_GetRef (view); + hierarchy_t *h = ref->hierarchy; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *len = h->components[view_len]; + viewcont_t *cont = h->components[view_control]; + uint32_t vind = ref->index; + + flowline_t flowline = { .first_child = h->childIndex[ref->index] }; flowline_t *line = &flowline; - line->cursor = view->ylen; - for (int i = 0; i < view->num_children; i++) { - view_t *child = view->children[i]; - if (line->cursor < view->ylen && line->cursor - child->ylen < 0) { - NEXT_LINE(line, i); - line->cursor = view->ylen; + line->cursor = len[vind].y; + for (uint32_t i = 0; i < h->childCount[vind]; i++) { + uint32_t child = h->childIndex[ref->index] + i; + if (line->cursor < len[vind].y && line->cursor - len[child].y < 0) { + NEXT_LINE(line, child); + line->cursor = len[vind].y; } - if (child->ypos < view->ylen || !child->bol_suppress) { - line->cursor -= child->ylen; + if (pos[child].y < len[vind].y || !cont[child].bol_suppress) { + line->cursor -= len[child].y; } - child->ypos = line->cursor; - line->height = max (child->xlen, line->height); + pos[child].y = line->cursor; + line->height = max (len[child].x, line->height); line->child_count++; } set_rows (view, &flowline); } static void -flow_view_height (view_t *view, flowline_t *flowlines) +flow_view_height (view_pos_t *len, flowline_t *flowlines) { - if (view->flow_size) { - view->ylen = 0; - for (flowline_t *line = flowlines; line; line = line->next) { - view->ylen += line->height; - } + len->y = 0; + for (flowline_t *line = flowlines; line; line = line->next) { + len->y += line->height; } } static void -flow_view_width (view_t *view, flowline_t *flowlines) +flow_view_width (view_pos_t *len, flowline_t *flowlines) { - if (view->flow_size) { - view->xlen = 0; - for (flowline_t *line = flowlines; line; line = line->next) { - view->xlen += line->height; - } + len->x = 0; + for (flowline_t *line = flowlines; line; line = line->next) { + len->x += line->height; } } static void -set_rows_down (view_t *view, flowline_t *flowlines) +set_rows_down (view_t view, flowline_t *flowlines) { - flow_view_height (view, flowlines); + __auto_type ref = View_GetRef (view); + hierarchy_t *h = ref->hierarchy; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *rel = h->components[view_rel]; + view_pos_t *len = h->components[view_len]; + viewcont_t *cont = h->components[view_control]; + uint32_t vind = ref->index; + + if (cont[vind].flow_size) { + flow_view_height (&len[ref->index], flowlines); + } int cursor = 0; for (flowline_t *line = flowlines; line; line = line->next) { cursor += line->height; for (int i = 0; i < line->child_count; i++) { - view_t *child = view->children[line->first_child + i]; + uint32_t child = line->first_child + i; - child->xrel = child->xpos; - child->yrel = cursor + child->ypos - child->ylen; + rel[child].x = pos[child].x; + rel[child].y = cursor + pos[child].y - len[child].y; } } } static void -set_rows_up (view_t *view, flowline_t *flowlines) +set_rows_up (view_t view, flowline_t *flowlines) { - flow_view_height (view, flowlines); + __auto_type ref = View_GetRef (view); + hierarchy_t *h = ref->hierarchy; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *rel = h->components[view_rel]; + view_pos_t *len = h->components[view_len]; + viewcont_t *cont = h->components[view_control]; + uint32_t vind = ref->index; - int cursor = view->ylen; + if (cont[vind].flow_size) { + flow_view_height (&len[ref->index], flowlines); + } + + int cursor = len[vind].y; for (flowline_t *line = flowlines; line; line = line->next) { for (int i = 0; i < line->child_count; i++) { - view_t *child = view->children[line->first_child + i]; + uint32_t child = line->first_child + i; - child->xrel = child->xpos; - child->yrel = cursor + child->ypos - child->ylen; + rel[child].x = pos[child].x; + rel[child].y = cursor + pos[child].y - len[child].y; } cursor -= line->height; } } static void -set_columns_right (view_t *view, flowline_t *flowlines) +set_columns_right (view_t view, flowline_t *flowlines) { - flow_view_width (view, flowlines); + __auto_type ref = View_GetRef (view); + hierarchy_t *h = ref->hierarchy; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *rel = h->components[view_rel]; + view_pos_t *len = h->components[view_len]; + viewcont_t *cont = h->components[view_control]; + uint32_t vind = ref->index; + + if (cont[vind].flow_size) { + flow_view_width (&len[ref->index], flowlines); + } int cursor = 0; for (flowline_t *line = flowlines; line; line = line->next) { for (int i = 0; i < line->child_count; i++) { - view_t *child = view->children[line->first_child + i]; + uint32_t child = line->first_child + i; - child->xrel = cursor + child->xpos; - child->yrel = child->ypos; + rel[child].x = cursor + pos[child].x; + rel[child].y = pos[child].y; } cursor += line->height; } } static void -set_columns_left (view_t *view, flowline_t *flowlines) +set_columns_left (view_t view, flowline_t *flowlines) { - flow_view_width (view, flowlines); + __auto_type ref = View_GetRef (view); + hierarchy_t *h = ref->hierarchy; + view_pos_t *pos = h->components[view_pos]; + view_pos_t *rel = h->components[view_rel]; + view_pos_t *len = h->components[view_len]; + viewcont_t *cont = h->components[view_control]; + uint32_t vind = ref->index; - int cursor = view->xlen; + if (cont[vind].flow_size) { + flow_view_width (&len[ref->index], flowlines); + } + + int cursor = len[vind].x; for (flowline_t *line = flowlines; line; line = line->next) { cursor -= line->height; for (int i = 0; i < line->child_count; i++) { - view_t *child = view->children[line->first_child + i]; + uint32_t child = line->first_child + i; - child->xrel = cursor + child->xpos; - child->yrel = child->ypos; + rel[child].x = cursor + pos[child].x; + rel[child].y = pos[child].y; } } } VISIBLE void -view_flow_right_down (view_t *view) +view_flow_right_down (view_t view, view_pos_t len) { flow_right (view, set_rows_down); } VISIBLE void -view_flow_right_up (view_t *view) +view_flow_right_up (view_t view, view_pos_t len) { flow_right (view, set_rows_up); } VISIBLE void -view_flow_left_down (view_t *view) +view_flow_left_down (view_t view, view_pos_t len) { flow_left (view, set_rows_down); } VISIBLE void -view_flow_left_up (view_t *view) +view_flow_left_up (view_t view, view_pos_t len) { flow_left (view, set_rows_up); } VISIBLE void -view_flow_down_right (view_t *view) +view_flow_down_right (view_t view, view_pos_t len) { flow_down (view, set_columns_right); } VISIBLE void -view_flow_up_right (view_t *view) +view_flow_up_right (view_t view, view_pos_t len) { flow_up (view, set_columns_right); } VISIBLE void -view_flow_down_left (view_t *view) +view_flow_down_left (view_t view, view_pos_t len) { flow_down (view, set_columns_left); } VISIBLE void -view_flow_up_left (view_t *view) +view_flow_up_left (view_t view, view_pos_t len) { flow_up (view, set_columns_left); } -#endif