more layouting

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

227
ugui.c

@ -150,6 +150,10 @@ struct _UgCtx {
int width, height; int width, height;
} size; } size;
struct {
UgPoint margin;
} style;
// input structure, it describes the events received between frames // input structure, it describes the events received between frames
struct { struct {
uint32_t flags; uint32_t flags;
@ -159,21 +163,22 @@ struct _UgCtx {
}; };
// layouting // layouting
int ug_layout_row(void); int ug_layout_set_row(UgCtx *ctx);
int ug_layout_column(void); int ug_layout_set_column(UgCtx *ctx);
int ug_layout_floating(void); int ug_layout_set_floating(UgCtx *ctx);
int ug_layout_next_row(void); // these reset the offsets introduced by the previous elements
int ug_layout_next_column(void); 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_begin(UgCtx *ctx, const char *label, UgRect div);
int ug_div_end(UgCtx *ctx); int ug_div_end(UgCtx *ctx);
int ug_input_window_size(UgCtx *ctx, int width, int height); int ug_input_window_size(UgCtx *ctx, int width, int height);
UgId djb2(const char *str); static UgId djb2(const char *str);
UgId FNV_1a(const char *str); static UgId FNV_1a(const char *str);
int ug_button(UgCtx *ctx, const char *label, UgRect size); 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) int main(void)
{ {
@ -201,21 +206,16 @@ int main(void)
// main div, fill the whole window // main div, fill the whole window
ug_div_begin(&ctx, "main", DIV_FILL); ug_div_begin(&ctx, "main", DIV_FILL);
{ {
ug_layout_set_column(&ctx);
ug_button( ug_button(
&ctx, &ctx,
"batt342353453452wrwea", "button0",
(UgRect) {.y = 100, .x = 130, .w = 100, .h = 16} (UgRect) {.y = 100, .x = 100, .w = 30, .h = 30}
);
ug_button(
&ctx,
"arieasd3ree2234tast",
(UgRect) {.x = 10, .w = 30, .h = 30}
);
ug_button(
&ctx,
"bughsdfsfdstton2",
(UgRect) {.x = 10, .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); 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 // 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 // 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; int is_new = 0;
uint32_t cache_idx; uint32_t cache_idx;
@ -287,6 +287,21 @@ int search_or_insert(UgCtx *ctx, UgElem **elem, UgId id)
return is_new; 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) int ug_init(UgCtx *ctx)
{ {
if (ctx == NULL) { if (ctx == NULL) {
@ -300,6 +315,9 @@ int ug_init(UgCtx *ctx)
ctx->layout = row; ctx->layout = row;
ctx->div_using = 0; ctx->div_using = 0;
// TODO: add style config
ctx->style.margin = (UgPoint) {2, 2};
return 0; return 0;
} }
@ -316,7 +334,7 @@ int ug_destroy(UgCtx *ctx)
return 0; return 0;
} }
void print_tree(UgCtx *ctx) static void print_tree(UgCtx *ctx)
{ {
printf("ctx->tree: ["); printf("ctx->tree: [");
for (int c = -1, x; (x = ug_tree_level_order_it(&ctx->tree, 0, &c)) != -1;) { 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; 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_off = 0xcbf29ce484222325;
const uint64_t fnv_prime = 0x100000001b3; const uint64_t fnv_prime = 0x100000001b3;
@ -437,7 +455,7 @@ UgId FNV_1a(const char *str)
return hash; return hash;
} }
UgId djb2(const char *str) static UgId djb2(const char *str)
{ {
uint64_t hash = 5381; uint64_t hash = 5381;
uint32_t c; uint32_t c;
@ -468,13 +486,8 @@ int ug_div_begin(UgCtx *ctx, const char *label, UgRect div)
printf("Error adding to tree\n"); printf("Error adding to tree\n");
} }
// take a reference to the parent UgElem *parent;
// FIXME: if the tree held pointers to the elements then no more if (get_parent(ctx, &parent)) {
// 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()?
return -1; 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 // do layout and update flags only if the element was updated
if (is_new || FTEST(parent, ELEM_UPDATED)) { if (is_new || FTEST(parent, ELEM_UPDATED)) {
// 2. layout the element // 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 // 3. Mark the element as updated
c_elem->flags |= ELEM_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 // 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}; UgRect elem_rect = {0};
UgPoint origin = {0}; UgPoint origin = {0};
@ -571,6 +584,18 @@ UgRect position_element(UgCtx *ctx, UgElem *parent, UgRect rect)
.y = elem_rect.y + elem_rect.h, .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( printf(
"positioning rect: %lx {%d %d %d %d}(%d %d %d %d) -> {%d %d %d "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); ug_tree_add(&ctx->tree, id, ctx->div_using);
print_tree(ctx); print_tree(ctx);
// take a reference to the parent UgElem *parent;
// FIXME: if the tree held pointers to the elements then no more if (get_parent(ctx, &parent)) {
// 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()?
return -1; 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 the element is new or the parent was updated then redo layout
if (is_new || parent->flags & ELEM_UPDATED) { if (is_new || parent->flags & ELEM_UPDATED) {
// 2. Layout // 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 // 3. TODO: Fill the button specific fields
} else { } else {
@ -641,3 +661,128 @@ int ug_button(UgCtx *ctx, const char *label, UgRect size)
return 0; 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