commit - 98d0e23f0c6d7384bfd5f4cfe5ac016c019f71e3
commit + 8964e49031e0a23aaa0d9d2155a62bba92b5d587
blob - 02ef472c17c38b13da36ebae7a87f31f33977bfc
blob + 526401143b87409307e1d991f80cabac3e6b3de6
--- Makefile
+++ Makefile
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
struct aui_gridpar {
unsigned int column;
unsigned int row;
+ unsigned int columnspan;
+ unsigned int rowspan;
};
struct aui_widget;
};
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
-.Dd $Mdocdate: July 07 2026$
+.Dd $Mdocdate: July 08 2026$
.Dt AUI_RUN 3
.Os
.Sh NAME
.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 ,
.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
.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
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
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
}
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;
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;
}
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;
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
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;