/* * 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 "../tk.h" #include "style.h" #include "widget.h" struct mftk_button { struct mftk_widget parent; struct mftk_widget *label; int padding; int border; int (*action)(void *); void *user_data; }; static void _mftk_button_layout(struct mftk_widget *w) { struct mftk_button *b = (struct mftk_button *) w; mftk_widget_layout(b->label); w->w = b->label->w + b->padding * 2 + b->border * 2; w->h = b->label->h + b->padding * 2 + b->border * 2; } static void _mftk_button_focus(struct mftk_widget *w __attribute__((__unused__))) { /* Nothing to do */ } static void _mftk_button_defocus(struct mftk_widget *w __attribute__((__unused__))) { /* Nothing to do */ } static int _mftk_button_key_event(struct mftk_widget *w, SDL_Event *e) { struct mftk_button *b = (struct mftk_button *) w; switch (e->type) { case SDL_KEYDOWN: switch (e->key.keysym.sym) { case SDLK_SPACE: case SDLK_RETURN: case SDLK_KP_ENTER: if (b->action == NULL) { return 0; } return b->action(b->user_data); default: break; } default: break; } return 0; } static int _mftk_button_mouse_event(struct mftk_widget *w, SDL_Event *e, int x __attribute__((__unused__)), int y __attribute__((__unused__))) { struct mftk_button *b = (struct mftk_button *) w; switch (e->type) { case SDL_MOUSEBUTTONUP: if (e->button.button == SDL_BUTTON_LEFT) { mftk_window_focus(w->window, w); if (b->action == NULL) { return 0; } return b->action(b->user_data); } break; default: break; } return 0; } static int _mftk_button_render(struct mftk_widget *w, SDL_Renderer *renderer, int x, int y) { struct mftk_button *b = (struct mftk_button *) w; SDL_Rect rect; SDL_Color border; rect.x = x; rect.y = y; rect.w = w->w; rect.h = w->h; if (w->focused == SDL_TRUE) { border.r = MFTK_COLOR_BDRF_R, border.g = MFTK_COLOR_BDRF_G; border.b = MFTK_COLOR_BDRF_B, border.a = MFTK_COLOR_BDRF_A; } else { border.r = MFTK_COLOR_BDRN_R, border.g = MFTK_COLOR_BDRN_G; border.b = MFTK_COLOR_BDRN_B, border.a = MFTK_COLOR_BDRN_A; } if (SDL_SetRenderDrawColor(renderer, border.r, border.g, border.b, border.a) < 0 || SDL_RenderFillRect(renderer, &rect) < 0) { goto err; } rect.x += b->border; rect.y += b->border; rect.w -= b->border * 2; rect.h -= b->border * 2; if (SDL_SetRenderDrawColor(renderer, MFTK_COLOR_BACK_R, MFTK_COLOR_BACK_G, MFTK_COLOR_BACK_B, MFTK_COLOR_BACK_A) < 0 || SDL_RenderFillRect(renderer, &rect) < 0) { goto err; } if (mftk_widget_render(b->label, renderer, x + b->padding, y + b->padding) < 0) { return -1; } return 0; err: SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't render widget: %s", SDL_GetError()); return -1; } static void _mftk_button_destroy(struct mftk_widget *w) { struct mftk_button *b = (struct mftk_button *) w; mftk_widget_destroy(&b->label); } struct mftk_widget * mftk_button_new(TTF_Font *font, const char *text, int padding, int border, int (*action)(void *), void *user_data, SDL_Renderer *renderer) { struct mftk_widget *w; struct mftk_button *b; mftk_widget_init_focusable(w, b, button); b->label = mftk_label_new(font, text, renderer); if (b->label == NULL) { free(b); return NULL; } b->padding = padding; b->border = border; b->action = action; b->user_data = user_data; return w; }