Commit Diff


commit - d7667be892b6c39aa9a1f7ff16e3ee996a9b0b0b
commit + 5a91456705cbad9b60a5a8bdb2e2d312139f1b9a
blob - 23726f477429dbcce18c8e990451b9de4f169f21
blob + 456d9eb5f774977bd662cccd0aaec64462564ce3
--- aui.h
+++ aui.h
@@ -50,26 +50,14 @@ struct aui_gridpar {
 	unsigned int row;
 	unsigned int columnspan;
 	unsigned int rowspan;
-	unsigned int ipadx; /* Internal padding X */
-	unsigned int ipady; /* Internal padding Y */
-	unsigned int padx;
-	unsigned int pady;
+	unsigned char sticky;
 };
 
-struct aui_rowpar {
+struct aui_gridconfigure {
 	unsigned int minsize;
-	unsigned char weight; /*  Minimum is 1 */
-	unsigned char uniform;
-	unsigned int pad;
+	unsigned char weight;
 };
 
-struct aui_columnpar {
-	unsigned int minsize;
-	unsigned char weight; /*  Minimum is 1 */
-	unsigned char uniform;
-	unsigned int pad;
-};
-
 struct aui_widget;
 struct aui_window;
 struct aui_frame;
@@ -125,8 +113,8 @@ int aui_getpackpar(struct aui_widget *, struct aui_pac
 /*
  * Grid container operations
  */
-int aui_rowconfigure(struct aui_widget *, struct aui_rowpar *);
-int aui_columnconfigure(struct aui_widget *, struct aui_columnpar *);
+int aui_rowconfigure(struct aui_widget *, int, struct aui_gridconfigure *);
+int aui_columnconfigure(struct aui_widget *, int, struct aui_gridconfigure *);
 
 #define AUI_CANVAS_RECTANGLE		0
 #define AUI_CANVAS_ARC				1
blob - 27247026aac62a520238719eea0fa73522bf1522
blob + 3351733279b5a3765dab3eea8876a9cc1319ffb8
--- aui_run.3
+++ aui_run.3
@@ -1,4 +1,4 @@
-.Dd $Mdocdate: July 14 2026$
+.Dd $Mdocdate: July 30 2026$
 .Dt AUI_RUN 3
 .Os
 .Sh NAME
@@ -55,6 +55,10 @@
 .Fn aui_getgridpar "struct aui_widget * widget"
 .Ft int
 .Fn aui_getpackpar "struct aui_widget * widget"
+.Ft int
+.Fn aui_columnconfigure "struct aui_widget * widget" "int index" "struct aui_gridconfigure * config"
+.Ft int
+.Fn aui_rowconfigure "struct aui_widget * widget" "int index" "struct aui_gridconfigure * config"
 .Sh DESCRIPTION
 Assides for windows, every widget must take a container in order to be
 created. The containers can be a window or a frame. Once a widget is
blob - b831bfede94fa9091f932ac551253007c170c259
blob + 610f28e9e1c67ac1f9af5dd6eaccd5f57aca9962
--- layout.c
+++ layout.c
@@ -29,26 +29,13 @@ static struct aui_gridpar default_grid = {
 	.row = 0,
 	.columnspan = 1,
 	.rowspan = 1,
-	.ipadx = 0,
-	.ipady = 0,
-	.padx = 0,
-	.pady = 0
 };
 
-static struct aui_rowpar default_rowconfigure = {
+static struct aui_gridconfigure default_gridconfigure = {
 	.minsize = 0,
 	.weight = 0,
-	.uniform = 0,
-	.pad = 0,
 };
 
-static struct aui_columnpar default_columnconfigure = {
-	.minsize = 0,
-	.weight = 0,
-	.uniform = 0,
-	.pad = 0,
-};
-
 static int
 can_add(struct aui_widget *widget, enum aui_layout_type type)
 {
@@ -147,49 +134,38 @@ 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;
+	unsigned int column_weights = 0;
+	unsigned int row_weights = 0;
 	struct aui_widget *child;
+	unsigned int height = 0;
+	unsigned int width = 0;
+	int extra_w, extra_h;
 
 	unsigned int *rsize = con->row_sizes;
 	unsigned int *csize = con->col_sizes;
-
-	memset(con->row_maps, 0, sizeof(*con->row_maps) * con->grid_size[1]);
-	memset(con->col_maps, 0, sizeof(*con->col_maps) * con->grid_size[0]);
-
-	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;
+	memset(rsize, 0, sizeof(*rsize) * con->grid_size[1]);
+	memset(csize, 0, sizeof(*csize) * con->grid_size[0]);
 
-	for (int r = 0; r < con->grid_size[1]; r++) {
-		rpos[r] = rowdt;
-		rowdt = (rmap[r] == 1) ? rowdt + rsize[r] : rowdt;
+	memset(cpos, 0, sizeof(*cpos) * con->grid_size[0]);
+	memset(rpos, 0, sizeof(*rpos) * con->grid_size[1]);
+
+	/*
+	 * Setting up the minimum dimensions and getting the
+	 * extra space for distribution.
+	 */
+	for (int i = 0; i < con->grid_size[0]; i++) {
+		column_weights += con->columnconfigure[i].weight;
+		csize[i] = con->columnconfigure[i].minsize;
+		width += csize[i];
 	}
 
-	for (int c = 0; c < con->grid_size[0]; c++) {
-		cpos[c] = coldt;
-		coldt = (cmap[c] == 1) ? coldt + csize[c] : coldt;
+	for (int i = 0; i < con->grid_size[1]; i++) {
+		row_weights += con->rowconfigure[i].weight;
+		rsize[i] = con->rowconfigure[i].minsize;
+		height += rsize[i];
 	}
 
 	TAILQ_FOREACH(child, &widget->queue, entries) {
@@ -197,33 +173,89 @@ grid(struct aui_widget *widget)
 			continue;
 
 		struct aui_geometry min = child->ops->get_min_size(child);
-		struct aui_geometry geom = { 0 };
-		struct aui_gridpar *gpar = &child->gridpar;
+		int column = child->gridpar.column;
+		int row = child->gridpar.row;
 
-		int cspan = (gpar->column + gpar->columnspan) <= con->grid_size[0] ?
-					gpar->columnspan - 1: con->grid_size[0] - gpar->column - 1;
+		if (min.width > csize[column] && con->columnconfigure[column].weight == 0) {
+			width += min.width - csize[column];
+			csize[column] = min.width;
+		}
 
-		int rspan = (gpar->row + gpar->rowspan) <= con->grid_size[1] ?
-					gpar->rowspan - 1: con->grid_size[1] - gpar->row - 1;
+		if (min.height > rsize[row] && con->rowconfigure[row].weight == 0) {
+			height += min.height - rsize[row];
+			rsize[row] = min.height;
+		}
+	}
 
+	extra_w = (widget->geom.width - width);
+	extra_h = (widget->geom.height - height);
 
-		int dx = (csize[child->gridpar.column] - min.width);
-		int dy = (rsize[child->gridpar.row] - min.height);
+	if (extra_w < 0) extra_w = 0;
+	if (extra_h < 0) extra_h = 0;
 
-		int width = min.width;
-		int height = min.height;
+	/*
+	 * Extra space distribution depending on constraints
+	 */
+	if (extra_w > 0 && column_weights > 0) {
+		for (int i = 0; i < con->grid_size[0]; i++) {
+			csize[i] += con->columnconfigure[i].weight * extra_w / column_weights;
+		}
+	}
 
-		for (int i = gpar->column; i < gpar->column + cspan; i++)
-			width += csize[i];
+	if (extra_h > 0 && row_weights > 0) {
+		for (int i = 0; i < con->grid_size[1]; i++) {
+			rsize[i] += con->rowconfigure[i].weight * extra_h / row_weights;
+		}
+	}
 
-		for (int i = gpar->row; i < gpar->row + rspan; i++)
-			height += rsize[i];
+	/*
+	 * Setting up positions by accumulating occupied cells
+	 */
+	for (int i = 0; i < con->grid_size[1]; i++) {
+		if (i == 0) {
+			rpos[i] = rsize[i];
+			continue;
+		}
 
-		geom.x = widget->geom.x + cpos[child->gridpar.column] + dx / 2;
-		geom.y = widget->geom.y + rpos[child->gridpar.row] + dy / 2;
-		geom.width = width;
-		geom.height = height;
+		rpos[i] = rsize[i] + rpos[i - 1];
+	}
 
+	for (int i = 0; i < con->grid_size[0]; i++) {
+		if (i == 0) {
+			cpos[i] = csize[i];
+			continue;
+		}
+		
+		cpos[i] = csize[i] + cpos[i - 1];
+	}
+
+	TAILQ_FOREACH(child, &widget->queue, entries) {
+		if (child->mapped == 0)
+			continue;
+
+		unsigned int cspan = child->gridpar.columnspan;
+		unsigned int rspan = child->gridpar.rowspan;
+		unsigned int column = child->gridpar.column;
+		unsigned int row = child->gridpar.row;
+		struct aui_geometry geom;
+
+		geom.width = csize[column];
+		geom.height = rsize[row];
+
+		if (cspan > 1) {
+			geom.width = cpos[column + cspan - 1];
+			if (column > 0) geom.width -= cpos[column - 1];
+		}
+
+		if (rspan > 1) {
+			geom.height = rpos[row + rspan - 1];
+
+			if (row > 0) geom.height -= rpos[row - 1];
+		}
+
+		geom.x = widget->geom.x + cpos[column + cspan - 1] - geom.width;
+		geom.y = widget->geom.y + rpos[row + rspan - 1] - geom.height;
+
 		child->ops->set_geometry(child, &geom);
 	}
 
@@ -634,6 +666,8 @@ aui_grid(struct aui_widget *widget, struct aui_gridpar
 	unsigned int *csizes;
 	unsigned int *rpos;
 	unsigned int *cpos;
+	unsigned int nrow;
+	unsigned int ncol;
 	uint8_t *rmaps;
 	uint8_t *cmaps;
 
@@ -652,27 +686,35 @@ aui_grid(struct aui_widget *widget, struct aui_gridpar
 	widget->mapped = 1;
 	con->map_count++;
 
+	nrow = con->grid_size[1];
+	ncol = con->grid_size[0];
+
 	con->grid_size[0] = (con->grid_size[0] > (par->column + par->columnspan)) ? 
 		con->grid_size[0] : (par->column + par->columnspan);
 
 	con->grid_size[1] = (con->grid_size[1] > (par->row + par->rowspan)) ? 
 		con->grid_size[1] : (par->row + par->rowspan);
 
-	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;
+	if (nrow < con->grid_size[1]) {
+		struct aui_gridconfigure *ptr = reallocarray(con->rowconfigure,
+			con->grid_size[1], sizeof(*con->rowconfigure));
 
-	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;
+		for (int i = nrow; i < con->grid_size[1]; i++)
+			memcpy(&ptr[i], &default_gridconfigure, sizeof(default_gridconfigure));
+
+		con->rowconfigure = ptr;
 	}
-	con->col_maps = cmaps;
 
+	if (ncol < con->grid_size[0]) {
+		struct aui_gridconfigure *ptr = reallocarray(con->columnconfigure,
+			con->grid_size[0], sizeof(*con->columnconfigure));
 
+		for (int i = ncol; i < con->grid_size[0]; i++)
+			memcpy(&ptr[i], &default_gridconfigure, sizeof(default_gridconfigure));
+
+		con->columnconfigure = ptr;
+	}
+
 	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");
@@ -726,3 +768,39 @@ aui_getgridpar(struct aui_widget *widget, struct aui_g
 	*par = widget->gridpar;
 	return 0;
 }
+
+int
+aui_rowconfigure(struct aui_widget *widget, int row, struct aui_gridconfigure *config)
+{
+	struct aui_container *con = (struct aui_container *)widget;
+
+	if (config == NULL)
+		config = &default_gridconfigure;
+
+	if (row > con->grid_size[1]) {
+		fprintf(stderr, "libaui: cannot configure row index higher than dimensions\n");
+		return -1;
+	}
+
+	con->rowconfigure[row] = *config;
+	layout_organize(widget);
+	return 0;
+}
+
+int
+aui_columnconfigure(struct aui_widget *widget, int column, struct aui_gridconfigure *config)
+{
+	struct aui_container *con = (struct aui_container *)widget;
+
+	if (config == NULL)
+		config = &default_gridconfigure;
+
+	if (column > con->grid_size[0]) {
+		fprintf(stderr, "libaui: cannot configure column index higher than dimensions\n");
+		return -1;
+	}
+
+	con->columnconfigure[column] = *config;
+	layout_organize(widget);
+	return 0;
+}
blob - ff0077c16e3465ac05c6d6ec98065e4f0a6f14ba
blob + 58662b34a7f8eebec0d48b0ebb26d2ca780ad000
--- widget.h
+++ widget.h
@@ -66,15 +66,13 @@ struct aui_container {
 	/*
 	 * 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 aui_rowpar *rowconfigure;
-	struct aui_columnpar *columnconfigure;
+	struct aui_gridconfigure *rowconfigure;
+	struct aui_gridconfigure *columnconfigure;
 
 	struct container_focus {
 		struct aui_widget *press;