/* * 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 . */ #include #include "errno.h" #include #include #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; mftk_widget_init(w, g, grid); 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; }