aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gui/CMakeLists.txt1
-rw-r--r--src/gui/inc/gui/container.h34
-rw-r--r--src/gui/src/container.c56
3 files changed, 91 insertions, 0 deletions
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 4c5039b..1d7e686 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -1,6 +1,7 @@
add_library(gui
"src/bar.c"
"src/button.c"
+ "src/container.c"
"src/gui.c"
"src/label.c"
"src/progress_bar.c"
diff --git a/src/gui/inc/gui/container.h b/src/gui/inc/gui/container.h
new file mode 100644
index 0000000..d290424
--- /dev/null
+++ b/src/gui/inc/gui/container.h
@@ -0,0 +1,34 @@
+#ifndef GUI_CONTAINER_H
+#define GUI_CONTAINER_H
+
+#include <gui.h>
+#include <util.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+struct gui_container
+{
+ struct gui_common common;
+ short w, h;
+
+ enum
+ {
+ GUI_CONTAINER_MODE_H,
+ GUI_CONTAINER_MODE_V
+ } mode;
+};
+
+UTIL_STATIC_ASSERT(!offsetof(struct gui_container, common),
+ "unexpected offset for struct gui_container");
+
+void gui_container_init(struct gui_container *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GUI_CONTAINER_H */
diff --git a/src/gui/src/container.c b/src/gui/src/container.c
new file mode 100644
index 0000000..6d586f1
--- /dev/null
+++ b/src/gui/src/container.c
@@ -0,0 +1,56 @@
+#include <gui/container.h>
+#include <gui.h>
+
+static void add_child(struct gui_common *const parent,
+ struct gui_common *const child)
+{
+ if (!child->get_dim)
+ return;
+
+ struct gui_container *const c = (struct gui_container *)parent;
+ short w, h;
+
+ child->get_dim(child, &w, &h);
+
+ switch (c->mode)
+ {
+ case GUI_CONTAINER_MODE_H:
+ child->x += c->w;
+ c->w += w;
+
+ if (h > c->h)
+ c->h = h;
+
+ break;
+
+ case GUI_CONTAINER_MODE_V:
+ child->y += c->h;
+ c->h += h;
+
+ if (w > c->w)
+ c->w = w;
+
+ break;
+ }
+}
+
+static void get_dim(const struct gui_common *const g,
+ short *const w, short *const h)
+{
+ struct gui_container *const c = (struct gui_container *)g;
+
+ *w = c->w;
+ *h = c->h;
+}
+
+void gui_container_init(struct gui_container *const c)
+{
+ *c = (const struct gui_container)
+ {
+ .common =
+ {
+ .add_child = add_child,
+ .get_dim = get_dim
+ }
+ };
+}