From a84a55aa2558b537aeb4adde1875683e88e11624 Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Sat, 11 Jun 2022 23:22:04 +0200 Subject: Implement button component --- src/button/CMakeLists.txt | 3 ++ src/button/inc/button.h | 36 +++++++++++++++++ src/button/src/button.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 src/button/CMakeLists.txt create mode 100644 src/button/inc/button.h create mode 100644 src/button/src/button.c (limited to 'src/button') diff --git a/src/button/CMakeLists.txt b/src/button/CMakeLists.txt new file mode 100644 index 0000000..1e6e693 --- /dev/null +++ b/src/button/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(button "src/button.c") +target_include_directories(button PUBLIC "inc") +target_link_libraries(button PUBLIC gfx PRIVATE font) diff --git a/src/button/inc/button.h b/src/button/inc/button.h new file mode 100644 index 0000000..062cb07 --- /dev/null +++ b/src/button/inc/button.h @@ -0,0 +1,36 @@ +#ifndef BUTTON_H +#define BUTTON_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum +{ + BUTTON_LEFT, + BUTTON_MID, + BUTTON_RIGHT, + + MAX_BUTTON_SPRITES +}; + +struct button +{ + const char *text; + short x, y, w; +}; + +bool button_is_pressed(const struct button *b); +int button_render(const struct button *b); + +extern struct sprite button_sprites[MAX_BUTTON_SPRITES]; + +#ifdef __cplusplus +} +#endif + +#endif /* BUTTON_H */ diff --git a/src/button/src/button.c b/src/button/src/button.c new file mode 100644 index 0000000..9508d5c --- /dev/null +++ b/src/button/src/button.c @@ -0,0 +1,100 @@ +#include +#include +#include + +struct sprite button_sprites[MAX_BUTTON_SPRITES]; + +bool button_is_pressed(const struct button *const b) +{ + return false; +} + +static int render_left(const struct button *const b, short *const x) +{ + sprite_get_or_ret(s, -1); + + if (sprite_clone(&button_sprites[BUTTON_LEFT], s)) + return -1; + + s->x = b->x; + s->y = b->y; + sprite_sort(s); + *x = s->x + s->w; + return 0; +} + +static int render_mid(const struct button *const b, short *const x) +{ + const short mid_w = button_sprites[BUTTON_MID].w; + const short lw = button_sprites[BUTTON_LEFT].w; + const short rw = button_sprites[BUTTON_RIGHT].w; + const short w = b->w - lw - rw; + + if (w > 0) + { + const short rem_mid = w > 0 ? w % mid_w : 0; + const short whole_mid = w / mid_w; + const short n_mid = rem_mid ? whole_mid + 1 : whole_mid; + + for (struct + { + size_t i; + short x; + } a = {.i = 0, .x = lw}; + a.i < n_mid; + a.i++, a.x += mid_w) + { + sprite_get_or_ret(m, -1); + + if (sprite_clone(&button_sprites[BUTTON_MID], m)) + return -1; + + m->x = *x; + m->y = b->y; + + if (rem_mid && a.i + 1 == n_mid) + m->w = rem_mid; + else + m->w = mid_w; + + sprite_sort(m); + *x += m->w; + } + } + + return 0; +} + +static int render_right(const struct button *const b, const short *const x) +{ + sprite_get_or_ret(s, -1); + + if (sprite_clone(&button_sprites[BUTTON_RIGHT], s)) + return -1; + + s->x = *x; + s->y = b->y; + sprite_sort(s); + return 0; +} + +static int render_text(const struct button *const b) +{ + const short x = b->x + button_sprites[BUTTON_LEFT].w, + y = b->y + (button_sprites[BUTTON_MID].h >> 2); + + return font_printf(FONT, x, y, "%s", b->text) < 0; +} + +int button_render(const struct button *const b) +{ + short x; + + if (render_left(b, &x) + || render_mid(b, &x) + || render_right(b, &x) + || render_text(b)) + return -1; + + return 0; +} -- cgit v1.2.3