diff --git a/include/QF/ui/imui.h b/include/QF/ui/imui.h index 8ab69d0ce..6a761bebb 100644 --- a/include/QF/ui/imui.h +++ b/include/QF/ui/imui.h @@ -36,6 +36,7 @@ typedef struct imui_ctx_s imui_ctx_t; struct canvas_system_s; struct IE_event_s; +struct passage_s; enum { imui_percent_x, ///< int @@ -131,6 +132,8 @@ void IMUI_Style_Fetch (const imui_ctx_t *ctx, imui_style_t *style); void IMUI_Label (imui_ctx_t *ctx, const char *label); void IMUI_Labelf (imui_ctx_t *ctx, const char *fmt, ...)__attribute__((format(PRINTF,2,3))); +void IMUI_Passage (imui_ctx_t *ctx, const char *name, + struct passage_s *passage); bool IMUI_Button (imui_ctx_t *ctx, const char *label); bool IMUI_Checkbox (imui_ctx_t *ctx, bool *flag, const char *label); void IMUI_Radio (imui_ctx_t *ctx, int *curvalue, int value, const char *label); @@ -172,6 +175,9 @@ void IMUI_EndScrollBox (imui_ctx_t *ctx); #define UI_Labelf(fmt...) \ IMUI_Labelf(IMUI_context, fmt) +#define UI_Passage(name, psg) \ + IMUI_Passage(IMUI_context, name, psg) + #define UI_Button(label) \ IMUI_Button(IMUI_context, label) diff --git a/libs/ruamoko/rua_imui.c b/libs/ruamoko/rua_imui.c index 12cd09190..09fd8069c 100644 --- a/libs/ruamoko/rua_imui.c +++ b/libs/ruamoko/rua_imui.c @@ -330,6 +330,15 @@ bi (IMUI_Labelf) IMUI_Label (bi_ctx->imui_ctx, res->dstr->str); } +bi (IMUI_Passage) +{ + qfZoneScoped (true); + auto res = (imui_resources_t *) _res; + auto bi_ctx = get_imui_ctx (P_INT (pr, 0)); + auto passage = RUA_GUI_GetPassage (pr, P_INT (pr, 2)); + IMUI_Passage (bi_ctx->imui_ctx, P_GSTRING (pr, 1), passage); +} + bi (IMUI_Button) { qfZoneScoped (true); @@ -498,6 +507,7 @@ static builtin_t builtins[] = { bi(IMUI_Style_Fetch, 2, p(int), p(ptr)), bi(IMUI_Label, 2, p(int), p(string)), bi(IMUI_Labelf, -3, p(int), p(string)), + bi(IMUI_Passage, 3, p(int), p(string), p(int)), bi(IMUI_Button, 2, p(int), p(string)), bi(IMUI_Checkbox, 3, p(int), p(ptr), p(string)), bi(IMUI_Radio, 4, p(int), p(ptr), p(int), p(string)), diff --git a/libs/ui/imui.c b/libs/ui/imui.c index 4dfa7e811..f49ab7c29 100644 --- a/libs/ui/imui.c +++ b/libs/ui/imui.c @@ -56,8 +56,9 @@ #define c_percent_x (ctx->csys.imui_base + imui_percent_x) #define c_percent_y (ctx->csys.imui_base + imui_percent_y) #define c_reference (ctx->csys.imui_base + imui_reference) +#define t_passage_glyphs (ctx->csys.text_base + text_passage_glyphs) +#define c_passage_glyphs (ctx->csys.base + canvas_passage_glyphs) #define c_glyphs (ctx->csys.base + canvas_glyphs) -#define c_passage_glyphs (ctx->csys.text_base + text_passage_glyphs) #define c_color (ctx->tsys.text_base + text_color) #define c_fill (ctx->csys.base + canvas_fill) @@ -304,9 +305,28 @@ IMUI_NewContext (canvas_system_t canvas_sys, const char *font, float fontsize) return ctx; } +static void +clear_items (imui_ctx_t *ctx) +{ + uint32_t root_ent = ctx->root_view.id; + + // delete the root view (but not the root entity) + Ent_RemoveComponent (root_ent, ctx->root_view.comp, ctx->root_view.reg); + + for (uint32_t i = 0; i < ctx->windows.size; i++) { + auto window = View_FromEntity (ctx->vsys, ctx->windows.a[i]->entity); + View_Delete (window); + } + DARRAY_RESIZE (&ctx->parent_stack, 0); + DARRAY_RESIZE (&ctx->windows, 0); + DARRAY_RESIZE (&ctx->links, 0); + DARRAY_RESIZE (&ctx->style_stack, 0); +} + void IMUI_DestroyContext (imui_ctx_t *ctx) { + clear_items (ctx); for (auto s = ctx->states; s; s = s->next) { free (s->label); } @@ -415,8 +435,7 @@ IMUI_BeginFrame (imui_ctx_t *ctx) uint32_t root_ent = ctx->root_view.id; auto root_size = View_GetLen (ctx->root_view); - // delete and recreate the root view (but not the root entity) - Ent_RemoveComponent (root_ent, ctx->root_view.comp, ctx->root_view.reg); + clear_items (ctx); ctx->root_view = View_AddToEntity (root_ent, ctx->vsys, nullview, true); set_hierarchy_tree_mode (ctx, View_GetRef (ctx->root_view), true); View_SetLen (ctx->root_view, root_size.x, root_size.y); @@ -424,15 +443,7 @@ IMUI_BeginFrame (imui_ctx_t *ctx) ctx->frame_start = Sys_LongTime (); ctx->frame_count++; ctx->current_parent = ctx->root_view; - for (uint32_t i = 0; i < ctx->windows.size; i++) { - auto window = View_FromEntity (ctx->vsys, ctx->windows.a[i]->entity); - View_Delete (window); - } ctx->draw_order = imui_draw_order (ctx->windows.size); - DARRAY_RESIZE (&ctx->parent_stack, 0); - DARRAY_RESIZE (&ctx->windows, 0); - DARRAY_RESIZE (&ctx->links, 0); - DARRAY_RESIZE (&ctx->style_stack, 0); ctx->current_menu = 0; } @@ -493,11 +504,15 @@ dump_tree (hierref_t href, int level, imui_ctx_t *ctx) auto reg = ctx->csys.reg; uint32_t ind = href.index; hierarchy_t *h = Ent_GetComponent (href.id, ecs_hierarchy, reg); + view_pos_t *abs = h->components[view_abs]; view_pos_t *len = h->components[view_len]; auto c = ((viewcont_t *)h->components[view_control])[ind]; uint32_t e = h->ent[ind]; - printf ("%2d: %*s[%s%d %s%d"DFL"] %c %s%d %s%d"DFL, ind, + printf ("%3d:%08x %*s[%s%d %s%d"DFL"] [%s%d %s%d"DFL"] %c %s%d %s%d"DFL, + ind, e, level * 3, "", + view_color (h, ind, ctx, false), abs[ind].x, + view_color (h, ind, ctx, true), abs[ind].y, view_color (h, ind, ctx, false), len[ind].x, view_color (h, ind, ctx, true), len[ind].y, c.vertical ? 'v' : 'h', @@ -516,14 +531,14 @@ dump_tree (hierref_t href, int level, imui_ctx_t *ctx) printf (DFL"\n"); if (c.is_link) { - printf (GRN"%2d: %*slink"DFL"\n", ind, level * 3, ""); + printf (GRN"%3d: %*slink"DFL"\n", ind, 8 + 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, level + 1, ctx); - printf (RED"%2d: %*slink"DFL"\n", ind, level * 3, ""); + printf (RED"%3d: %*slink"DFL"\n", ind, 8 + level * 3, ""); } if (h->childIndex[ind] > ind) { for (uint32_t i = 0; i < h->childCount[ind]; i++) { @@ -1068,7 +1083,7 @@ add_text (imui_ctx_t *ctx, view_t view, imui_state_t *state, int mode) View_SetVisible (text, 1); Ent_SetComponent (text.id, c_glyphs, reg, - Ent_GetComponent (text.id, c_passage_glyphs, reg)); + Ent_GetComponent (text.id, t_passage_glyphs, reg)); len = View_GetLen (text); View_SetLen (view, len.x, len.y); @@ -1143,6 +1158,63 @@ IMUI_Labelf (imui_ctx_t *ctx, const char *fmt, ...) IMUI_Label (ctx, ctx->dstr->str); } +void +IMUI_Passage (imui_ctx_t *ctx, const char *name, struct passage_s *passage) +{ + auto anchor_view = View_New (ctx->vsys, ctx->current_parent); + *View_Control (anchor_view) = (viewcont_t) { + .gravity = grav_northwest, + .visible = 1, + .semantic_x = imui_size_expand, + .semantic_y = imui_size_expand, + .vertical = true, + .active = 1, + }; + auto reg = ctx->csys.reg; + *(int*) Ent_AddComponent (anchor_view.id, c_percent_x, reg) = 100; + *(int*) Ent_AddComponent (anchor_view.id, c_percent_y, reg) = 100; + + auto state = imui_get_state (ctx, name, anchor_view.id); + update_hot_active (ctx, state); + + set_fill (ctx, anchor_view, ctx->style.background.normal); + + auto psg_view = Text_PassageView (ctx->tsys, nullview, + ctx->font, passage); + Canvas_SetReference (ctx->csys, psg_view.id, + Canvas_Entity (ctx->csys, + View_GetRoot (anchor_view).id)); + if (Ent_HasComponent (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_passage_glyphs, reg); + } + Ent_SetComponent (psg_view.id, c_passage_glyphs, reg, + Ent_GetComponent (psg_view.id, t_passage_glyphs, reg)); + *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, + }; + *(int*) Ent_AddComponent (psg_view.id, c_percent_x, ctx->csys.reg) = 100; + *(int*) Ent_AddComponent (psg_view.id, c_percent_y, ctx->csys.reg) = 100; + + View_Control (anchor_view)->is_link = 1; + imui_reference_t link = { + .ref_id = psg_view.id, + }; + Ent_SetComponent (anchor_view.id, c_reference, anchor_view.reg, &link); + + imui_reference_t anchor = { + .ref_id = anchor_view.id, + }; + Ent_SetComponent (psg_view.id, c_reference, psg_view.reg, &anchor); +} + bool IMUI_Button (imui_ctx_t *ctx, const char *label) { diff --git a/ruamoko/include/imui.h b/ruamoko/include/imui.h index 9508b811a..d795ef2a9 100644 --- a/ruamoko/include/imui.h +++ b/ruamoko/include/imui.h @@ -61,6 +61,7 @@ void IMUI_Style_Fetch (imui_ctx_t ctx, imui_style_t *style); void IMUI_Label (imui_ctx_t ctx, string label); void IMUI_Labelf (imui_ctx_t ctx, string fmt, ...); +void IMUI_Passage (imui_ctx_t ctx, string name, int passage); int IMUI_Button (imui_ctx_t ctx, string label); int IMUI_Checkbox (imui_ctx_t ctx, int *flag, string label); void IMUI_Radio (imui_ctx_t ctx, int *curvalue, int value, string label); @@ -96,6 +97,9 @@ void IMUI_EndScrollBox (imui_ctx_t ctx); #define UI_Labelf(fmt...) \ IMUI_Labelf(IMUI_context, fmt) +#define UI_Passage(name, psg) \ + IMUI_Passage(IMUI_context, name, psg) + #define UI_Button(label) \ IMUI_Button(IMUI_context, label) diff --git a/ruamoko/lib/imui.r b/ruamoko/lib/imui.r index 2d26b5454..ae434a136 100644 --- a/ruamoko/lib/imui.r +++ b/ruamoko/lib/imui.r @@ -27,6 +27,7 @@ void IMUI_Style_Fetch (imui_ctx_t ctx, imui_style_t *style) = #0; void IMUI_Label (imui_ctx_t ctx, string label) = #0; void IMUI_Labelf (imui_ctx_t ctx, string fmt, ...) = #0; +void IMUI_Passage (imui_ctx_t ctx, string name, int passage) = #0; int IMUI_Button (imui_ctx_t ctx, string label) = #0; int IMUI_Checkbox (imui_ctx_t ctx, int *flag, string label) = #0; void IMUI_Radio (imui_ctx_t ctx, int *curvalue, int value, string label) = #0;