more layouting
This commit is contained in:
parent
d6358944ac
commit
305df93182
233
ugui.c
233
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…
Reference in New Issue
Block a user