aboutsummaryrefslogtreecommitdiff
path: root/src/button
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-06-11 23:22:04 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-06-11 23:42:27 +0200
commit6f74cbd20b1fe0ef9f2a55057e9ac066bec0b575 (patch)
treebd6e709305fa93c216915ad73662517b74754489 /src/button
parent46fec13fcbee1385db0927f1162f60e1f328d63c (diff)
downloadjancity-6f74cbd20b1fe0ef9f2a55057e9ac066bec0b575.tar.gz
Implement button component
Diffstat (limited to 'src/button')
-rw-r--r--src/button/CMakeLists.txt3
-rw-r--r--src/button/inc/button.h36
-rw-r--r--src/button/src/button.c100
3 files changed, 139 insertions, 0 deletions
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 <gfx.h>
+#include <stdbool.h>
+
+#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 <button.h>
+#include <font.h>
+#include <gfx.h>
+
+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;
+}