From 371eed87471036c4ac4e5cf030869bdade8a7107 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Thu, 05 Aug 2021 18:29:03 -0400 Subject: tk: Support alignment of widgets in grid --- (limited to 'src/tk/grid.c') diff --git a/src/tk/grid.c b/src/tk/grid.c index dc25f75..62c5612 100644 --- a/src/tk/grid.c +++ b/src/tk/grid.c @@ -29,8 +29,9 @@ struct mftk_grid { int rows; int cols; struct mftk_widget **children; - int *children_x; - int *children_y; + int *alignments; + int *rows_h; + int *cols_w; int row_spacing; int col_spacing; }; @@ -54,10 +55,10 @@ _mftk_grid_layout(struct mftk_widget *w) max_sz = sz; } } + g->rows_h[r] = max_sz; if (r > 0) { w->h += g->row_spacing; } - g->children_y[r] = w->h; w->h += max_sz; } @@ -70,10 +71,10 @@ _mftk_grid_layout(struct mftk_widget *w) max_sz = sz; } } + g->cols_w[c] = max_sz; if (c > 0) { w->w += g->col_spacing; } - g->children_x[c] = w->w; w->w += max_sz; } } @@ -85,27 +86,62 @@ _mftk_grid_event(struct mftk_widget *w, SDL_Event *e, int x, int y) SDL_Point p; SDL_Rect rect; int r; + int cy; int c; - struct mftk_widget *child; + int cx; + int i; + struct mftk_widget *ch; switch (e->type) { case SDL_MOUSEBUTTONUP: p.x = e->button.x; p.y = e->button.y; + cy = y; for (r = 0; r < g->rows; ++r) { + if (r > 0) { + cy += g->row_spacing; + } + cx = x; for (c = 0; c < g->cols; ++c) { - child = g->children[r * g->cols + c]; - rect.x = x + g->children_x[c]; - rect.y = y + g->children_y[r]; - rect.w = child->w; - rect.h = child->h; + if (c > 0) { + cx += g->col_spacing; + } + i = r * g->cols + c; + ch = g->children[i]; + rect.x = cx; + rect.y = cy; + if (g->alignments != NULL) { + if (g->alignments[i] & + MFTK_GRID_HALIGN_C) { + rect.x += (g->cols_w[c] + - ch->w) + / 2; + } else if (g->alignments[i] & + MFTK_GRID_HALIGN_R) { + rect.x += g->cols_w[c] - + ch->w; + } + if (g->alignments[i] & + MFTK_GRID_VALIGN_M) { + rect.y += (g->rows_h[r] + - ch->h) + / 2; + } else if (g->alignments[i] & + MFTK_GRID_VALIGN_B) { + rect.y += g->rows_h[r] - + ch->h; + } + } + rect.w = ch->w; + rect.h = ch->h; if (SDL_PointInRect(&p, &rect) == SDL_TRUE) { - return mftk_widget_event(child, - e, + return mftk_widget_event(ch, e, rect.x, rect.y); } + cx += g->cols_w[c]; } + cy += g->rows_h[r]; } break; default: @@ -118,20 +154,49 @@ _mftk_grid_event(struct mftk_widget *w, SDL_Event *e, int x, int y) static int _mftk_grid_render(struct mftk_widget *w, SDL_Renderer *renderer, int x, int y) { - struct mftk_grid *g = (struct mftk_grid *) w; - int e = 0; - int r; - int c; + struct mftk_grid *g = (struct mftk_grid *) w; + int e = 0; + int r; + int cy; + int c; + int cx; + int i; + struct mftk_widget *ch; + int chx; + int chy; + cy = y; for (r = 0; r < g->rows; ++r) { + if (r > 0) { + cy += g->row_spacing; + } + cx = x; for (c = 0; c < g->cols; ++c) { - if (mftk_widget_render(g->children[r * g->cols + c], - renderer, - x + g->children_x[c], - y + g->children_y[r]) < 0) { + if (c > 0) { + cx += g->col_spacing; + } + i = r * g->cols + c; + ch = g->children[i]; + chx = cx; + chy = cy; + if (g->alignments != NULL) { + if (g->alignments[i] & MFTK_GRID_HALIGN_C) { + chx += (g->cols_w[c] - ch->w) / 2; + } else if (g->alignments[i]&MFTK_GRID_HALIGN_R){ + chx += g->cols_w[c] - ch->w; + } + if (g->alignments[i] & MFTK_GRID_VALIGN_M) { + chy += (g->rows_h[r] - ch->h) / 2; + } else if (g->alignments[i]&MFTK_GRID_VALIGN_B){ + chy += g->rows_h[r] - ch->h; + } + } + if (mftk_widget_render(ch, renderer, chx, chy) < 0) { e = -1; } + cx += g->cols_w[c]; } + cy += g->rows_h[r]; } return e; @@ -151,21 +216,24 @@ _mftk_grid_destroy(struct mftk_widget *w) } free(g->children); - free(g->children_x); - free(g->children_y); + if (g->alignments != NULL) { + free(g->alignments); + } + free(g->rows_h); + free(g->cols_w); } struct mftk_widget * mftk_grid_new_a(int rows, int cols, int row_spacing, int col_spacing, - struct mftk_widget **children) + struct mftk_widget **children, int *alignments) { struct mftk_widget *w; struct mftk_grid *g; mftk_widget_init(w, g, grid); - g->children_x = calloc(cols, sizeof(*g->children_x)); - if (g->children_x == NULL) { + g->rows_h = calloc(rows, sizeof(*g->rows_h)); + if (g->rows_h == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create widget: %s", strerror(errno)); @@ -173,12 +241,12 @@ mftk_grid_new_a(int rows, int cols, int row_spacing, int col_spacing, free(g); return NULL; } - g->children_y = calloc(rows, sizeof(*g->children_y)); - if (g->children_y == NULL) { + g->cols_w = calloc(cols, sizeof(*g->cols_w)); + if (g->cols_w == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create widget: %s", strerror(errno)); - free(g->children_x); + free(g->rows_h); free(g->children); free(g); return NULL; @@ -189,6 +257,7 @@ mftk_grid_new_a(int rows, int cols, int row_spacing, int col_spacing, g->row_spacing = row_spacing; g->col_spacing = col_spacing; g->children = children; + g->alignments = alignments; return w; } @@ -197,6 +266,7 @@ struct mftk_widget * mftk_grid_new(int rows, int cols, int row_spacing, int col_spacing, ...) { struct mftk_widget **children; + int *alignments; struct mftk_widget *w; va_list ap; int r; @@ -209,18 +279,28 @@ mftk_grid_new(int rows, int cols, int row_spacing, int col_spacing, ...) strerror(errno)); return NULL; } + alignments = calloc(rows * cols, sizeof(*alignments)); + if (alignments == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Couldn't create widget: %s", + strerror(errno)); + return NULL; + } va_start(ap, col_spacing); for (r = 0; r < rows; ++r) { for (c = 0; c < cols; ++c) { children[r*cols + c] = va_arg(ap, struct mftk_widget *); + alignments[r*cols + c] = va_arg(ap, int); } } va_end(ap); - w = mftk_grid_new_a(rows, cols, row_spacing, col_spacing, children); + w = mftk_grid_new_a(rows, cols, row_spacing, col_spacing, children, + alignments); if (w == NULL) { free(children); + free(alignments); } return w; -- cgit v0.9.1