mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +00:00
[ui] Sort out most of the nested canvas layout issues
Draw order is now stable and sizing is mostly correct.
This commit is contained in:
parent
a50c1d0f81
commit
101c50e3e1
1 changed files with 42 additions and 25 deletions
|
@ -75,6 +75,8 @@ typedef struct imui_state_s {
|
|||
imui_window_t *menu;
|
||||
int32_t draw_order; // for window canvases
|
||||
int32_t draw_group;
|
||||
uint32_t first_link;
|
||||
uint32_t num_links;
|
||||
uint32_t frame_count;
|
||||
uint32_t old_entity;
|
||||
uint32_t entity;
|
||||
|
@ -104,6 +106,7 @@ struct imui_ctx_s {
|
|||
view_t current_parent;
|
||||
struct DARRAY_TYPE(view_t) parent_stack;
|
||||
struct DARRAY_TYPE(imui_state_t *) windows;
|
||||
struct DARRAY_TYPE(imui_state_t *) links;
|
||||
int32_t draw_order;
|
||||
imui_window_t *current_menu;
|
||||
imui_state_t *current_state;
|
||||
|
@ -251,6 +254,7 @@ IMUI_NewContext (canvas_system_t canvas_sys, const char *font, float fontsize)
|
|||
.root_view = Canvas_GetRootView (canvas_sys, canvas),
|
||||
.parent_stack = DARRAY_STATIC_INIT (8),
|
||||
.windows = DARRAY_STATIC_INIT (8),
|
||||
.links = DARRAY_STATIC_INIT (8),
|
||||
.dstr = dstring_newstr (),
|
||||
.hot = nullent,
|
||||
.active = nullent,
|
||||
|
@ -304,6 +308,7 @@ IMUI_DestroyContext (imui_ctx_t *ctx)
|
|||
|
||||
DARRAY_CLEAR (&ctx->parent_stack);
|
||||
DARRAY_CLEAR (&ctx->windows);
|
||||
DARRAY_CLEAR (&ctx->links);
|
||||
DARRAY_CLEAR (&ctx->style_stack);
|
||||
dstring_delete (ctx->dstr);
|
||||
|
||||
|
@ -488,6 +493,16 @@ dump_tree (hierarchy_t *h, uint32_t ind, int level, imui_ctx_t *ctx)
|
|||
}
|
||||
printf (DFL"\n");
|
||||
|
||||
if (c.is_link) {
|
||||
printf (GRN"%2d: %*slink"DFL"\n", ind, level * 3, "");
|
||||
auto reg = ctx->csys.reg;
|
||||
uint32_t ent = h->ent[ind];
|
||||
imui_reference_t *sub = Ent_GetComponent (ent, c_reference, reg);
|
||||
auto sub_view = View_FromEntity (ctx->vsys, sub->ref_id);
|
||||
auto href = View_GetRef (sub_view);
|
||||
dump_tree (href->hierarchy, 0, level + 1, ctx);
|
||||
printf (RED"%2d: %*slink"DFL"\n", ind, level * 3, "");
|
||||
}
|
||||
if (h->childIndex[ind] > ind) {
|
||||
for (uint32_t i = 0; i < h->childCount[ind]; i++) {
|
||||
if (h->childIndex[ind] + i >= h->num_objects) {
|
||||
|
@ -503,7 +518,6 @@ dump_tree (hierarchy_t *h, uint32_t ind, int level, imui_ctx_t *ctx)
|
|||
|
||||
typedef struct {
|
||||
bool x, y;
|
||||
uint32_t ent; // cached reference
|
||||
uint32_t num_views; // number of views in sub-hierarchy
|
||||
} downdep_t;
|
||||
|
||||
|
@ -520,6 +534,9 @@ calc_upwards_dependent (imui_ctx_t *ctx, hierarchy_t *h,
|
|||
|
||||
down_depend[0].num_views = h->num_objects;
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
if (i > 0) {
|
||||
down_depend[i].num_views = 0;
|
||||
}
|
||||
if (cont[i].semantic_x == imui_size_fitchildren
|
||||
|| cont[i].semantic_x == imui_size_expand) {
|
||||
down_depend[i].x = true;
|
||||
|
@ -554,7 +571,6 @@ calc_upwards_dependent (imui_ctx_t *ctx, hierarchy_t *h,
|
|||
auto href = View_GetRef (sub_view);
|
||||
// control logic was propagated from the linked hierarcy, so
|
||||
// propagate down_depend to the linked hierarcy.
|
||||
down_depend[i].num_views = 0;
|
||||
side_depend[0] = down_depend[i];
|
||||
calc_upwards_dependent (ctx, href->hierarchy, side_depend);
|
||||
down_depend[0].num_views += side_depend[0].num_views;
|
||||
|
@ -694,6 +710,8 @@ calc_expansions (imui_ctx_t *ctx, hierarchy_t *h)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
if (cont[i].is_link) {
|
||||
imui_reference_t *sub = Ent_GetComponent (ent[i], c_reference, reg);
|
||||
auto sub_view = View_FromEntity (ctx->vsys, sub->ref_id);
|
||||
|
@ -829,25 +847,6 @@ imui_window_cmp (const void *a, const void *b)
|
|||
return windowa->draw_order - windowb->draw_order;
|
||||
}
|
||||
|
||||
static void
|
||||
set_draw_order (imui_ctx_t *ctx, uint32_t entity, int32_t base)
|
||||
{
|
||||
*Canvas_DrawOrder (ctx->csys, entity) = base;
|
||||
|
||||
auto reg = ctx->csys.reg;
|
||||
auto view = View_FromEntity (ctx->vsys, entity);
|
||||
auto h = View_GetRef (view)->hierarchy;
|
||||
viewcont_t *cont = h->components[view_control];
|
||||
uint32_t *ent = h->ent;
|
||||
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
if (cont[i].is_link) {
|
||||
imui_reference_t *sub = Ent_GetComponent (ent[i], c_reference, reg);
|
||||
set_draw_order (ctx, sub->ref_id, base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sort_windows (imui_ctx_t *ctx)
|
||||
{
|
||||
|
@ -856,7 +855,12 @@ sort_windows (imui_ctx_t *ctx)
|
|||
for (uint32_t i = 0; i < ctx->windows.size; i++) {
|
||||
auto window = ctx->windows.a[i];
|
||||
window->draw_order = imui_draw_order (i + 1);
|
||||
set_draw_order (ctx, window->entity, window->draw_order);
|
||||
*Canvas_DrawOrder (ctx->csys, window->entity) = window->draw_order;
|
||||
for (uint32_t j = 0; j < window->num_links; j++) {
|
||||
auto link = ctx->links.a[window->first_link + j];
|
||||
link->draw_order = window->draw_order + j + 1;
|
||||
*Canvas_DrawOrder (ctx->csys, link->entity) = link->draw_order;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1398,6 +1402,8 @@ IMUI_StartPanel (imui_ctx_t *ctx, imui_window_t *panel)
|
|||
gravity = panel->reference_gravity;
|
||||
}
|
||||
|
||||
state->first_link = ctx->links.size;
|
||||
state->num_links = 0;
|
||||
DARRAY_APPEND (&ctx->windows, state);
|
||||
|
||||
if (!state->draw_order) {
|
||||
|
@ -1638,7 +1644,15 @@ int
|
|||
IMUI_StartScrollBox (imui_ctx_t *ctx, const char *name)
|
||||
{
|
||||
auto anchor_view = View_New (ctx->vsys, ctx->current_parent);
|
||||
set_control (ctx, anchor_view, true);
|
||||
*View_Control (anchor_view) = (viewcont_t) {
|
||||
.gravity = grav_northwest,
|
||||
.visible = 1,
|
||||
.semantic_x = imui_size_expand,
|
||||
.semantic_y = imui_size_expand,
|
||||
.active = 0,
|
||||
};
|
||||
*(int*) Ent_AddComponent (anchor_view.id, c_percent_x, ctx->csys.reg) = 100;
|
||||
*(int*) Ent_AddComponent (anchor_view.id, c_percent_y, ctx->csys.reg) = 100;
|
||||
|
||||
auto panel = ctx->windows.a[ctx->windows.size - 1];
|
||||
|
||||
|
@ -1649,6 +1663,9 @@ IMUI_StartScrollBox (imui_ctx_t *ctx, const char *name)
|
|||
auto state = imui_get_state (ctx, name, scroll_box.id);
|
||||
update_hot_active (ctx, state);
|
||||
|
||||
DARRAY_APPEND (&ctx->links, state);
|
||||
panel->num_links++;
|
||||
|
||||
DARRAY_APPEND (&ctx->parent_stack, ctx->current_parent);
|
||||
|
||||
auto ref = View_GetRef (scroll_box);
|
||||
|
@ -1673,8 +1690,8 @@ IMUI_StartScrollBox (imui_ctx_t *ctx, const char *name)
|
|||
*View_Control (scroll_box) = (viewcont_t) {
|
||||
.gravity = grav_northwest,
|
||||
.visible = 1,
|
||||
.semantic_x = imui_size_expand,
|
||||
.semantic_y = imui_size_expand,
|
||||
.semantic_x = imui_size_pixels,
|
||||
.semantic_y = imui_size_pixels,
|
||||
.free_x = 1,
|
||||
.free_y = 1,
|
||||
.vertical = true,
|
||||
|
|
Loading…
Reference in a new issue