[ui] Move passage paragraph placement into text handling

This allows the passage view to be sized properly during imui's layout
phase.
This commit is contained in:
Bill Currie 2024-01-08 08:51:18 +09:00
parent ab702d7fb7
commit 97a83bf1ed
4 changed files with 66 additions and 41 deletions

View file

@ -83,6 +83,7 @@ typedef struct viewcont_s {
unsigned resize_y:1; ///< If true, view's height follows parent's.
unsigned bol_suppress:1; ///< If true, view_flow skips at start of line.
unsigned flow_size:1; ///< If true, view's size is adjusted to flow.
unsigned flow_parent:1; ///< If true, parent's size is adjusted to flow.
unsigned semantic_x:3; ///< layout size control (imui_size_t)
unsigned semantic_y:3; ///< layout size control (imui_size_t)
unsigned free_x:1; ///< don't set position automatically

View file

@ -1220,34 +1220,6 @@ IMUI_Labelf (imui_ctx_t *ctx, const char *fmt, ...)
IMUI_Label (ctx, ctx->dstr->str);
}
static void
passage_update (view_t psgview, void *data)
{
auto reg = psgview.reg;
auto href = View_GetRef (psgview);
hierarchy_t *h = Ent_GetComponent (href.id, ecs_hierarchy, reg);
view_pos_t *abs = h->components[view_abs];
view_pos_t *rel = h->components[view_rel];
view_pos_t *len = h->components[view_len];
uint32_t *parentIndex = h->parentIndex;
uint32_t *childIndex = h->childIndex;
uint32_t *childCount = h->childCount;
// all paragraph views are children of the root view
int y = 0;
for (uint32_t i = 0; i < childCount[0]; i++) {
uint32_t ind = childIndex[0] + i;
// x is already correct
rel[ind].y = y;
y += len[ind].y + 10; //FIXME style
}
for (uint32_t i = 1; i < h->num_objects; i++) {
uint32_t par = parentIndex[i];
// x is already correct
abs[i].y = rel[i].y + abs[par].y;
}
}
void
IMUI_Passage (imui_ctx_t *ctx, const char *name, struct passage_s *passage)
{
@ -1266,7 +1238,8 @@ IMUI_Passage (imui_ctx_t *ctx, const char *name, struct passage_s *passage)
Ent_SetComponent (anchor_view.id, c_fraction_y, reg,
&(imui_frac_t) { 100, 100 });
auto state = imui_get_state (ctx, name, anchor_view.id);
auto state = imui_get_state (ctx, va (0, "%s#passage_anchor", name),
anchor_view.id);
update_hot_active (ctx, state);
set_fill (ctx, anchor_view, ctx->style.background.normal);
@ -1278,26 +1251,16 @@ IMUI_Passage (imui_ctx_t *ctx, const char *name, struct passage_s *passage)
View_GetRoot (anchor_view).id));
// FIXME this shouldn't be necessary and is a sign of bigger problems
Ent_RemoveComponent (psg_view.id, c_passage_glyphs, reg);
// FIXME this shouldn't be necessary and is a sign of bigger problems
Ent_RemoveComponent (psg_view.id, c_updateonce, reg);
Ent_SetComponent (psg_view.id, c_passage_glyphs, reg,
Ent_GetComponent (psg_view.id, t_passage_glyphs, reg));
Ent_SetComponent (psg_view.id, c_updateonce, reg,
&(canvas_update_t) { .update = passage_update });
*View_Control (psg_view) = (viewcont_t) {
.gravity = grav_northwest,
.visible = 1,
.semantic_x = imui_size_expand,
.semantic_y = imui_size_expand,
.free_x = 1,
.free_y = 1,
.vertical = true,
.active = 1,
};
Ent_SetComponent (psg_view.id, c_fraction_x, ctx->csys.reg,
&(imui_frac_t) { 100, 100 });
Ent_SetComponent (psg_view.id, c_fraction_y, ctx->csys.reg,
&(imui_frac_t) { 100, 100 });
View_Control (anchor_view)->is_link = 1;
imui_reference_t link = {

View file

@ -104,7 +104,7 @@ typedef struct glyphnode_s {
int maxs[2];
} glyphnode_t;
static view_resize_f text_flow_funcs[] = {
static view_resize_f para_flow_funcs[] = {
[text_right_down] = view_flow_right_down,
[text_left_down] = view_flow_left_down,
[text_down_right] = view_flow_down_right,
@ -115,6 +115,35 @@ static view_resize_f text_flow_funcs[] = {
[text_up_left] = view_flow_up_left,
};
static void
text_flow_vertical (view_t view, view_pos_t len)
{
auto ref = View_GetRef (view);
hierarchy_t *h = Ent_GetComponent (ref.id, ecs_hierarchy, view.reg);
view_pos_t *vlen = h->components[view_len];
vlen[ref.index].y = 0;
}
static void
text_flow_horizontal (view_t view, view_pos_t len)
{
auto ref = View_GetRef (view);
hierarchy_t *h = Ent_GetComponent (ref.id, ecs_hierarchy, view.reg);
view_pos_t *vlen = h->components[view_len];
vlen[ref.index].x = 0;
}
static view_resize_f text_flow_funcs[] = {
[text_right_down] = text_flow_vertical,
[text_left_down] = text_flow_vertical,
[text_down_right] = text_flow_horizontal,
[text_up_right] = text_flow_horizontal,
[text_right_up] = text_flow_vertical,
[text_left_up] = text_flow_vertical,
[text_down_left] = text_flow_horizontal,
[text_up_left] = text_flow_horizontal,
};
static void
layout_glyphs (glyphnode_t *node, font_t *font, unsigned glpyhCount,
const hb_glyph_info_t *glyphInfo,
@ -271,6 +300,7 @@ Text_PassageView (text_system_t textsys, view_t parent,
}
view_t passage_view = View_AddToEntity (h->ent[0], viewsys, parent,
false);
View_SetOnResize (passage_view, text_flow_funcs[psg_script.direction]);
h = Ent_GetComponent (passage->hierarchy, ecs_hierarchy, reg);
glyphref_t passage_ref = {};
glyphobj_t *glyphs = malloc (glyph_count * sizeof (glyphobj_t));
@ -281,6 +311,8 @@ Text_PassageView (text_system_t textsys, view_t parent,
uint32_t paragraph = h->childIndex[0] + i;
view_t paraview = View_AddToEntity (h->ent[paragraph], viewsys,
passage_view, false);
View_Control (paraview)->free_x = 1;
View_Control (paraview)->free_y = 1;
h = Ent_GetComponent (passage->hierarchy, ecs_hierarchy, reg);
glyphref_t pararef = { .start = passage_ref.count };
for (uint32_t j = 0; j < h->childCount[paragraph]; j++, g = g->next) {
@ -303,10 +335,11 @@ Text_PassageView (text_system_t textsys, view_t parent,
reg);
para_direction = s->direction;
}
View_SetOnResize (paraview, text_flow_funcs[para_direction]);
View_SetOnResize (paraview, para_flow_funcs[para_direction]);
View_SetResize (paraview, !psg_vertical, psg_vertical);
View_SetGravity (paraview, grav_northwest);
View_Control (paraview)->flow_size = 1;
View_Control (paraview)->flow_parent = 1;
}
Ent_SetComponent (passage_view.id, c_glyphs, reg, &passage_ref);
glyphset_t glyphset = {

View file

@ -428,6 +428,22 @@ flow_up (view_t view, void (*set_rows) (view_t, flowline_t *))
set_rows (view, &flowline);
}
static void
flow_view_vertical (view_pos_t *pos, view_pos_t *len,
uint32_t vind, uint32_t pind)
{
pos[vind].y = len[pind].y;
len[pind].y += len[vind].y;
}
static void
flow_view_horizontal (view_pos_t *pos, view_pos_t *len,
uint32_t vind, uint32_t pind)
{
pos[vind].x = len[pind].x;
len[pind].x += len[vind].x;
}
static void
flow_view_height (view_pos_t *len, flowline_t *flowlines)
{
@ -459,6 +475,9 @@ set_rows_down (view_t view, flowline_t *flowlines)
if (cont[vind].flow_size) {
flow_view_height (&len[ref.index], flowlines);
if (cont[vind].flow_parent) {
flow_view_vertical (pos, len, vind, h->parentIndex[vind]);
}
}
int cursor = 0;
@ -487,6 +506,9 @@ set_rows_up (view_t view, flowline_t *flowlines)
if (cont[vind].flow_size) {
flow_view_height (&len[ref.index], flowlines);
if (cont[vind].flow_parent) {
flow_view_vertical (pos, len, vind, h->parentIndex[vind]);
}
}
int cursor = len[vind].y;
@ -515,6 +537,9 @@ set_columns_right (view_t view, flowline_t *flowlines)
if (cont[vind].flow_size) {
flow_view_width (&len[ref.index], flowlines);
if (cont[vind].flow_parent) {
flow_view_horizontal (pos, len, vind, h->parentIndex[vind]);
}
}
int cursor = 0;
@ -543,6 +568,9 @@ set_columns_left (view_t view, flowline_t *flowlines)
if (cont[vind].flow_size) {
flow_view_width (&len[ref.index], flowlines);
if (cont[vind].flow_parent) {
flow_view_horizontal (pos, len, vind, h->parentIndex[vind]);
}
}
int cursor = len[vind].x;