mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 04:31:35 +00:00
[ui] Implement nested canvases
This is for scroll boxes (the nesting of canvases is for the clipping they provide). There are some issues with automatic layout, but this gets things mostly working, in particular the management of the link between hierarchies as a canvas is always the root of its hierarchy.
This commit is contained in:
parent
6faa78eaa1
commit
a50c1d0f81
5 changed files with 263 additions and 51 deletions
|
@ -71,8 +71,13 @@ typedef struct imui_style_s {
|
|||
imui_color_t text;
|
||||
} imui_style_t;
|
||||
|
||||
// on a root view, this points to a pseudo-parent
|
||||
// on a non-root view, this points to a pseudo-child (layout info is taken from
|
||||
// the reference to set the non-root view's size, then that is propagated back
|
||||
// to the reference)
|
||||
typedef struct imui_reference_s {
|
||||
uint32_t ref_id;
|
||||
struct imui_ctx_s *ctx; // owns entity if not null
|
||||
} imui_reference_t;
|
||||
|
||||
typedef struct imui_window_s {
|
||||
|
@ -153,6 +158,9 @@ void IMUI_CloseButton (imui_ctx_t *ctx, imui_window_t *window);
|
|||
int IMUI_StartWindow (imui_ctx_t *ctx, imui_window_t *window);
|
||||
void IMUI_EndWindow (imui_ctx_t *ctx);
|
||||
|
||||
int IMUI_StartScrollBox (imui_ctx_t *ctx, const char *name);
|
||||
void IMUI_EndScrollBox (imui_ctx_t *ctx);
|
||||
|
||||
#define IMUI_DeferLoop(begin, end) \
|
||||
for (int _i_ = (begin); !_i_; _i_++, (end))
|
||||
|
||||
|
@ -206,6 +214,10 @@ void IMUI_EndWindow (imui_ctx_t *ctx);
|
|||
IMUI_DeferLoop (IMUI_StartWindow (IMUI_context, window), \
|
||||
IMUI_EndWindow (IMUI_context))
|
||||
|
||||
#define UI_ScrollBox(name) \
|
||||
IMUI_DeferLoop (IMUI_StartScrollBox (IMUI_context, name), \
|
||||
IMUI_EndScrollBox (IMUI_context))
|
||||
|
||||
#define UI_Style(style) \
|
||||
IMUI_DeferLoop (IMUI_PushStyle (IMUI_context, style), \
|
||||
IMUI_PopStyle (IMUI_context ))
|
||||
|
|
|
@ -411,6 +411,21 @@ bi (IMUI_EndWindow)
|
|||
IMUI_EndWindow (bi_ctx->imui_ctx);
|
||||
}
|
||||
|
||||
bi (IMUI_StartScrollBox)
|
||||
{
|
||||
auto res = (imui_resources_t *) _res;
|
||||
auto bi_ctx = get_imui_ctx (P_INT (pr, 0));
|
||||
const char *name = P_GSTRING (pr, 1);
|
||||
R_INT (pr) = IMUI_StartScrollBox (bi_ctx->imui_ctx, name);
|
||||
}
|
||||
|
||||
bi (IMUI_EndScrollBox)
|
||||
{
|
||||
auto res = (imui_resources_t *) _res;
|
||||
auto bi_ctx = get_imui_ctx (P_INT (pr, 0));
|
||||
IMUI_EndScrollBox (bi_ctx->imui_ctx);
|
||||
}
|
||||
|
||||
#undef bi
|
||||
#define bi(x,np,params...) {#x, bi_##x, -1, np, {params}}
|
||||
#define p(type) PR_PARAM(type)
|
||||
|
@ -426,7 +441,7 @@ static builtin_t builtins[] = {
|
|||
bi(IMUI_DestroyContext, 2, p(int)),
|
||||
bi(IMUI_SetVisible, 2, p(int), p(int)),
|
||||
bi(IMUI_SetSize, 3, p(int), p(int), p(int)),
|
||||
bi(IMUI_ProcessEvent, 3, p(int), p(ptr)),
|
||||
bi(IMUI_ProcessEvent, 2, p(int), p(ptr)),
|
||||
bi(IMUI_BeginFrame, 1, p(int)),
|
||||
bi(IMUI_Draw, 1, p(int)),
|
||||
bi(IMUI_PushLayout, 2, p(int), p(int)),
|
||||
|
@ -445,14 +460,16 @@ static builtin_t builtins[] = {
|
|||
bi(IMUI_Slider, 5, p(int), p(ptr), p(float), p(float), p(string)),
|
||||
bi(IMUI_Spacer, 5, p(int), p(int), p(int), p(int), p(int)),
|
||||
bi(IMUI_FlexibleSpace, 1, p(int)),
|
||||
bi(IMUI_StartPanel, 3, p(int), p(ptr)),
|
||||
bi(IMUI_StartPanel, 2, p(int), p(ptr)),
|
||||
bi(IMUI_ExtendPanel, 3, p(int), p(string)),
|
||||
bi(IMUI_EndPanel, 1, p(int)),
|
||||
bi(IMUI_StartMenu, 3, p(int), p(ptr), p(int)),
|
||||
bi(IMUI_EndMenu, 1, p(int)),
|
||||
bi(IMUI_MenuItem, 3, p(int), p(string), p(int)),
|
||||
bi(IMUI_StartWindow, 3, p(int), p(ptr)),
|
||||
bi(IMUI_StartWindow, 2, p(int), p(ptr)),
|
||||
bi(IMUI_EndWindow, 1, p(int)),
|
||||
bi(IMUI_StartScrollBox, 1, p(int)),
|
||||
bi(IMUI_EndScrollBox, 1, p(int)),
|
||||
|
||||
{0}
|
||||
};
|
||||
|
|
268
libs/ui/imui.c
268
libs/ui/imui.c
|
@ -66,21 +66,6 @@
|
|||
#define imui_ontop imui_draw_order((1 << 15) - 1)
|
||||
#define imui_onbottom imui_draw_order(-(1 << 15) + 1)
|
||||
|
||||
const component_t imui_components[imui_comp_count] = {
|
||||
[imui_percent_x] = {
|
||||
.size = sizeof (int),
|
||||
.name = "percent x",
|
||||
},
|
||||
[imui_percent_y] = {
|
||||
.size = sizeof (int),
|
||||
.name = "percent y",
|
||||
},
|
||||
[imui_reference] = {
|
||||
.size = sizeof (imui_reference_t),
|
||||
.name = "reference",
|
||||
},
|
||||
};
|
||||
|
||||
typedef struct imui_state_s {
|
||||
struct imui_state_s *next;
|
||||
struct imui_state_s **prev;
|
||||
|
@ -140,6 +125,31 @@ struct imui_ctx_s {
|
|||
struct DARRAY_TYPE(imui_style_t) style_stack;
|
||||
};
|
||||
|
||||
static void
|
||||
imui_reference_destroy (void *_ref)
|
||||
{
|
||||
imui_reference_t *ref = _ref;
|
||||
if (ref->ctx) {
|
||||
ECS_DelEntity (ref->ctx->csys.reg, ref->ref_id);
|
||||
}
|
||||
}
|
||||
|
||||
const component_t imui_components[imui_comp_count] = {
|
||||
[imui_percent_x] = {
|
||||
.size = sizeof (int),
|
||||
.name = "percent x",
|
||||
},
|
||||
[imui_percent_y] = {
|
||||
.size = sizeof (int),
|
||||
.name = "percent y",
|
||||
},
|
||||
[imui_reference] = {
|
||||
.size = sizeof (imui_reference_t),
|
||||
.name = "reference",
|
||||
.destroy = imui_reference_destroy,
|
||||
},
|
||||
};
|
||||
|
||||
static int32_t
|
||||
imui_next_window (imui_ctx_t *ctx)
|
||||
{
|
||||
|
@ -356,17 +366,38 @@ IMUI_GetIO (imui_ctx_t *ctx)
|
|||
};
|
||||
}
|
||||
|
||||
static void
|
||||
set_hierarchy_tree_mode (imui_ctx_t *ctx, hierarchy_t *h, bool tree)
|
||||
{
|
||||
Hierarchy_SetTreeMode (h, tree);
|
||||
|
||||
auto reg = ctx->csys.reg;
|
||||
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);
|
||||
auto sub_view = View_FromEntity (ctx->vsys, sub->ref_id);
|
||||
auto href = View_GetRef (sub_view);
|
||||
set_hierarchy_tree_mode (ctx, href->hierarchy, tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IMUI_BeginFrame (imui_ctx_t *ctx)
|
||||
{
|
||||
Shaper_FlushUnused (ctx->shaper);
|
||||
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);
|
||||
ctx->root_view = View_AddToEntity (root_ent, ctx->vsys, nullview);
|
||||
auto ref = View_GetRef (ctx->root_view);
|
||||
Hierarchy_SetTreeMode (ref->hierarchy, true);
|
||||
set_hierarchy_tree_mode (ctx, ref->hierarchy, true);
|
||||
View_SetLen (ctx->root_view, root_size.x, root_size.y);
|
||||
|
||||
ctx->frame_start = Sys_LongTime ();
|
||||
ctx->frame_count++;
|
||||
ctx->current_parent = ctx->root_view;
|
||||
|
@ -471,26 +502,28 @@ dump_tree (hierarchy_t *h, uint32_t ind, int level, imui_ctx_t *ctx)
|
|||
}
|
||||
|
||||
typedef struct {
|
||||
bool x, y;
|
||||
} boolpair_t;
|
||||
bool x, y;
|
||||
uint32_t ent; // cached reference
|
||||
uint32_t num_views; // number of views in sub-hierarchy
|
||||
} downdep_t;
|
||||
|
||||
static void
|
||||
calc_upwards_dependent (imui_ctx_t *ctx, hierarchy_t *h,
|
||||
boolpair_t *down_depend)
|
||||
downdep_t *down_depend)
|
||||
{
|
||||
auto reg = ctx->csys.reg;
|
||||
uint32_t *ent = h->ent;
|
||||
view_pos_t *len = h->components[view_len];
|
||||
viewcont_t *cont = h->components[view_control];
|
||||
uint32_t *parent = h->parentIndex;
|
||||
downdep_t *side_depend = down_depend + h->num_objects;
|
||||
|
||||
down_depend[0].num_views = h->num_objects;
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
if (down_depend
|
||||
&& (cont[i].semantic_x == imui_size_fitchildren
|
||||
|| cont[i].semantic_x == imui_size_expand)) {
|
||||
if (cont[i].semantic_x == imui_size_fitchildren
|
||||
|| cont[i].semantic_x == imui_size_expand) {
|
||||
down_depend[i].x = true;
|
||||
} else if ((!down_depend
|
||||
|| !(i > 0
|
||||
&& (down_depend[i].x = down_depend[parent[i]].x)))
|
||||
} else if (!(i > 0 && (down_depend[i].x = down_depend[parent[i]].x))
|
||||
&& cont[i].semantic_x == imui_size_percent) {
|
||||
int *percent = Ent_GetComponent (ent[i], c_percent_x, reg);
|
||||
int x = (len[parent[i]].x * *percent) / 100;
|
||||
|
@ -501,13 +534,10 @@ calc_upwards_dependent (imui_ctx_t *ctx, hierarchy_t *h,
|
|||
len[i].x = *pixels;
|
||||
down_depend[i].x = false;
|
||||
}
|
||||
if (down_depend
|
||||
&& (cont[i].semantic_y == imui_size_fitchildren
|
||||
|| cont[i].semantic_y == imui_size_expand)) {
|
||||
if (cont[i].semantic_y == imui_size_fitchildren
|
||||
|| cont[i].semantic_y == imui_size_expand) {
|
||||
down_depend[i].y = true;
|
||||
} else if ((!down_depend
|
||||
|| !(i > 0
|
||||
&& (down_depend[i].y = down_depend[parent[i]].y)))
|
||||
} else if (!(i > 0 && (down_depend[i].y = down_depend[parent[i]].y))
|
||||
&& cont[i].semantic_y == imui_size_percent) {
|
||||
int *percent = Ent_GetComponent (ent[i], c_percent_y, reg);
|
||||
int y = (len[parent[i]].y * *percent) / 100;
|
||||
|
@ -518,15 +548,36 @@ calc_upwards_dependent (imui_ctx_t *ctx, hierarchy_t *h,
|
|||
len[i].y = *pixels;
|
||||
down_depend[i].y = false;
|
||||
}
|
||||
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);
|
||||
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;
|
||||
side_depend += side_depend[0].num_views;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
calc_downwards_dependent (hierarchy_t *h)
|
||||
calc_downwards_dependent (imui_ctx_t *ctx, hierarchy_t *h)
|
||||
{
|
||||
auto reg = ctx->csys.reg;
|
||||
uint32_t *ent = h->ent;
|
||||
view_pos_t *len = h->components[view_len];
|
||||
viewcont_t *cont = h->components[view_control];
|
||||
for (uint32_t i = h->num_objects; i-- > 0; ) {
|
||||
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);
|
||||
auto href = View_GetRef (sub_view);
|
||||
calc_downwards_dependent (ctx, href->hierarchy);
|
||||
len[i] = View_GetLen (sub_view);
|
||||
}
|
||||
view_pos_t clen = len[i];
|
||||
if (cont[i].semantic_x == imui_size_fitchildren
|
||||
|| cont[i].semantic_x == imui_size_expand) {
|
||||
|
@ -566,7 +617,6 @@ static void
|
|||
calc_expansions (imui_ctx_t *ctx, hierarchy_t *h)
|
||||
{
|
||||
auto reg = ctx->csys.reg;
|
||||
|
||||
uint32_t *ent = h->ent;
|
||||
view_pos_t *len = h->components[view_len];
|
||||
viewcont_t *cont = h->components[view_control];
|
||||
|
@ -644,30 +694,48 @@ calc_expansions (imui_ctx_t *ctx, hierarchy_t *h)
|
|||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
auto href = View_GetRef (sub_view);
|
||||
View_SetLen (sub_view, len[i].x, len[i].y);
|
||||
calc_expansions (ctx, href->hierarchy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME currently works properly only for grav_northwest
|
||||
static uint32_t __attribute__((pure))
|
||||
count_views (imui_ctx_t *ctx, hierarchy_t *h)
|
||||
{
|
||||
uint32_t count = h->num_objects;
|
||||
viewcont_t *cont = h->components[view_control];
|
||||
uint32_t *ent = h->ent;
|
||||
auto reg = h->reg;
|
||||
|
||||
// the root object is never a link (if it has a reference component, it's
|
||||
// to the pseudo-parent of the hierarchy)
|
||||
for (uint32_t i = 1; 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);
|
||||
auto href = View_GetRef (sub_view);
|
||||
count += count_views (ctx, href->hierarchy);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
layout_objects (imui_ctx_t *ctx, view_t root_view)
|
||||
position_views (imui_ctx_t *ctx, view_t root_view)
|
||||
{
|
||||
auto ref = View_GetRef (root_view);
|
||||
auto h = ref->hierarchy;
|
||||
|
||||
uint32_t *ent = h->ent;
|
||||
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 *parent = h->parentIndex;
|
||||
boolpair_t down_depend[h->num_objects];
|
||||
|
||||
// the root view size is always explicit
|
||||
down_depend[0] = (boolpair_t) { false, false };
|
||||
calc_upwards_dependent (ctx, h, down_depend);
|
||||
calc_downwards_dependent (h);
|
||||
calc_expansions (ctx, h);
|
||||
//dump_tree (h, 0, 0, ctx);
|
||||
// resolve conflicts
|
||||
//fflush (stdout);
|
||||
|
||||
if (Ent_HasComponent (root_view.id, c_reference, ctx->vsys.reg)) {
|
||||
auto ent = root_view.id;
|
||||
|
@ -698,6 +766,35 @@ layout_objects (imui_ctx_t *ctx, view_t root_view)
|
|||
}
|
||||
|
||||
View_UpdateHierarchy (root_view);
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
if (cont[i].is_link) {
|
||||
auto reg = ctx->vsys.reg;
|
||||
imui_reference_t *sub = Ent_GetComponent (ent[i], c_reference, reg);
|
||||
auto sub_view = View_FromEntity (ctx->vsys, sub->ref_id);
|
||||
position_views (ctx, sub_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME currently works properly only for grav_northwest
|
||||
static void
|
||||
layout_objects (imui_ctx_t *ctx, view_t root_view)
|
||||
{
|
||||
auto ref = View_GetRef (root_view);
|
||||
auto h = ref->hierarchy;
|
||||
|
||||
downdep_t down_depend[count_views (ctx, h)];
|
||||
|
||||
// the root view size is always explicit
|
||||
down_depend[0] = (downdep_t) { };
|
||||
calc_upwards_dependent (ctx, h, down_depend);
|
||||
calc_downwards_dependent (ctx, h);
|
||||
calc_expansions (ctx, h);
|
||||
//dump_tree (h, 0, 0, ctx);
|
||||
// resolve conflicts
|
||||
//fflush (stdout);
|
||||
|
||||
position_views (ctx, root_view);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -732,6 +829,25 @@ 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)
|
||||
{
|
||||
|
@ -740,7 +856,7 @@ 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);
|
||||
*Canvas_DrawOrder (ctx->csys, window->entity) = window->draw_order;
|
||||
set_draw_order (ctx, window->entity, window->draw_order);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -752,11 +868,11 @@ IMUI_Draw (imui_ctx_t *ctx)
|
|||
ctx->mouse_released = 0;
|
||||
sort_windows (ctx);
|
||||
auto ref = View_GetRef (ctx->root_view);
|
||||
Hierarchy_SetTreeMode (ref->hierarchy, false);
|
||||
set_hierarchy_tree_mode (ctx, ref->hierarchy, false);
|
||||
for (uint32_t i = 0; i < ctx->windows.size; i++) {
|
||||
auto window = View_FromEntity (ctx->vsys, ctx->windows.a[i]->entity);
|
||||
auto ref = View_GetRef (window);
|
||||
Hierarchy_SetTreeMode (ref->hierarchy, false);
|
||||
set_hierarchy_tree_mode (ctx, ref->hierarchy, false);
|
||||
}
|
||||
Canvas_DrawSort (ctx->csys);
|
||||
|
||||
|
@ -1517,3 +1633,59 @@ IMUI_EndWindow (imui_ctx_t *ctx)
|
|||
{
|
||||
IMUI_PopLayout (ctx);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
auto panel = ctx->windows.a[ctx->windows.size - 1];
|
||||
|
||||
auto canvas = Canvas_New (ctx->csys);
|
||||
*Canvas_DrawGroup (ctx->csys, canvas) = panel->draw_group;
|
||||
auto scroll_box = Canvas_GetRootView (ctx->csys, canvas);
|
||||
|
||||
auto state = imui_get_state (ctx, name, scroll_box.id);
|
||||
update_hot_active (ctx, state);
|
||||
|
||||
DARRAY_APPEND (&ctx->parent_stack, ctx->current_parent);
|
||||
|
||||
auto ref = View_GetRef (scroll_box);
|
||||
Hierarchy_SetTreeMode (ref->hierarchy, true);
|
||||
|
||||
View_Control (anchor_view)->is_link = 1;
|
||||
imui_reference_t link = {
|
||||
.ref_id = scroll_box.id,
|
||||
.ctx = ctx,
|
||||
};
|
||||
Ent_SetComponent (anchor_view.id, c_reference, anchor_view.reg, &link);
|
||||
imui_reference_t anchor = {
|
||||
.ref_id = anchor_view.id,
|
||||
};
|
||||
Ent_SetComponent (scroll_box.id, c_reference, scroll_box.reg, &anchor);
|
||||
|
||||
if (!state->draw_order) {
|
||||
state->draw_order = ++ctx->draw_order;
|
||||
}
|
||||
|
||||
ctx->current_parent = scroll_box;
|
||||
*View_Control (scroll_box) = (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,
|
||||
};
|
||||
state->content = scroll_box.id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
IMUI_EndScrollBox (imui_ctx_t *ctx)
|
||||
{
|
||||
IMUI_PopLayout (ctx);
|
||||
}
|
||||
|
|
|
@ -81,6 +81,10 @@ int IMUI_MenuItem (imui_ctx_t ctx, string label, int collapse);
|
|||
int IMUI_StartWindow (imui_ctx_t ctx, imui_window_t *window);
|
||||
void IMUI_EndWindow (imui_ctx_t ctx);
|
||||
|
||||
int IMUI_StartScrollBox (imui_ctx_t ctx, string name);
|
||||
void IMUI_EndScrollBox (imui_ctx_t ctx);
|
||||
|
||||
|
||||
#define IMUI_DeferLoop(begin, end) \
|
||||
for (int _i_ = (begin); !_i_; _i_++, (end))
|
||||
|
||||
|
@ -134,6 +138,10 @@ void IMUI_EndWindow (imui_ctx_t ctx);
|
|||
IMUI_DeferLoop (IMUI_StartWindow (IMUI_context, window), \
|
||||
IMUI_EndWindow (IMUI_context))
|
||||
|
||||
#define UI_ScrollBox(name) \
|
||||
IMUI_DeferLoop (IMUI_StartScrollBox (IMUI_context, name), \
|
||||
IMUI_EndScrollBox (IMUI_context))
|
||||
|
||||
#define UI_Style(style) \
|
||||
IMUI_DeferLoop (IMUI_PushStyle (IMUI_context, style), \
|
||||
IMUI_PopStyle (IMUI_context ))
|
||||
|
|
|
@ -46,3 +46,6 @@ int IMUI_MenuItem (imui_ctx_t ctx, string label, int collapse) = #0;
|
|||
|
||||
int IMUI_StartWindow (imui_ctx_t ctx, imui_window_t *window) = #0;
|
||||
void IMUI_EndWindow (imui_ctx_t ctx) = #0;
|
||||
|
||||
int IMUI_StartScrollBox (imui_ctx_t ctx, string name) = #0;
|
||||
void IMUI_EndScrollBox (imui_ctx_t ctx) = #0;
|
||||
|
|
Loading…
Reference in a new issue