Mercurial > molko
changeset 115:3bd0d3a39e30
core: implement checkbox, closes #2486
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 12 Jul 2020 09:44:27 +0200 |
parents | bf7500aea454 |
children | 0a6683615c73 |
files | Makefile examples/example-sound.c src/adventure/main.c src/core/button.c src/core/checkbox.c src/core/checkbox.h src/core/theme.c src/core/theme.h |
diffstat | 8 files changed, 214 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Thu Jul 09 22:38:48 2020 +0200 +++ b/Makefile Sun Jul 12 09:44:27 2020 +0200 @@ -52,6 +52,7 @@ CORE_SRCS= src/core/animation.c \ src/core/button.c \ + src/core/checkbox.c \ src/core/clock.c \ src/core/debug.c \ src/core/error.c \
--- a/examples/example-sound.c Thu Jul 09 22:38:48 2020 +0200 +++ b/examples/example-sound.c Sun Jul 12 09:44:27 2020 +0200 @@ -38,7 +38,7 @@ .text = "Keys: <s> start, <p> pause, <r> resume, <q> stop, <l> loop", .x = 10, .y = 10, - .w = 1920, + .w = W, .h = 32, .flags = LABEL_NO_HCENTER };
--- a/src/adventure/main.c Thu Jul 09 22:38:48 2020 +0200 +++ b/src/adventure/main.c Sun Jul 12 09:44:27 2020 +0200 @@ -23,6 +23,7 @@ #include <string.h> #include "button.h" +#include "checkbox.h" #include "clock.h" #include "debug.h" #include "error.h" @@ -83,12 +84,18 @@ run(void) { struct clock clock = { 0 }; - struct button button = { - .text = "click me", + struct frame mainmenu = { .x = 10, - .y = 40, - .w = 100, - .h = 30 + .y = 10, + .w = 200, + .h = 64 + }; + struct checkbox cb = { + .label = "Play hard mode", + .x = 20, + .y = 20, + .w = 200, + .h = 16 }; for (;;) { @@ -101,25 +108,16 @@ case EVENT_QUIT: return; default: - button_handle(&button, &ev); - - if (button.state == BUTTON_STATE_ACTIVATED) { - puts("CLICKED!!!"); - button_reset(&button); - } - + checkbox_handle(&cb, &ev); break; } } - printf("%d\n", button.state); - painter_set_color(0xffffffff); painter_clear(); theme_draw_frame(NULL, &(const struct frame){ .x=10, .y=10, .w=500, .h=500 }); - label_draw(&(const struct label){ .text = "Hello for this quest.", .x=20, .y=20, .w=100, .h=100 }); - button_draw(&button); + checkbox_draw(&cb); painter_present();
--- a/src/core/button.c Thu Jul 09 22:38:48 2020 +0200 +++ b/src/core/button.c Sun Jul 12 09:44:27 2020 +0200 @@ -40,7 +40,6 @@ assert(button); assert(ev); - switch (ev->type) { case EVENT_CLICKDOWN: if (is_boxed(button, &ev->click))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/checkbox.c Sun Jul 12 09:44:27 2020 +0200 @@ -0,0 +1,55 @@ +/* + * checkbox.c -- GUI checkbox + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> + +#include "checkbox.h" +#include "theme.h" +#include "event.h" +#include "maths.h" + +static bool +is_boxed(const struct checkbox *cb, const struct event_click *click) +{ + assert(cb); + assert(click && click->type == EVENT_CLICKDOWN); + + return maths_is_boxed(cb->x, cb->y, cb->w, cb->h, click->x, click->y); +} + +void +checkbox_handle(struct checkbox *cb, const union event *ev) +{ + assert(cb); + assert(ev); + + switch (ev->type) { + case EVENT_CLICKDOWN: + if (is_boxed(cb, &ev->click)) + cb->checked = !cb->checked; + break; + default: + break; + } +} + +void +checkbox_draw(const struct checkbox *cb) +{ + theme_draw_checkbox(cb->theme, cb); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/checkbox.h Sun Jul 12 09:44:27 2020 +0200 @@ -0,0 +1,64 @@ +/* + * checkbox.h -- GUI checkbox + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_CHECKBOX_H +#define MOLKO_CHECKBOX_H + +/** + * \file checkbox.h + * \brief GUI checkbox. + */ + +#include <stdbool.h> + +union event; + +/** + * \brief GUI checkbox. + */ +struct checkbox { + int x; /*!< (RW) Position in x. */ + int y; /*!< (RW) Position in y. */ + unsigned int w; /*!< (RW) Width. */ + unsigned int h; /*!< (RW) Height. */ + const char *label; /*!< (RW, ref) Text to show. */ + bool checked; /*!< (RW) Is activated? */ + struct theme *theme; /*!< (RW, ref, optional) Theme to use. */ +}; + +/** + * Draw the checkbox. + * + * \pre cb != NULL + * \pre ev != NULL + * \param cb the checkbox + * \param ev the event + */ +void +checkbox_handle(struct checkbox *cb, const union event *ev); + +/** + * Draw the checkbox. + * + * \pre cb != NULL + * \param cb the checkbox + */ +void +checkbox_draw(const struct checkbox *cb); + +#endif /* !MOLKO_CHECKBOX_H */
--- a/src/core/theme.c Thu Jul 09 22:38:48 2020 +0200 +++ b/src/core/theme.c Sun Jul 12 09:44:27 2020 +0200 @@ -20,6 +20,7 @@ #include <stddef.h> #include "button.h" +#include "checkbox.h" #include "font.h" #include "frame.h" #include "label.h" @@ -34,6 +35,10 @@ #define THEME(t) (t ? t : &default_theme) +#define CHECKBOX_W 16 +#define CHECKBOX_H 16 +#define CHECKBOX_RAD 6 + static struct font default_font; static void @@ -48,6 +53,7 @@ painter_draw_line(x + w, y, x + w, y + h); } + static void draw_frame(struct theme *t, const struct frame *frame) { @@ -120,6 +126,31 @@ box(button->x, button->y, button->w, button->h); } +static void +draw_checkbox(struct theme *t, const struct checkbox *cb) +{ + box(cb->x, cb->y, CHECKBOX_W, CHECKBOX_H); + + if (cb->checked) + painter_draw_rectangle(cb->x + 5, cb->y + 5, CHECKBOX_W - 9, CHECKBOX_H - 9); + + if (cb->label) { + const unsigned int w = cb->w - (t->padding * 2) - CHECKBOX_W; + const int x = cb->x + (t->padding * 2) + CHECKBOX_W; + + struct label label = { + .text = cb->label, + .flags = LABEL_NO_HCENTER, + .x = x, + .y = cb->y, + .w = w, + .h = cb->h + }; + + draw_label(t, &label); + } +} + /* Default theme. */ static struct theme default_theme = { .colors = { @@ -127,9 +158,11 @@ [THEME_COLOR_SELECTED] = 0x006554ff, [THEME_COLOR_SHADOW] = 0x000000ff }, + .padding = 10, .draw_frame = draw_frame, .draw_label = draw_label, - .draw_button = draw_button + .draw_button = draw_button, + .draw_checkbox = draw_checkbox }; /* Default font catalog. */ @@ -174,6 +207,12 @@ return &default_theme; } +unsigned int +theme_padding(const struct theme *t) +{ + return THEME(t)->padding; +} + void theme_draw_frame(struct theme *t, const struct frame *frame) { @@ -199,6 +238,14 @@ } void +theme_draw_checkbox(struct theme *t, const struct checkbox *cb) +{ + assert(cb); + + THEME(t)->draw_checkbox(THEME(t), cb); +} + +void theme_finish(void) { for (size_t i = 0; i < NELEM(default_fonts); ++i) {
--- a/src/core/theme.h Thu Jul 09 22:38:48 2020 +0200 +++ b/src/core/theme.h Sun Jul 12 09:44:27 2020 +0200 @@ -26,6 +26,7 @@ #include <stdbool.h> +struct checkbox; struct button; struct font; struct frame; @@ -64,6 +65,11 @@ unsigned long colors[THEME_COLOR_LAST]; /** + * (RW) Padding between GUI elements. + */ + unsigned int padding; + + /** * Draw a frame. * * This function is used to draw a box usually as a container where UI @@ -86,6 +92,13 @@ * \see \ref theme_draw_button */ void (*draw_button)(struct theme *, const struct button *); + + /** + * Draw a checkbox. + * + * \see \ref theme_draw_button + */ + void (*draw_checkbox)(struct theme *t, const struct checkbox *); }; /** @@ -106,6 +119,15 @@ theme_default(void); /** + * Get the desired padding between GUI elements. + * + * \param t the theme to use (may be NULL) + * \return the padding in pixels + */ +unsigned int +theme_padding(const struct theme *t); + +/** * Draw a frame. * * \pre frame != NULL @@ -136,6 +158,15 @@ theme_draw_button(struct theme *t, const struct button *button); /** + * Draw a checkbox. + * + * \param t the theme to use (may be NULL) + * \param cb the checkbox + */ +void +theme_draw_checkbox(struct theme *t, const struct checkbox *cb); + +/** * Close associated resources. */ void