more layouting

rewrite2
Alessandro Mauri 11 months ago
parent d6358944ac
commit 305df93182
  1. 235
      ugui.c

235
ugui.c

@ -150,6 +150,10 @@ struct _UgCtx {
int width, height;
} size;
struct {
UgPoint margin;
} style;
// input structure, it describes the events received between frames
struct {
uint32_t flags;
@ -159,21 +163,22 @@ struct _UgCtx {
};
// layouting
int ug_layout_row(void);
int ug_layout_column(void);
int ug_layout_floating(void);
int ug_layout_next_row(void);
int ug_layout_next_column(void);
int ug_div_begin(UgCtx *ctx, const char *label, UgRect div);
int ug_div_end(UgCtx *ctx);
int ug_input_window_size(UgCtx *ctx, int width, int height);
UgId djb2(const char *str);
UgId FNV_1a(const char *str);
int ug_layout_set_row(UgCtx *ctx);
int ug_layout_set_column(UgCtx *ctx);
int ug_layout_set_floating(UgCtx *ctx);
// these reset the offsets introduced by the previous elements
int ug_layout_next_row(UgCtx *ctx);
int ug_layout_next_column(UgCtx *ctx);
int ug_div_begin(UgCtx *ctx, const char *label, UgRect div);
int ug_div_end(UgCtx *ctx);
int ug_input_window_size(UgCtx *ctx, int width, int height);
static UgId djb2(const char *str);
static UgId FNV_1a(const char *str);
int ug_button(UgCtx *ctx, const char *label, UgRect size);
UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect);
UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect, int style);
int main(void)
{
@ -201,21 +206,16 @@ int main(void)
// main div, fill the whole window
ug_div_begin(&ctx, "main", DIV_FILL);
{
ug_layout_set_column(&ctx);
ug_button(
&ctx,
"batt342353453452wrwea",
(UgRect) {.y = 100, .x = 130, .w = 100, .h = 16}
);
ug_button(
&ctx,
"arieasd3ree2234tast",
(UgRect) {.x = 10, .w = 30, .h = 30}
);
ug_button(
&ctx,
"bughsdfsfdstton2",
(UgRect) {.x = 10, .w = 30, .h = 30}
"button0",
(UgRect) {.y = 100, .x = 100, .w = 30, .h = 30}
);
ug_layout_next_column(&ctx);
ug_button(&ctx, "button1", (UgRect) {.w = 30, .h = 30});
ug_layout_next_column(&ctx);
ug_button(&ctx, "button2", (UgRect) {.w = 30, .h = 30});
}
ug_div_end(&ctx);
@ -271,7 +271,7 @@ int main(void)
// search the element of the corresponding id in the cache, if no element is found
// insert a new one of that id. Return the pointer to the element
int search_or_insert(UgCtx *ctx, UgElem **elem, UgId id)
static int search_or_insert(UgCtx *ctx, UgElem **elem, UgId id)
{
int is_new = 0;
uint32_t cache_idx;
@ -287,6 +287,21 @@ int search_or_insert(UgCtx *ctx, UgElem **elem, UgId id)
return is_new;
}
static int get_parent(UgCtx *ctx, UgElem **parent)
{
// take a reference to the parent
// FIXME: if the tree held pointers to the elements then no more
// redundant cache search
UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using);
*parent = ug_cache_search(&ctx->cache, parent_id);
if (parent == NULL) {
// Error, did you forget to do frame_begin()?
return -1;
}
return 0;
}
int ug_init(UgCtx *ctx)
{
if (ctx == NULL) {
@ -300,6 +315,9 @@ int ug_init(UgCtx *ctx)
ctx->layout = row;
ctx->div_using = 0;
// TODO: add style config
ctx->style.margin = (UgPoint) {2, 2};
return 0;
}
@ -316,7 +334,7 @@ int ug_destroy(UgCtx *ctx)
return 0;
}
void print_tree(UgCtx *ctx)
static void print_tree(UgCtx *ctx)
{
printf("ctx->tree: [");
for (int c = -1, x; (x = ug_tree_level_order_it(&ctx->tree, 0, &c)) != -1;) {
@ -423,7 +441,7 @@ int ug_input_window_size(UgCtx *ctx, int width, int height)
return 0;
}
UgId FNV_1a(const char *str)
static UgId FNV_1a(const char *str)
{
const uint64_t fnv_off = 0xcbf29ce484222325;
const uint64_t fnv_prime = 0x100000001b3;
@ -437,7 +455,7 @@ UgId FNV_1a(const char *str)
return hash;
}
UgId djb2(const char *str)
static UgId djb2(const char *str)
{
uint64_t hash = 5381;
uint32_t c;
@ -468,13 +486,8 @@ int ug_div_begin(UgCtx *ctx, const char *label, UgRect div)
printf("Error adding to tree\n");
}
// take a reference to the parent
// FIXME: if the tree held pointers to the elements then no more
// redundant cache search
UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using);
UgElem *parent = ug_cache_search(&ctx->cache, parent_id);
if (parent == NULL) {
// Error, did you forget to do frame_begin()?
UgElem *parent;
if (get_parent(ctx, &parent)) {
return -1;
}
@ -491,7 +504,7 @@ int ug_div_begin(UgCtx *ctx, const char *label, UgRect div)
// do layout and update flags only if the element was updated
if (is_new || FTEST(parent, ELEM_UPDATED)) {
// 2. layout the element
c_elem->rect = position_element(ctx, parent, div);
c_elem->rect = position_element(ctx, parent, div, 0);
// 3. Mark the element as updated
c_elem->flags |= ELEM_UPDATED;
@ -532,7 +545,7 @@ int ug_div_end(UgCtx *ctx)
}
// position the rectangle inside the parent according to the layout
UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect)
UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect, int style)
{
UgRect elem_rect = {0};
UgPoint origin = {0};
@ -571,6 +584,18 @@ UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect)
.y = elem_rect.y + elem_rect.h,
};
// if using the style then apply margins
if (style && parent->div.layout != DIV_LAYOUT_FLOATING) {
elem_rect.x += ctx->style.margin.x;
elem_rect.y += ctx->style.margin.y;
parent->div.origin_r.x += ctx->style.margin.x;
// parent->div.origin_r.y += ctx->style.margin.y;
// parent->div.origin_c.x += ctx->style.margin.x;
parent->div.origin_c.y += ctx->style.margin.y;
}
/*
printf(
"positioning rect: %lx {%d %d %d %d}(%d %d %d %d) -> {%d %d %d
@ -603,13 +628,8 @@ int ug_button(UgCtx *ctx, const char *label, UgRect size)
ug_tree_add(&ctx->tree, id, ctx->div_using);
print_tree(ctx);
// take a reference to the parent
// FIXME: if the tree held pointers to the elements then no more
// redundant cache search
UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using);
UgElem *parent = ug_cache_search(&ctx->cache, parent_id);
if (parent == NULL) {
// Error, did you forget to do frame_begin()?
UgElem *parent;
if (get_parent(ctx, &parent)) {
return -1;
}
@ -621,7 +641,7 @@ int ug_button(UgCtx *ctx, const char *label, UgRect size)
// if the element is new or the parent was updated then redo layout
if (is_new || parent->flags & ELEM_UPDATED) {
// 2. Layout
c_elem->rect = position_element(ctx, parent, size);
c_elem->rect = position_element(ctx, parent, size, 1);
// 3. TODO: Fill the button specific fields
} else {
@ -641,3 +661,128 @@ int ug_button(UgCtx *ctx, const char *label, UgRect size)
return 0;
}
int ug_layout_set_row(UgCtx *ctx)
{
if (ctx == NULL) {
return -1;
}
UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using);
UgElem *parent = ug_cache_search(&ctx->cache, parent_id);
if (parent == NULL) {
// Error, did you forget to do frame_begin()?
return -1;
}
if (parent->type != ETYPE_DIV) {
// what?
return -1;
}
parent->div.layout = DIV_LAYOUT_ROW;
return 0;
}
int ug_layout_set_column(UgCtx *ctx)
{
if (ctx == NULL) {
return -1;
}
UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using);
UgElem *parent = ug_cache_search(&ctx->cache, parent_id);
if (parent == NULL) {
// Error, did you forget to do frame_begin()?
return -1;
}
if (parent->type != ETYPE_DIV) {
// what?
return -1;
}
parent->div.layout = DIV_LAYOUT_COLUMN;
return 0;
}
int ug_layout_set_floating(UgCtx *ctx)
{
if (ctx == NULL) {
return -1;
}
UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using);
UgElem *parent = ug_cache_search(&ctx->cache, parent_id);
if (parent == NULL) {
// Error, did you forget to do frame_begin()?
return -1;
}
if (parent->type != ETYPE_DIV) {
// what?
return -1;
}
parent->div.layout = DIV_LAYOUT_FLOATING;
return 0;
}
int ug_layout_next_row(UgCtx *ctx)
{
if (ctx == NULL) {
return -1;
}
UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using);
UgElem *parent = ug_cache_search(&ctx->cache, parent_id);
if (parent == NULL) {
// Error, did you forget to do frame_begin()?
return -1;
}
if (parent->type != ETYPE_DIV) {
// what?
return -1;
}
parent->div.origin_r = (UgPoint) {
.x = parent->rect.x,
.y = parent->div.origin_c.y,
};
parent->div.origin_c = parent->div.origin_r;
return 0;
}
int ug_layout_next_column(UgCtx *ctx)
{
if (ctx == NULL) {
return -1;
}
UgId parent_id = ug_tree_get(&ctx->tree, ctx->div_using);
UgElem *parent = ug_cache_search(&ctx->cache, parent_id);
if (parent == NULL) {
// Error, did you forget to do frame_begin()?
return -1;
}
if (parent->type != ETYPE_DIV) {
// what?
return -1;
}
parent->div.origin_c = (UgPoint) {
.x = parent->div.origin_r.x,
.y = parent->rect.y,
};
parent->div.origin_r = parent->div.origin_c;
return 0;
}

Loading…
Cancel
Save