summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2021-08-04 19:06:24 (EDT)
committer P. J. McDermott <pj@pehjota.net>2021-08-04 19:06:24 (EDT)
commit8cdfd577b4f7d70acddde353b600559010ea6d39 (patch)
treee1e9afc6b15e72e5f2e729d3c1785696d4327f04 /src
parent614d914e31f36d751d96309a64953c1f405a33d3 (diff)
downloadmazefight-8cdfd577b4f7d70acddde353b600559010ea6d39.zip
mazefight-8cdfd577b4f7d70acddde353b600559010ea6d39.tar.gz
mazefight-8cdfd577b4f7d70acddde353b600559010ea6d39.tar.bz2
tk: Add grid widget
Diffstat (limited to 'src')
-rw-r--r--src/tk.h3
-rw-r--r--src/tk/grid.c195
-rw-r--r--src/tk/local.mk1
3 files changed, 199 insertions, 0 deletions
diff --git a/src/tk.h b/src/tk.h
index c41b194..7a3c9c6 100644
--- a/src/tk.h
+++ b/src/tk.h
@@ -53,4 +53,7 @@ mftk_button_new(TTF_Font *font, const char *text, SDL_Color *text_color,
SDL_Color *fill_color, int padding,
int (*action)(void *), void *user_data, SDL_Renderer *renderer);
+struct mftk_widget *
+mftk_grid_new(int rows, int cols, int row_spacing, int col_spacing, ...);
+
#endif /* MFTK_H_ */
diff --git a/src/tk/grid.c b/src/tk/grid.c
new file mode 100644
index 0000000..4f09928
--- /dev/null
+++ b/src/tk/grid.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2021 P. J. McDermott
+ *
+ * This file is part of Maze Fight
+ *
+ * Maze Fight is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Maze Fight is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Maze Fight. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <SDL.h>
+#include "errno.h"
+#include <stdlib.h>
+#include <string.h>
+#include "../tk.h"
+#include "widget.h"
+
+struct mftk_grid {
+ struct mftk_widget parent;
+ int rows;
+ int cols;
+ struct mftk_widget **children;
+ int *children_x;
+ int *children_y;
+ int row_spacing;
+ int col_spacing;
+};
+
+static void
+_mftk_grid_layout(struct mftk_widget *w)
+{
+ struct mftk_grid *g = (struct mftk_grid *) w;
+ int r;
+ int c;
+ int sz;
+ int max_sz;
+
+ w->h = 0;
+ for (r = 0; r < g->rows; ++r) {
+ g->children_y[r] = w->h;
+ max_sz = 0;
+ for (c = 0; c < g->cols; ++c) {
+ mftk_widget_layout(g->children[r * g->cols + c]);
+ sz = g->children[r * g->cols + c]->h;
+ if (sz > max_sz) {
+ max_sz = sz;
+ }
+ }
+ if (r > 0) {
+ w->h += g->row_spacing;
+ }
+ w->h += max_sz;
+ }
+
+ w->w = 0;
+ for (c = 0; c < g->cols; ++c) {
+ g->children_x[c] = w->w;
+ max_sz = 0;
+ for (r = 0; r < g->rows; ++r) {
+ sz = g->children[r * g->cols + c]->w;
+ if (sz > max_sz) {
+ max_sz = sz;
+ }
+ }
+ if (c > 0) {
+ w->w += g->col_spacing;
+ }
+ w->w += max_sz;
+ }
+}
+
+static int
+_mftk_grid_event(struct mftk_widget *w, SDL_Event *e)
+{
+ struct mftk_grid *g = (struct mftk_grid *) w;
+
+ switch (e->type) {
+ case SDL_MOUSEBUTTONUP:
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+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;
+
+ for (r = 0; r < g->rows; ++r) {
+ 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) {
+ e = -1;
+ }
+ }
+ }
+
+ return e;
+}
+
+static void
+_mftk_grid_destroy(struct mftk_widget *w)
+{
+ struct mftk_grid *g = (struct mftk_grid *) w;
+ int r;
+ int c;
+
+ for (r = 0; r < g->rows; ++r) {
+ for (c = 0; c < g->cols; ++c) {
+ mftk_widget_destroy(&g->children[r * g->cols + c]);
+ }
+ }
+
+ free(g->children);
+ free(g->children_x);
+ free(g->children_y);
+}
+
+struct mftk_widget *
+mftk_grid_new(int rows, int cols, int row_spacing, int col_spacing, ...)
+{
+ struct mftk_widget *w;
+ struct mftk_grid *g;
+ va_list ap;
+ int r;
+ int c;
+
+ if ((w = mftk_widget_new(sizeof(*g))) == NULL) return NULL;
+ g = (struct mftk_grid *) w;
+ w->layout = &_mftk_grid_layout;
+ w->event = &_mftk_grid_event;
+ w->render = &_mftk_grid_render;
+ w->destroy = &_mftk_grid_destroy;
+
+ g->children = calloc(rows * cols, sizeof(*g->children));
+ if (g->children == NULL) {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "Couldn't create widget: %s",
+ strerror(errno));
+ free(g);
+ return NULL;
+ }
+ g->children_x = calloc(cols, sizeof(*g->children_x));
+ if (g->children_x == NULL) {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "Couldn't create widget: %s",
+ strerror(errno));
+ free(g->children);
+ free(g);
+ return NULL;
+ }
+ g->children_y = calloc(rows, sizeof(*g->children_y));
+ if (g->children_y == NULL) {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "Couldn't create widget: %s",
+ strerror(errno));
+ free(g->children_x);
+ free(g->children);
+ free(g);
+ return NULL;
+ }
+
+ g->rows = rows;
+ g->cols = cols;
+ g->row_spacing = row_spacing;
+ g->col_spacing = col_spacing;
+
+ va_start(ap, col_spacing);
+ for (r = 0; r < g->rows; ++r) {
+ for (c = 0; c < g->cols; ++c) {
+ g->children[r * g->cols + c] = va_arg(ap,
+ struct mftk_widget *);
+ }
+ }
+ va_end(ap);
+
+ return w;
+}
diff --git a/src/tk/local.mk b/src/tk/local.mk
index cb71e9f..a15bd33 100644
--- a/src/tk/local.mk
+++ b/src/tk/local.mk
@@ -1,5 +1,6 @@
mazefight_SOURCES += \
%reldir%/button.c \
+ %reldir%/grid.c \
%reldir%/label.c \
%reldir%/widget.c \
%reldir%/widget.h