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;
|
imui_window_t *menu;
|
||||||
int32_t draw_order; // for window canvases
|
int32_t draw_order; // for window canvases
|
||||||
int32_t draw_group;
|
int32_t draw_group;
|
||||||
|
uint32_t first_link;
|
||||||
|
uint32_t num_links;
|
||||||
uint32_t frame_count;
|
uint32_t frame_count;
|
||||||
uint32_t old_entity;
|
uint32_t old_entity;
|
||||||
uint32_t entity;
|
uint32_t entity;
|
||||||
|
@ -104,6 +106,7 @@ struct imui_ctx_s {
|
||||||
view_t current_parent;
|
view_t current_parent;
|
||||||
struct DARRAY_TYPE(view_t) parent_stack;
|
struct DARRAY_TYPE(view_t) parent_stack;
|
||||||
struct DARRAY_TYPE(imui_state_t *) windows;
|
struct DARRAY_TYPE(imui_state_t *) windows;
|
||||||
|
struct DARRAY_TYPE(imui_state_t *) links;
|
||||||
int32_t draw_order;
|
int32_t draw_order;
|
||||||
imui_window_t *current_menu;
|
imui_window_t *current_menu;
|
||||||
imui_state_t *current_state;
|
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),
|
.root_view = Canvas_GetRootView (canvas_sys, canvas),
|
||||||
.parent_stack = DARRAY_STATIC_INIT (8),
|
.parent_stack = DARRAY_STATIC_INIT (8),
|
||||||
.windows = DARRAY_STATIC_INIT (8),
|
.windows = DARRAY_STATIC_INIT (8),
|
||||||
|
.links = DARRAY_STATIC_INIT (8),
|
||||||
.dstr = dstring_newstr (),
|
.dstr = dstring_newstr (),
|
||||||
.hot = nullent,
|
.hot = nullent,
|
||||||
.active = nullent,
|
.active = nullent,
|
||||||
|
@ -304,6 +308,7 @@ IMUI_DestroyContext (imui_ctx_t *ctx)
|
||||||
|
|
||||||
DARRAY_CLEAR (&ctx->parent_stack);
|
DARRAY_CLEAR (&ctx->parent_stack);
|
||||||
DARRAY_CLEAR (&ctx->windows);
|
DARRAY_CLEAR (&ctx->windows);
|
||||||
|
DARRAY_CLEAR (&ctx->links);
|
||||||
DARRAY_CLEAR (&ctx->style_stack);
|
DARRAY_CLEAR (&ctx->style_stack);
|
||||||
dstring_delete (ctx->dstr);
|
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");
|
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) {
|
if (h->childIndex[ind] > ind) {
|
||||||
for (uint32_t i = 0; i < h->childCount[ind]; i++) {
|
for (uint32_t i = 0; i < h->childCount[ind]; i++) {
|
||||||
if (h->childIndex[ind] + i >= h->num_objects) {
|
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 {
|
typedef struct {
|
||||||
bool x, y;
|
bool x, y;
|
||||||
uint32_t ent; // cached reference
|
|
||||||
uint32_t num_views; // number of views in sub-hierarchy
|
uint32_t num_views; // number of views in sub-hierarchy
|
||||||
} downdep_t;
|
} downdep_t;
|
||||||
|
|
||||||
|
@ -520,6 +534,9 @@ calc_upwards_dependent (imui_ctx_t *ctx, hierarchy_t *h,
|
||||||
|
|
||||||
down_depend[0].num_views = h->num_objects;
|
down_depend[0].num_views = h->num_objects;
|
||||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
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
|
if (cont[i].semantic_x == imui_size_fitchildren
|
||||||
|| cont[i].semantic_x == imui_size_expand) {
|
|| cont[i].semantic_x == imui_size_expand) {
|
||||||
down_depend[i].x = true;
|
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);
|
auto href = View_GetRef (sub_view);
|
||||||
// control logic was propagated from the linked hierarcy, so
|
// control logic was propagated from the linked hierarcy, so
|
||||||
// propagate down_depend to the linked hierarcy.
|
// propagate down_depend to the linked hierarcy.
|
||||||
down_depend[i].num_views = 0;
|
|
||||||
side_depend[0] = down_depend[i];
|
side_depend[0] = down_depend[i];
|
||||||
calc_upwards_dependent (ctx, href->hierarchy, side_depend);
|
calc_upwards_dependent (ctx, href->hierarchy, side_depend);
|
||||||
down_depend[0].num_views += side_depend[0].num_views;
|
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) {
|
if (cont[i].is_link) {
|
||||||
imui_reference_t *sub = Ent_GetComponent (ent[i], c_reference, reg);
|
imui_reference_t *sub = Ent_GetComponent (ent[i], c_reference, reg);
|
||||||
auto sub_view = View_FromEntity (ctx->vsys, sub->ref_id);
|
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;
|
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
|
static void
|
||||||
sort_windows (imui_ctx_t *ctx)
|
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++) {
|
for (uint32_t i = 0; i < ctx->windows.size; i++) {
|
||||||
auto window = ctx->windows.a[i];
|
auto window = ctx->windows.a[i];
|
||||||
window->draw_order = imui_draw_order (i + 1);
|
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;
|
gravity = panel->reference_gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state->first_link = ctx->links.size;
|
||||||
|
state->num_links = 0;
|
||||||
DARRAY_APPEND (&ctx->windows, state);
|
DARRAY_APPEND (&ctx->windows, state);
|
||||||
|
|
||||||
if (!state->draw_order) {
|
if (!state->draw_order) {
|
||||||
|
@ -1638,7 +1644,15 @@ int
|
||||||
IMUI_StartScrollBox (imui_ctx_t *ctx, const char *name)
|
IMUI_StartScrollBox (imui_ctx_t *ctx, const char *name)
|
||||||
{
|
{
|
||||||
auto anchor_view = View_New (ctx->vsys, ctx->current_parent);
|
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];
|
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);
|
auto state = imui_get_state (ctx, name, scroll_box.id);
|
||||||
update_hot_active (ctx, state);
|
update_hot_active (ctx, state);
|
||||||
|
|
||||||
|
DARRAY_APPEND (&ctx->links, state);
|
||||||
|
panel->num_links++;
|
||||||
|
|
||||||
DARRAY_APPEND (&ctx->parent_stack, ctx->current_parent);
|
DARRAY_APPEND (&ctx->parent_stack, ctx->current_parent);
|
||||||
|
|
||||||
auto ref = View_GetRef (scroll_box);
|
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) {
|
*View_Control (scroll_box) = (viewcont_t) {
|
||||||
.gravity = grav_northwest,
|
.gravity = grav_northwest,
|
||||||
.visible = 1,
|
.visible = 1,
|
||||||
.semantic_x = imui_size_expand,
|
.semantic_x = imui_size_pixels,
|
||||||
.semantic_y = imui_size_expand,
|
.semantic_y = imui_size_pixels,
|
||||||
.free_x = 1,
|
.free_x = 1,
|
||||||
.free_y = 1,
|
.free_y = 1,
|
||||||
.vertical = true,
|
.vertical = true,
|
||||||
|
|
Loading…
Reference in a new issue