summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2021-08-05 14:45:14 (EDT)
committer P. J. McDermott <pj@pehjota.net>2021-08-05 14:45:14 (EDT)
commit9b20f199806fe63292526279399c15c406740671 (patch)
tree4f85065264b2554277add16c87d5a375ed85eb18 /src
parentfa7a4af184162fabb03e90998b0388672fc354d9 (diff)
downloadmazefight-9b20f199806fe63292526279399c15c406740671.zip
mazefight-9b20f199806fe63292526279399c15c406740671.tar.gz
mazefight-9b20f199806fe63292526279399c15c406740671.tar.bz2
tk: Handle radio button events
Diffstat (limited to 'src')
-rw-r--r--src/tk/check.c8
-rw-r--r--src/tk/radio.c90
-rw-r--r--src/tk/widget.h3
3 files changed, 76 insertions, 25 deletions
diff --git a/src/tk/check.c b/src/tk/check.c
index c8e639c..344ab16 100644
--- a/src/tk/check.c
+++ b/src/tk/check.c
@@ -44,6 +44,14 @@ mftk_check_set_shape(struct mftk_widget *w, enum mftk_check_shape shape)
c->shape = shape;
}
+void
+mftk_check_set_state(struct mftk_widget *w, int state)
+{
+ struct mftk_check *c = (struct mftk_check *) w;
+
+ c->state = state;
+}
+
static void
_mftk_check_layout(struct mftk_widget *w)
{
diff --git a/src/tk/radio.c b/src/tk/radio.c
index fcf63b3..1336b60 100644
--- a/src/tk/radio.c
+++ b/src/tk/radio.c
@@ -24,14 +24,39 @@
#include "../tk.h"
#include "widget.h"
+struct _mftk_radio_state {
+ struct mftk_radio *r;
+ int state;
+};
+
struct mftk_radio {
- struct mftk_widget parent;
- struct mftk_widget *grid;
- int state;
- int (*action)(void *, int);
- void *user_data;
+ struct mftk_widget parent;
+ struct mftk_widget **children;
+ struct mftk_widget *grid;
+ struct _mftk_radio_state *states;
+ int state;
+ int (*action)(void *, int);
+ void *user_data;
};
+static int
+_mftk_radio_state_change(void *user_data, int state)
+{
+ struct _mftk_radio_state *rs = (struct _mftk_radio_state *) user_data;
+
+ if (state == SDL_FALSE) {
+ /* Radio buttons can't be deselected */
+ mftk_check_set_state(rs->r->children[rs->r->state], SDL_TRUE);
+ return 0;
+ } else {
+ /* Deselect previous check button */
+ mftk_check_set_state(rs->r->children[rs->r->state], SDL_FALSE);
+ /* Set and announce new state */
+ rs->r->state = rs->state;
+ return rs->r->action(rs->r->user_data, rs->r->state);
+ }
+}
+
static void
_mftk_radio_layout(struct mftk_widget *w)
{
@@ -64,6 +89,7 @@ _mftk_radio_destroy(struct mftk_widget *w)
struct mftk_radio *r = (struct mftk_radio *) w;
mftk_widget_destroy(&r->grid);
+ free(r->states);
}
struct mftk_widget *
@@ -73,47 +99,61 @@ mftk_radio_new(int butn_width, int butn_padding, SDL_Color *butn_color,
int (*action)(void *, int), void *user_data,
SDL_Renderer *renderer, int state, int options, ...)
{
- struct mftk_widget **children;
- va_list ap;
- int i;
- struct mftk_widget *w;
- struct mftk_radio *r;
-
- children = calloc(options, sizeof(*children));
- if (children == NULL) {
+ struct mftk_widget *w;
+ struct mftk_radio *r;
+ va_list ap;
+ int i;
+
+ mftk_widget_init(w, r, radio);
+
+ r->children = calloc(options, sizeof(*r->children));
+ if (r->children == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Couldn't create widget: %s",
strerror(errno));
+ free(r);
+ return NULL;
+ }
+ r->states = calloc(options, sizeof(*r->states));
+ if (r->states == NULL) {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+ "Couldn't create widget: %s",
+ strerror(errno));
+ free(r->children);
+ free(r);
return NULL;
}
va_start(ap, options);
for (i = 0; i < options; ++i) {
- children[i] = mftk_check_new(butn_width, butn_padding,
+ r->children[i] = mftk_check_new(butn_width, butn_padding,
butn_color, mark_color, (i == state),
label_padding, font, va_arg(ap, const char *),
- text_color, NULL/*TODO*/, NULL/*TODO*/,
- renderer);
- if (children[i] == NULL) {
+ text_color, _mftk_radio_state_change,
+ &r->states[i], renderer);
+ if (r->children[i] == NULL) {
for (; i >= 0; --i) {
- mftk_widget_destroy(&children[i]);
+ mftk_widget_destroy(&r->children[i]);
}
- free(children);
+ free(r->children);
+ free(r->states);
+ free(r);
va_end(ap);
return NULL;
}
- mftk_check_set_shape(children[i], MFTK_CHECK_SHAPE_CIR);
+ mftk_check_set_shape(r->children[i], MFTK_CHECK_SHAPE_CIR);
+ r->states[i].r = r;
+ r->states[i].state = i;
}
va_end(ap);
- mftk_widget_init(w, r, radio);
-
- r->grid = mftk_grid_new_a(options, 1, item_padding, 0, children);
+ r->grid = mftk_grid_new_a(options, 1, item_padding, 0, r->children);
if (r->grid == NULL) {
for (i = 0; i < options; ++i) {
- mftk_widget_destroy(&children[i]);
+ mftk_widget_destroy(&r->children[i]);
}
- free(children);
+ free(r->children);
+ free(r->states);
free(r);
}
diff --git a/src/tk/widget.h b/src/tk/widget.h
index 1ac5f46..402435c 100644
--- a/src/tk/widget.h
+++ b/src/tk/widget.h
@@ -62,4 +62,7 @@ enum mftk_check_shape {
void
mftk_check_set_shape(struct mftk_widget *w, enum mftk_check_shape shape);
+void
+mftk_check_set_state(struct mftk_widget *w, int state);
+
#endif /* MFTK_WIDGET_H_ */