gui: implement container

Containers, somewhat inspired by GtkBox, allow to packed other GUI
elements into a single row or column.
This commit is contained in:
Xavier Del Campo Romero 2022-07-02 00:52:59 +02:00
parent 04b9219ee5
commit e68c2fb4be
3 changed files with 91 additions and 0 deletions

View File

@ -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"

View File

@ -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 */

56
src/gui/src/container.c Normal file
View File

@ -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
}
};
}