diff options
author | P. 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) |
commit | 9b20f199806fe63292526279399c15c406740671 (patch) | |
tree | 4f85065264b2554277add16c87d5a375ed85eb18 /src | |
parent | fa7a4af184162fabb03e90998b0388672fc354d9 (diff) | |
download | mazefight-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.c | 8 | ||||
-rw-r--r-- | src/tk/radio.c | 90 | ||||
-rw-r--r-- | src/tk/widget.h | 3 |
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_ */ |