summaryrefslogtreecommitdiffstats
path: root/src/tk
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2021-08-05 18:29:03 (EDT)
committer P. J. McDermott <pj@pehjota.net>2021-08-05 18:37:18 (EDT)
commit371eed87471036c4ac4e5cf030869bdade8a7107 (patch)
tree38e919bc2e5dd016edc166f59aa332bff75a64f3 /src/tk
parent674e4bedcc69288da92248e0f988b45f1c055fee (diff)
downloadmazefight-371eed87471036c4ac4e5cf030869bdade8a7107.zip
mazefight-371eed87471036c4ac4e5cf030869bdade8a7107.tar.gz
mazefight-371eed87471036c4ac4e5cf030869bdade8a7107.tar.bz2
tk: Support alignment of widgets in grid
Diffstat (limited to 'src/tk')
-rw-r--r--src/tk/grid.c138
-rw-r--r--src/tk/radio.c3
-rw-r--r--src/tk/widget.h2
3 files changed, 112 insertions, 31 deletions
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;
diff --git a/src/tk/radio.c b/src/tk/radio.c
index 1336b60..71c9486 100644
--- a/src/tk/radio.c
+++ b/src/tk/radio.c
@@ -147,7 +147,8 @@ mftk_radio_new(int butn_width, int butn_padding, SDL_Color *butn_color,
}
va_end(ap);
- r->grid = mftk_grid_new_a(options, 1, item_padding, 0, r->children);
+ r->grid = mftk_grid_new_a(options, 1, item_padding, 0, r->children,
+ NULL);
if (r->grid == NULL) {
for (i = 0; i < options; ++i) {
mftk_widget_destroy(&r->children[i]);
diff --git a/src/tk/widget.h b/src/tk/widget.h
index 402435c..b474f09 100644
--- a/src/tk/widget.h
+++ b/src/tk/widget.h
@@ -52,7 +52,7 @@ mftk_widget_new(size_t size);
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);
enum mftk_check_shape {
MFTK_CHECK_SHAPE_BOX,