commit 8964e49031e0a23aaa0d9d2155a62bba92b5d587 from: Onana Onana Xavier Manuel date: Sun Jul 12 00:45:22 2026 UTC Organization change to layout.c * Separate pack, grid and place in 3 functions * Updated some configurations * Updated man page commit - 98d0e23f0c6d7384bfd5f4cfe5ac016c019f71e3 commit + 8964e49031e0a23aaa0d9d2155a62bba92b5d587 blob - 02ef472c17c38b13da36ebae7a87f31f33977bfc blob + 526401143b87409307e1d991f80cabac3e6b3de6 --- Makefile +++ Makefile @@ -33,3 +33,6 @@ ${LIB}: ${OBJS} clean: rm -rf ${PREFIX}/lib/${LIB}.so ${PREFIX}/include/${HDR} ${PREFIX}/lib/${LIB}.a ${OBJS} + make -C examples clean + +.PHONY: examples blob - f38629d25d4e1a4e1308def65684adf2c6022363 blob + ccd50669b42d5dede1f47fd5c71ba7d1e2d0841c --- aui.h +++ aui.h @@ -48,6 +48,8 @@ struct aui_packpar { struct aui_gridpar { unsigned int column; unsigned int row; + unsigned int columnspan; + unsigned int rowspan; }; struct aui_widget; @@ -79,7 +81,7 @@ struct aui_canvas_config { }; struct aui_label_config { - const char *text; + char *text; struct aui_color foreground; struct aui_color bg; }; blob - 4c55709846422afb7b0a278df81d9c3cae5d277f blob + 1b3320cb09ed30ffbbde8bfc71b9fe9ba82c5989 --- aui_run.3 +++ aui_run.3 @@ -1,4 +1,4 @@ -.Dd $Mdocdate: July 07 2026$ +.Dd $Mdocdate: July 08 2026$ .Dt AUI_RUN 3 .Os .Sh NAME @@ -6,6 +6,13 @@ .Nm aui_destroy , .Nm aui_window_new , .Nm aui_button_new , +.Nm aui_button_config , +.Nm aui_frame_new , +.Nm aui_frame_config , +.Nm aui_label_new , +.Nm aui_label_config , +.Nm aui_canvas_new , +.Nm aui_canvas_config , .Nm aui_place , .Nm aui_pack , .Nm aui_grid , @@ -22,6 +29,8 @@ .Fn aui_window_new "struct aui_window_config * config" .Ft struct aui_button* .Fn aui_button_new "struct aui_widget * parent" "struct aui_button_config * config" +.Ft int +.Fn aui_button_config "struct aui_widget * widget" "struct aui_button_config * config" .Ft struct aui_label* .Fn aui_label_new "struct aui_widget * parent" "struct aui_label_config * config" .Ft int @@ -31,8 +40,10 @@ .Ft int .Fn aui_frame_config "struct aui_widget * widget" "struct aui_frame_config * config" .Ft struct aui_canvas* -.Fn aui_canvas_new "struct aui_widget * parent" +.Fn aui_canvas_new "struct aui_widget * widget" "struct aui_canvas_config * config" .Ft int +.Fn aui_canvas_config "struct aui_widget * parent" "struct aui_canvas_config * config" +.Ft int .Fn aui_place "struct aui_widget * widget" "struct aui_placepar * par" .Ft int .Fn aui_grid "struct aui_widget * widget" "struct aui_gridpar * par" blob - 8992755a9f908bfc20928dd3142f9154d9990df6 blob + 36661b64d6d1cac811398d1ce8ebc2207b00cdc3 --- button.c +++ button.c @@ -54,7 +54,8 @@ aui_button_new(struct aui_widget *parent, struct aui_b widget->primitives.list[1] = driver->ops->create_rectangle(); widget->primitives.list[2] = driver->ops->create_text(); - driver->ops->set_rectangle_color(widget->window, widget->primitives.list[0], &color[0]); + driver->ops->set_rectangle_color(widget->window, widget->primitives.list[0], + &button->config.foreground); driver->ops->set_rectangle_color(widget->window, widget->primitives.list[1], &color[1]); driver->ops->set_text(widget->primitives.list[2], button->config.text, 0, 0); driver->ops->set_text_color(widget->primitives.list[2], &button->config.foreground); blob - 67e29c8288c0653462bfe0dd6cc2f9ecfd0659b0 blob + ebeb86585fd96a64565a5fc6881784a9a9726eb3 --- label.c +++ label.c @@ -52,11 +52,22 @@ aui_label_config(struct aui_widget *widget, struct aui struct aui_label *label = (struct aui_label *)widget; struct aui_geometry geom = widget->geom; - label->config = (config == NULL) ? default_config : *config; + if (label->config.text) { + free(label->config.text); + label->config.text = NULL; + } + config = (config == NULL) ? &default_config : config; + label->config = *config; + + if (config->text) + label->config.text = strdup(config->text); + driver->ops->set_text(widget->primitives.list[0], label->config.text, 0, 0); driver->ops->set_text_color(widget->primitives.list[0], &label->config.foreground); label_set_geometry(widget, &geom); + + layout_organize(widget->parent); return 0; } blob - 73c2d50a0fe25487b2958c430bffdc2ff79a9416 blob + 3dffb8bcb5cb44e27c408169d974618992e39e19 --- layout.c +++ layout.c @@ -51,6 +51,461 @@ can_add(struct aui_widget *widget, enum aui_layout_typ } void +place(struct aui_widget *widget) +{ + struct aui_widget *child; + + TAILQ_FOREACH(child, &widget->queue, entries) { + if (child->mapped == 0) + continue; + + struct aui_placepar *par = &child->placepar; + int dx = 0, dy = 0; + + struct aui_geometry geom = { + .x = widget->geom.x + child->placepar.x + widget->geom.width * child->placepar.relx, + .y = widget->geom.y + child->placepar.y + widget->geom.height * child->placepar.rely, + .width = child->placepar.width + child->placepar.relwidth * widget->geom.width, + .height = child->placepar.height + child->placepar.relheight * widget->geom.height }; + + switch (par->anchor) { + case AUI_ANCHOR_NW: + dx = 0; + dy = 0; + break; + case AUI_ANCHOR_NE: + dx = -geom.width; + dy = 0; + break; + case AUI_ANCHOR_N: + dx = -geom.width / 2; + dy = 0; + break; + case AUI_ANCHOR_W: + dx = 0; + dy = -geom.height / 2; + break; + case AUI_ANCHOR_E: + dx = -geom.width; + dy = -geom.height /2; + break; + case AUI_ANCHOR_SE: + dx = -geom.width; + dy = -geom.height; + break; + case AUI_ANCHOR_SW: + dx = 0; + dy = -geom.height; + break; + case AUI_ANCHOR_S: + dx = -geom.width / 2; + dy = -geom.height; + break; + case AUI_ANCHOR_CENTER: + dx = -geom.width / 2; + dy = -geom.height / 2; + break; + default: + break; + } + + geom.x += dx; + geom.y += dy; + child->ops->set_geometry(child, &geom); + + switch (child->type) { + case WIDGET_TYPE_FRAME: + layout_organize(child); + break; + default: + break; + } + } +} + +void +grid(struct aui_widget *widget) +{ + struct aui_container *con = (struct aui_container *)widget; + uint8_t *rmap = con->row_maps; + uint8_t *cmap = con->col_maps; + struct aui_widget *child; + + unsigned int *rsize = con->row_sizes; + unsigned int *csize = con->col_sizes; + + memset(con->row_sizes, 0, sizeof(*con->row_sizes) * con->grid_size[1]); + memset(con->col_sizes, 0, sizeof(*con->col_sizes) * con->grid_size[0]); + + TAILQ_FOREACH(child, &widget->queue, entries) { + if (child->mapped == 0) + continue; + + struct aui_geometry min = child->ops->get_min_size(child); + + rmap[child->gridpar.row] = 1; + cmap[child->gridpar.column] = 1; + + rsize[child->gridpar.row] = (rsize[child->gridpar.row] < min.height) ? + min.height : rsize[child->gridpar.row]; + + csize[child->gridpar.column] = (csize[child->gridpar.column] < min.width) ? + min.width : csize[child->gridpar.column]; + } + + unsigned int *rpos = con->row_pos; + unsigned int *cpos = con->col_pos; + + unsigned int rowdt = 0; + unsigned int coldt = 0; + + for (int r = 0; r < con->grid_size[1]; r++) { + rpos[r] = rowdt; + rowdt = (rmap[r] == 1) ? rowdt + rsize[r] : rowdt; + } + + for (int c = 0; c < con->grid_size[0]; c++) { + cpos[c] = coldt; + coldt = (cmap[c] == 1) ? coldt + csize[c] : coldt; + } + + TAILQ_FOREACH(child, &widget->queue, entries) { + if (child->mapped == 0) + continue; + + struct aui_geometry min = child->ops->get_min_size(child); + struct aui_geometry geom = { 0 }; + + int dx = (csize[child->gridpar.column] - min.width); + int dy = (rsize[child->gridpar.row] - min.height); + + geom.x = widget->geom.x + cpos[child->gridpar.column] + dx / 2; + geom.y = widget->geom.y + rpos[child->gridpar.row] + dy / 2; + geom.width = min.width; + geom.height = min.height; + + child->ops->set_geometry(child, &geom); + } + + TAILQ_FOREACH(child, &widget->queue, entries) { + switch (child->type) { + case WIDGET_TYPE_FRAME: + layout_organize(child); + break; + default: + break; + } + } +} + +void +pack(struct aui_widget *widget) +{ + struct aui_container *con = (struct aui_container *)widget; + struct aui_widget *child; + struct aui_geometry space = widget->geom; + unsigned int hexpand = 0; + unsigned int vexpand = 0; + unsigned int req_w = 0; + unsigned int req_h = 0; + int extra_w = 0; + int extra_h = 0; + int hextra = 0; + int vextra = 0; + + /* + * Compute requested and extra space. hextra and vextra are only set + * if there is no top/bottom widgets succeeding it. This guarantees + * a proper request size. + */ + TAILQ_FOREACH(child, &widget->queue, entries) { + if (child->mapped == 0) + continue; + + struct aui_geometry cgeom = child->ops->get_min_size(child); + switch (child->packpar.side) { + case AUI_SIDE_TOP: + case AUI_SIDE_BOTTOM: + vexpand = (child->packpar.expand) ? vexpand + 1 : vexpand; + if (vextra) vextra = 0; + req_h += cgeom.height; + hextra = (cgeom.width > hextra) ? cgeom.width : hextra; + break; + case AUI_SIDE_LEFT: + case AUI_SIDE_RIGHT: + hexpand = (child->packpar.expand) ? hexpand + 1 : hexpand; + if (hextra) hextra = 0; + vextra = (cgeom.height > vextra) ? cgeom.height : vextra; + req_w += cgeom.width; + break; + default: + break; + } + } + + req_w += hextra; + req_h += vextra; + + if (req_w > space.width) + req_w = space.width; + + if (req_h > space.height) + req_h = space.height; + + extra_w = space.width - req_w; + extra_h = space.height - req_h; + + /* + * Making sure each widget consume space before expension + * for their area. + */ + TAILQ_FOREACH(child, &widget->queue, entries) { + if (child->mapped == 0) + continue; + + struct aui_geometry min = child->ops->get_min_size(child); + + switch (child->packpar.side) { + case AUI_SIDE_TOP: + child->packarea = (struct aui_geometry) { + .x = space.x, + .y = space.y, + .width = space.width, + .height = min.height, + }; + + if (child->packarea.height > space.height) { + child->packarea.height = space.height; + } + + space.y += child->packarea.height; + space.height -= child->packarea.height; + break; + case AUI_SIDE_BOTTOM: + child->packarea = (struct aui_geometry) { + .x = space.x, + .y = space.y, + .width = space.width, + .height = min.height + }; + + if (child->packarea.height > space.height) { + child->packarea.height = space.height; + } + + child->packarea.y = space.y + space.height - child->packarea.height; + + space.height -= child->packarea.height; + break; + case AUI_SIDE_LEFT: + child->packarea = (struct aui_geometry) { + .x = space.x, + .y = space.y, + .width = min.width, + .height = space.height + }; + + if (child->packarea.width > space.width) { + child->packarea.width = space.width; + } + + space.x += child->packarea.width; + space.width -= child->packarea.width; + break; + case AUI_SIDE_RIGHT: + child->packarea = (struct aui_geometry) { + .x = space.x, + .y = space.y, + .width = min.width, + .height = space.height + }; + + if (child->packarea.width > space.width) { + child->packarea.width = space.width; + } + + child->packarea.x = space.x + space.width - child->packarea.width; + + space.width -= child->packarea.width; + break; + default: + break; + } + } + + int top = 0; + int bottom = 0; + int right = 0; + int left = 0; + + /* + * Consuming the remaining space if expanded + */ + TAILQ_FOREACH(child, &widget->queue, entries) { + if (child->mapped == 0) + continue; + + if (space.width == 0 && space.height == 0) + break; + + struct aui_geometry *area = &child->packarea; + + switch (child->packpar.side) { + case AUI_SIDE_TOP: + area->x += left; + area->y += top; + area->width -= left; + + area->width -= right; + + if (child->packpar.expand == 1) { + if (vexpand) { + top += extra_h / vexpand; + area->height += extra_h / vexpand; + extra_h -= extra_h / vexpand; + vexpand--; + } + } + break; + + case AUI_SIDE_BOTTOM: + area->x += left; + area->width -= left; + + area->width -= right; + if (child->packpar.expand == 1) { + if (vexpand) { + bottom += extra_h / vexpand; + area->height += extra_h / vexpand; + area->y -= extra_h / vexpand; + extra_h -= extra_h / vexpand; + vexpand--; + } + } + break; + case AUI_SIDE_LEFT: + area->y += top; + area->x += left; + area->height -= top; + area->height -= bottom; + + if (child->packpar.expand == 1) { + if (hexpand) { + left += extra_w / hexpand; + area->width += extra_w / hexpand; + extra_w -= extra_w / hexpand; + hexpand--; + } + } + break; + case AUI_SIDE_RIGHT: + area->y += top; + area->height -= top; + area->height -= bottom; + + if (child->packpar.expand == 1) { + if (hexpand) { + right += extra_w / hexpand; + area->x -= extra_w / hexpand; + area->width += extra_w / hexpand; + extra_w -= extra_w / hexpand; + hexpand--; + } + } + break; + default: + break; + } + } + + /* + * Setting geometry + */ + TAILQ_FOREACH(child, &widget->queue, entries) { + if (child->mapped == 0) + continue; + + struct aui_geometry min = child->ops->get_min_size(child); + struct aui_geometry *area = &child->packarea; + + switch (child->packpar.fill) { + case AUI_FILL_NONE: + child->geom.width = (min.width > area->width) ? area->width : min.width; + child->geom.height = (min.height > area->height) ? area->height : min.height; + break; + case AUI_FILL_X: + child->geom.width = area->width; + child->geom.height = (min.height > area->height) ? area->height : min.height; + break; + case AUI_FILL_Y: + child->geom.width = (min.width > area->width) ? area->width : min.width; + child->geom.height = area->height; + break; + case AUI_FILL_BOTH: + child->geom.width = area->width; + child->geom.height = area->height; + break; + default: + break; + } + + switch (child->packpar.anchor) { + case AUI_ANCHOR_NW: + child->geom.x = area->x; + child->geom.y = area->y; + break; + case AUI_ANCHOR_N: + child->geom.x = area->x + area->width / 2 - child->geom.width / 2; + child->geom.y = area->y; + break; + case AUI_ANCHOR_NE: + child->geom.x = area->x + area->width - child->geom.width; + child->geom.y = area->y; + break; + case AUI_ANCHOR_CENTER: + child->geom.x = area->x + area->width / 2 - child->geom.width / 2; + child->geom.y = area->y + area->height / 2 - child->geom.height / 2; + break; + case AUI_ANCHOR_SE: + child->geom.x = area->x + area->width - child->geom.width; + child->geom.y = area->y + area->height - child->geom.height; + break; + case AUI_ANCHOR_S: + child->geom.x = area->x + area->width / 2 - child->geom.width / 2; + child->geom.y = area->y + area->height - child->geom.height; + break; + case AUI_ANCHOR_SW: + child->geom.x = area->x; + child->geom.y = area->y + area->height - child->geom.height; + break; + case AUI_ANCHOR_W: + child->geom.x = area->x; + child->geom.y = area->y + area->height / 2 - child->geom.height / 2; + break; + case AUI_ANCHOR_E: + child->geom.x = area->x + area->width - child->geom.width; + child->geom.y = area->y + area->height / 2 - child->geom.height / 2; + break; + default: + break; + break; + } + + child->ops->set_geometry(child, &child->geom); + } + + TAILQ_FOREACH(child, &widget->queue, entries) { + switch (child->type) { + case WIDGET_TYPE_FRAME: + layout_organize(child); + break; + default: + break; + } + } +} + +void layout_organize(struct aui_widget *widget) { struct aui_container *con = (struct aui_container *)widget; @@ -58,454 +513,17 @@ layout_organize(struct aui_widget *widget) switch (con->layout_type) { case AUI_LAYOUT_PLACE: - TAILQ_FOREACH(child, &widget->queue, entries) { - if (child->mapped == 0) - continue; - - struct aui_placepar *par = &child->placepar; - int dx = 0, dy = 0; - - struct aui_geometry geom = { - .x = widget->geom.x + child->placepar.x + widget->geom.width * child->placepar.relx, - .y = widget->geom.y + child->placepar.y + widget->geom.height * child->placepar.rely, - .width = child->placepar.width + child->placepar.relwidth * widget->geom.width, - .height = child->placepar.height + child->placepar.relheight * widget->geom.height }; - - switch (par->anchor) { - case AUI_ANCHOR_NW: - dx = 0; - dy = 0; - break; - case AUI_ANCHOR_NE: - dx = -geom.width; - dy = 0; - break; - case AUI_ANCHOR_N: - dx = -geom.width / 2; - dy = 0; - break; - case AUI_ANCHOR_W: - dx = 0; - dy = -geom.height / 2; - break; - case AUI_ANCHOR_E: - dx = -geom.width; - dy = -geom.height /2; - break; - case AUI_ANCHOR_SE: - dx = -geom.width; - dy = -geom.height; - break; - case AUI_ANCHOR_SW: - dx = 0; - dy = -geom.height; - break; - case AUI_ANCHOR_S: - dx = -geom.width / 2; - dy = -geom.height; - break; - case AUI_ANCHOR_CENTER: - dx = -geom.width / 2; - dy = -geom.height / 2; - break; - default: - break; - } - - geom.x += dx; - geom.y += dy; - child->ops->set_geometry(child, &geom); - - switch (child->type) { - case WIDGET_TYPE_FRAME: - layout_organize(child); - break; - default: - break; - } - } + place(widget); break; - case AUI_LAYOUT_GRID: { - uint8_t *rmap = calloc(con->grid_size[1], sizeof(uint8_t)); - uint8_t *cmap = calloc(con->grid_size[0], sizeof(uint8_t)); - - unsigned int *rsize = calloc(con->grid_size[1], sizeof(unsigned int)); - unsigned int *csize = calloc(con->grid_size[0], sizeof(unsigned int)); - - TAILQ_FOREACH(child, &widget->queue, entries) { - if (child->mapped == 0) - continue; - - struct aui_geometry min = child->ops->get_min_size(child); - - rmap[child->gridpar.row] = 1; - cmap[child->gridpar.column] = 1; - - rsize[child->gridpar.row] = (rsize[child->gridpar.row] < min.height) ? - min.height : rsize[child->gridpar.row]; - - csize[child->gridpar.column] = (csize[child->gridpar.column] < min.width) ? - min.width : csize[child->gridpar.column]; - } - - unsigned int *rpos = calloc(con->grid_size[1], sizeof(unsigned int)); - unsigned int *cpos = calloc(con->grid_size[0], sizeof(unsigned int)); - - unsigned int rowdt = 0; - unsigned int coldt = 0; - - for (int r = 0; r < con->grid_size[1]; r++) { - rpos[r] = rowdt; - rowdt = (rmap[r] == 1) ? rowdt + rsize[r] : rowdt; - } - - for (int c = 0; c < con->grid_size[0]; c++) { - cpos[c] = coldt; - coldt = (cmap[c] == 1) ? coldt + csize[c] : coldt; - } - - TAILQ_FOREACH(child, &widget->queue, entries) { - if (child->mapped == 0) - continue; - - struct aui_geometry min = child->ops->get_min_size(child); - struct aui_geometry geom = { 0 }; - - int dx = (csize[child->gridpar.column] - min.width); - int dy = (rsize[child->gridpar.row] - min.height); - - geom.x = widget->geom.x + cpos[child->gridpar.column] + dx / 2; - geom.y = widget->geom.y + rpos[child->gridpar.row] + dy / 2; - geom.width = min.width; - geom.height = min.height; - - child->ops->set_geometry(child, &geom); - } - - free(rsize); - free(csize); - free(rpos); - free(cpos); - free(rmap); - free(cmap); - - TAILQ_FOREACH(child, &widget->queue, entries) { - switch (child->type) { - case WIDGET_TYPE_FRAME: - layout_organize(child); - break; - default: - break; - } - } + case AUI_LAYOUT_GRID: + grid(widget); break; - } /* * Lots of suffering into implementing this one :D */ - case AUI_LAYOUT_PACK: { - struct aui_geometry space = widget->geom; - unsigned int hexpand = 0; - unsigned int vexpand = 0; - unsigned int req_w = 0; - unsigned int req_h = 0; - int extra_w = 0; - int extra_h = 0; - int hextra = 0; - int vextra = 0; - - /* - * Compute requested and extra space. hextra and vextra are only set - * if there is no top/bottom widgets succeeding it. This guarantees - * a proper request size. - */ - TAILQ_FOREACH(child, &widget->queue, entries) { - if (child->mapped == 0) - continue; - - struct aui_geometry cgeom = child->ops->get_min_size(child); - switch (child->packpar.side) { - case AUI_SIDE_TOP: - case AUI_SIDE_BOTTOM: - vexpand = (child->packpar.expand) ? vexpand + 1 : vexpand; - if (vextra) vextra = 0; - req_h += cgeom.height; - hextra = (cgeom.width > hextra) ? cgeom.width : hextra; - break; - case AUI_SIDE_LEFT: - case AUI_SIDE_RIGHT: - hexpand = (child->packpar.expand) ? hexpand + 1 : hexpand; - if (hextra) hextra = 0; - vextra = (cgeom.height > vextra) ? cgeom.height : vextra; - req_w += cgeom.width; - break; - default: - break; - } - } - - req_w += hextra; - req_h += vextra; - - if (req_w > space.width) - req_w = space.width; - - if (req_h > space.height) - req_h = space.height; - - extra_w = space.width - req_w; - extra_h = space.height - req_h; - - /* - * Making sure each widget consume space before expension - * for their area. - */ - TAILQ_FOREACH(child, &widget->queue, entries) { - if (child->mapped == 0) - continue; - - struct aui_geometry min = child->ops->get_min_size(child); - - switch (child->packpar.side) { - case AUI_SIDE_TOP: - child->packarea = (struct aui_geometry) { - .x = space.x, - .y = space.y, - .width = space.width, - .height = min.height, - }; - - if (child->packarea.height > space.height) { - child->packarea.height = space.height; - } - - space.y += child->packarea.height; - space.height -= child->packarea.height; - break; - case AUI_SIDE_BOTTOM: - child->packarea = (struct aui_geometry) { - .x = space.x, - .y = space.y, - .width = space.width, - .height = min.height - }; - - if (child->packarea.height > space.height) { - child->packarea.height = space.height; - } - - child->packarea.y = space.y + space.height - child->packarea.height; - - space.height -= child->packarea.height; - break; - case AUI_SIDE_LEFT: - child->packarea = (struct aui_geometry) { - .x = space.x, - .y = space.y, - .width = min.width, - .height = space.height - }; - - if (child->packarea.width > space.width) { - child->packarea.width = space.width; - } - - space.x += child->packarea.width; - space.width -= child->packarea.width; - break; - case AUI_SIDE_RIGHT: - child->packarea = (struct aui_geometry) { - .x = space.x, - .y = space.y, - .width = min.width, - .height = space.height - }; - - if (child->packarea.width > space.width) { - child->packarea.width = space.width; - } - - child->packarea.x = space.x + space.width - child->packarea.width; - - space.width -= child->packarea.width; - break; - default: - break; - } - } - - int top = 0; - int bottom = 0; - int right = 0; - int left = 0; - - /* - * Consuming the remaining space if expanded - */ - TAILQ_FOREACH(child, &widget->queue, entries) { - if (child->mapped == 0) - continue; - - if (space.width == 0 && space.height == 0) - break; - - struct aui_geometry *area = &child->packarea; - - switch (child->packpar.side) { - case AUI_SIDE_TOP: - area->x += left; - area->y += top; - area->width -= left; - - area->width -= right; - - if (child->packpar.expand == 1) { - if (vexpand) { - top += extra_h / vexpand; - area->height += extra_h / vexpand; - extra_h -= extra_h / vexpand; - vexpand--; - } - } - break; - - case AUI_SIDE_BOTTOM: - area->x += left; - area->width -= left; - - area->width -= right; - if (child->packpar.expand == 1) { - if (vexpand) { - bottom += extra_h / vexpand; - area->height += extra_h / vexpand; - area->y -= extra_h / vexpand; - extra_h -= extra_h / vexpand; - vexpand--; - } - } - break; - case AUI_SIDE_LEFT: - area->y += top; - area->x += left; - area->height -= top; - area->height -= bottom; - - if (child->packpar.expand == 1) { - if (hexpand) { - left += extra_w / hexpand; - area->width += extra_w / hexpand; - extra_w -= extra_w / hexpand; - hexpand--; - } - } - break; - case AUI_SIDE_RIGHT: - area->y += top; - area->height -= top; - area->height -= bottom; - - if (child->packpar.expand == 1) { - if (hexpand) { - right += extra_w / hexpand; - area->x -= extra_w / hexpand; - area->width += extra_w / hexpand; - extra_w -= extra_w / hexpand; - hexpand--; - } - } - break; - default: - break; - } - } - - /* - * Setting geometry - */ - TAILQ_FOREACH(child, &widget->queue, entries) { - if (child->mapped == 0) - continue; - - struct aui_geometry min = child->ops->get_min_size(child); - struct aui_geometry *area = &child->packarea; - - switch (child->packpar.fill) { - case AUI_FILL_NONE: - child->geom.width = (min.width > area->width) ? area->width : min.width; - child->geom.height = (min.height > area->height) ? area->height : min.height; - break; - case AUI_FILL_X: - child->geom.width = area->width; - child->geom.height = (min.height > area->height) ? area->height : min.height; - break; - case AUI_FILL_Y: - child->geom.width = (min.width > area->width) ? area->width : min.width; - child->geom.height = area->height; - break; - case AUI_FILL_BOTH: - child->geom.width = area->width; - child->geom.height = area->height; - break; - default: - break; - } - - switch (child->packpar.anchor) { - case AUI_ANCHOR_NW: - child->geom.x = area->x; - child->geom.y = area->y; - break; - case AUI_ANCHOR_N: - child->geom.x = area->x + area->width / 2 - child->geom.width / 2; - child->geom.y = area->y; - break; - case AUI_ANCHOR_NE: - child->geom.x = area->x + area->width - child->geom.width; - child->geom.y = area->y; - break; - case AUI_ANCHOR_CENTER: - child->geom.x = area->x + area->width / 2 - child->geom.width / 2; - child->geom.y = area->y + area->height / 2 - child->geom.height / 2; - break; - case AUI_ANCHOR_SE: - child->geom.x = area->x + area->width - child->geom.width; - child->geom.y = area->y + area->height - child->geom.height; - break; - case AUI_ANCHOR_S: - child->geom.x = area->x + area->width / 2 - child->geom.width / 2; - child->geom.y = area->y + area->height - child->geom.height; - break; - case AUI_ANCHOR_SW: - child->geom.x = area->x; - child->geom.y = area->y + area->height - child->geom.height; - break; - case AUI_ANCHOR_W: - child->geom.x = area->x; - child->geom.y = area->y + area->height / 2 - child->geom.height / 2; - break; - case AUI_ANCHOR_E: - child->geom.x = area->x + area->width - child->geom.width; - child->geom.y = area->y + area->height / 2 - child->geom.height / 2; - break; - default: - break; - break; - } - - child->ops->set_geometry(child, &child->geom); - } - - TAILQ_FOREACH(child, &widget->queue, entries) { - switch (child->type) { - case WIDGET_TYPE_FRAME: - layout_organize(child); - break; - default: - break; - } - } + case AUI_LAYOUT_PACK: + pack(widget); break; - } default: break; } @@ -572,6 +590,12 @@ aui_grid(struct aui_widget *widget, struct aui_gridpar int check = can_add(widget, AUI_LAYOUT_GRID); struct aui_widget *parent; struct aui_container *con; + unsigned int *rsizes; + unsigned int *csizes; + unsigned int *rpos; + unsigned int *cpos; + uint8_t *rmaps; + uint8_t *cmaps; if (check == -1) return -1; @@ -589,6 +613,49 @@ aui_grid(struct aui_widget *widget, struct aui_gridpar con->grid_size[0] = (con->grid_size[0] > par->column + 1) ? con->grid_size[0] : par->column + 1; con->grid_size[1] = (con->grid_size[1] > par->row + 1) ? con->grid_size[1] : par->row + 1; + rmaps = reallocarray(con->row_maps, con->grid_size[1], sizeof(*con->row_maps)); + if (rmaps == NULL) { + fprintf(stderr, "libaui: failed to allocate row maps\n"); + return -1; + } + con->row_maps = rmaps; + + cmaps = reallocarray(con->col_maps, con->grid_size[0], sizeof(*con->col_maps)); + if (cmaps == NULL) { + fprintf(stderr, "libaui: failed to allocate col maps\n"); + return -1; + } + con->col_maps = cmaps; + + + rsizes = reallocarray(con->row_sizes, con->grid_size[1], sizeof(*con->row_sizes)); + if (rsizes == NULL) { + fprintf(stderr, "libaui: failed to allocated row sizes\n"); + return -1; + } + con->row_sizes = rsizes; + + csizes = reallocarray(con->col_sizes, con->grid_size[0], sizeof(*con->col_sizes)); + if (csizes == NULL) { + fprintf(stderr, "libaui: failed to allocated col sizes\n"); + return -1; + } + con->col_sizes = csizes; + + rpos = reallocarray(con->row_pos, con->grid_size[1], sizeof(*con->row_pos)); + if (rpos == NULL) { + fprintf(stderr, "libaui: failed to allocate row positions\n"); + return -1; + } + con->row_pos = rpos; + + cpos = reallocarray(con->col_pos, con->grid_size[0], sizeof(*con->col_pos)); + if (cpos == NULL) { + fprintf(stderr, "libaui: failed to allocate col positions\n"); + return -1; + } + con->col_pos = cpos; + layout_organize(parent); return 0; blob - f5e91b8a3d37b22614a38538601fcc76e0b3ea3e blob + 7a83c3dbf2d1c03d32bd4dd5371081607aaee0b2 --- widget.h +++ widget.h @@ -61,9 +61,19 @@ struct widget_ops { struct aui_container { struct aui_widget widget; enum aui_layout_type layout_type; - uint32_t grid_size[2]; unsigned int map_count; + /* + * Grid members + */ + uint8_t *row_maps; + uint8_t *col_maps; + uint32_t grid_size[2]; + unsigned int *row_sizes; + unsigned int *col_sizes; + unsigned int *row_pos; + unsigned int *col_pos; + struct container_focus { struct aui_widget *press; struct aui_widget *hover;