Compare commits
10 Commits
d55fb31e21
...
bebf6d6b5f
Author | SHA1 | Date |
---|---|---|
Xavier Del Campo Romero | bebf6d6b5f | |
Xavier Del Campo Romero | 7bc58ab0e6 | |
Xavier Del Campo Romero | 7325906351 | |
Xavier Del Campo Romero | 93d2c39b1b | |
Xavier Del Campo Romero | b0eb562b9b | |
Xavier Del Campo Romero | a71ce37929 | |
Xavier Del Campo Romero | e68c2fb4be | |
Xavier Del Campo Romero | 04b9219ee5 | |
Xavier Del Campo Romero | 033ed5fb94 | |
Xavier Del Campo Romero | ec9f41f1ab |
|
@ -9,6 +9,17 @@ static int renderstr(const enum font f, const short x, short y,
|
|||
const char *str, const bool render, short *const max_x,
|
||||
short *const max_y)
|
||||
{
|
||||
if (!str)
|
||||
{
|
||||
if (max_x)
|
||||
*max_x = 0;
|
||||
|
||||
if (max_y)
|
||||
*max_y = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct cfg
|
||||
{
|
||||
const struct sprite *s;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -12,10 +12,15 @@ extern "C"
|
|||
|
||||
struct gui_common
|
||||
{
|
||||
int (*update)(struct gui_common *, const union peripheral *,
|
||||
const struct camera *);
|
||||
int (*render)(const struct gui_common *);
|
||||
void (*get_dim)(const struct gui_common *, short *w, short *h);
|
||||
const struct gui_common_cb
|
||||
{
|
||||
void (*add_child)(struct gui_common *parent, struct gui_common *child);
|
||||
int (*update)(struct gui_common *, const union peripheral *,
|
||||
const struct camera *);
|
||||
int (*render)(const struct gui_common *);
|
||||
void (*get_dim)(const struct gui_common *, short *w, short *h);
|
||||
} *cb;
|
||||
|
||||
short x, y;
|
||||
bool hcentered, vcentered;
|
||||
struct gui_common *parent, *child, *sibling;
|
||||
|
|
|
@ -14,11 +14,9 @@ extern "C"
|
|||
struct gui_bar
|
||||
{
|
||||
struct gui_common common;
|
||||
short w;
|
||||
};
|
||||
|
||||
UTIL_STATIC_ASSERT(!offsetof(struct gui_bar, common),
|
||||
"unexpected offset for struct gui_bar");
|
||||
|
||||
void gui_bar_init(struct gui_bar *b);
|
||||
|
||||
enum
|
||||
|
@ -30,6 +28,9 @@ enum
|
|||
MAX_GUI_BAR_SPRITES
|
||||
};
|
||||
|
||||
UTIL_STATIC_ASSERT(!offsetof(struct gui_bar, common),
|
||||
"unexpected offset for struct gui_bar");
|
||||
|
||||
extern struct sprite gui_bar_sprites[MAX_GUI_BAR_SPRITES];
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -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, spacing;
|
||||
|
||||
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 */
|
|
@ -1,48 +1,57 @@
|
|||
#include <gui/bar.h>
|
||||
#include <gui_private.h>
|
||||
#include <gui.h>
|
||||
#include <gfx.h>
|
||||
|
||||
struct sprite gui_bar_sprites[MAX_GUI_BAR_SPRITES];
|
||||
|
||||
static int render_topleft(void)
|
||||
static int render_topleft(const struct gui_bar *const b, const short x,
|
||||
const short y)
|
||||
{
|
||||
sprite_get_or_ret(s, -1);
|
||||
|
||||
if (sprite_clone(&gui_bar_sprites[GUI_BAR_LEFT], s))
|
||||
return -1;
|
||||
|
||||
s->x = x;
|
||||
s->y = y;
|
||||
sprite_sort(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int render_topright(void)
|
||||
static int render_topright(const struct gui_bar *const b, const short x,
|
||||
const short y)
|
||||
{
|
||||
sprite_get_or_ret(s, -1);
|
||||
|
||||
if (sprite_clone(&gui_bar_sprites[GUI_BAR_RIGHT], s))
|
||||
return -1;
|
||||
|
||||
s->x = screen_w - s->w;
|
||||
s->x = x + b->w - s->w;
|
||||
s->y = y;
|
||||
sprite_sort(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int render_topmid(void)
|
||||
static int render_topmid(const struct gui_bar *const b, const short x,
|
||||
const short y)
|
||||
{
|
||||
const uint16_t mid_w = gui_bar_sprites[GUI_BAR_MID].w;
|
||||
const uint16_t lw = gui_bar_sprites[GUI_BAR_LEFT].w;
|
||||
const size_t w = screen_w - lw - lw;
|
||||
const size_t rem_mid = w % mid_w;
|
||||
const size_t whole_mid = w / mid_w;
|
||||
const size_t n_mid = rem_mid ? whole_mid + 1 : whole_mid;
|
||||
const short mid_w = gui_bar_sprites[GUI_BAR_MID].w,
|
||||
lw = gui_bar_sprites[GUI_BAR_LEFT].w,
|
||||
w = b->w - lw - lw;
|
||||
|
||||
if (w <= 0)
|
||||
return -1;
|
||||
|
||||
const short rem_mid = w % mid_w,
|
||||
whole_mid = w / mid_w,
|
||||
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)
|
||||
} a = {.x = x + lw}; a.i < n_mid; a.i++, a.x += mid_w)
|
||||
{
|
||||
sprite_get_or_ret(m, -1);
|
||||
|
||||
|
@ -50,6 +59,7 @@ static int render_topmid(void)
|
|||
return -1;
|
||||
|
||||
m->x = a.x;
|
||||
m->y = y;
|
||||
|
||||
if (rem_mid && a.i + 1 == n_mid)
|
||||
m->w = rem_mid;
|
||||
|
@ -64,21 +74,41 @@ static int render_topmid(void)
|
|||
|
||||
static int render(const struct gui_common *const g)
|
||||
{
|
||||
if (render_topleft()
|
||||
|| render_topright()
|
||||
|| render_topmid())
|
||||
const struct gui_bar *const b = (const struct gui_bar *)g;
|
||||
short x, y;
|
||||
|
||||
gui_coords(&b->common, &x, &y);
|
||||
|
||||
if (render_topleft(b, x, y)
|
||||
|| render_topright(b, x, y)
|
||||
|| render_topmid(b, x, y))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_dim(const struct gui_common *const g, short *const w,
|
||||
short *const h)
|
||||
{
|
||||
const struct gui_bar *const b = (const struct gui_bar *)g;
|
||||
|
||||
*w = b->w;
|
||||
*h = gui_bar_sprites[GUI_BAR_MID].h;
|
||||
}
|
||||
|
||||
void gui_bar_init(struct gui_bar *const b)
|
||||
{
|
||||
static const struct gui_common_cb cb =
|
||||
{
|
||||
.render = render,
|
||||
.get_dim = get_dim
|
||||
};
|
||||
|
||||
*b = (const struct gui_bar)
|
||||
{
|
||||
.common =
|
||||
{
|
||||
.render = render
|
||||
.cb = &cb
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -164,16 +164,23 @@ static void get_dim(const struct gui_common *const g,
|
|||
|
||||
void gui_button_init(struct gui_button *const b)
|
||||
{
|
||||
static const struct gui_common_cb cb =
|
||||
{
|
||||
.get_dim = get_dim,
|
||||
.update = update,
|
||||
.render = render
|
||||
};
|
||||
|
||||
*b = (const struct gui_button)
|
||||
{
|
||||
.common =
|
||||
{
|
||||
.get_dim = get_dim,
|
||||
.update = update,
|
||||
.render = render
|
||||
.cb = &cb
|
||||
}
|
||||
};
|
||||
|
||||
gui_label_init(&b->label);
|
||||
b->label.common.hcentered = true;
|
||||
b->label.common.vcentered = true;
|
||||
gui_add_child(&b->common, &b->label.common);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
#include <gui/container.h>
|
||||
#include <gui.h>
|
||||
|
||||
static void add_child(struct gui_common *const parent,
|
||||
struct gui_common *const child)
|
||||
{
|
||||
if (!child->cb || !child->cb->get_dim)
|
||||
return;
|
||||
|
||||
struct gui_container *const c = (struct gui_container *)parent;
|
||||
short w, h;
|
||||
|
||||
child->cb->get_dim(child, &w, &h);
|
||||
|
||||
switch (c->mode)
|
||||
{
|
||||
case GUI_CONTAINER_MODE_H:
|
||||
if (c->w)
|
||||
c->w += c->spacing;
|
||||
|
||||
child->x += c->w;
|
||||
c->w += w;
|
||||
|
||||
if (h > c->h)
|
||||
c->h = h;
|
||||
|
||||
break;
|
||||
|
||||
case GUI_CONTAINER_MODE_V:
|
||||
if (c->h)
|
||||
c->h += c->spacing;
|
||||
|
||||
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)
|
||||
{
|
||||
static const struct gui_common_cb cb =
|
||||
{
|
||||
.add_child = add_child,
|
||||
.get_dim = get_dim
|
||||
};
|
||||
|
||||
*c = (const struct gui_container)
|
||||
{
|
||||
.common =
|
||||
{
|
||||
.cb = &cb
|
||||
}
|
||||
};
|
||||
}
|
|
@ -3,14 +3,14 @@
|
|||
static void get_centered(const struct gui_common *const g,
|
||||
short *const x, short *const y)
|
||||
{
|
||||
if (g->get_dim)
|
||||
if (g->cb && g->cb->get_dim)
|
||||
{
|
||||
short w, h, pw = 0, ph = 0;
|
||||
|
||||
if (g->parent)
|
||||
{
|
||||
if (g->parent->get_dim)
|
||||
g->parent->get_dim(g->parent, &pw, &ph);
|
||||
if (g->parent->cb && g->parent->cb->get_dim)
|
||||
g->parent->cb->get_dim(g->parent, &pw, &ph);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ static void get_centered(const struct gui_common *const g,
|
|||
ph = screen_h;
|
||||
}
|
||||
|
||||
g->get_dim(g, &w, &h);
|
||||
g->cb->get_dim(g, &w, &h);
|
||||
|
||||
if (g->hcentered)
|
||||
*x += (pw - w) / 2;
|
||||
|
@ -34,7 +34,9 @@ void gui_coords(const struct gui_common *const g, short *const x,
|
|||
*x = g->x;
|
||||
*y = g->y;
|
||||
|
||||
for (const struct gui_common *p = g->parent; p; p = p->parent)
|
||||
const struct gui_common *p = g->parent;
|
||||
|
||||
if (p)
|
||||
{
|
||||
short px = p->x, py = p->y;
|
||||
|
||||
|
@ -69,12 +71,15 @@ void gui_add_child(struct gui_common *const p,
|
|||
p->child = c;
|
||||
|
||||
c->parent = p;
|
||||
|
||||
if (p->cb && p->cb->add_child)
|
||||
p->cb->add_child(p, c);
|
||||
}
|
||||
|
||||
int gui_update(struct gui_common *const g, const union peripheral *const p,
|
||||
const struct camera *const c)
|
||||
{
|
||||
if (g->update && g->update(g, p, c))
|
||||
if (g->cb && g->cb->update && g->cb->update(g, p, c))
|
||||
return -1;
|
||||
|
||||
if (g->child && gui_update(g->child, p, c))
|
||||
|
@ -89,7 +94,7 @@ int gui_update(struct gui_common *const g, const union peripheral *const p,
|
|||
|
||||
int gui_render(const struct gui_common *const g)
|
||||
{
|
||||
if (g->render && g->render(g))
|
||||
if (g->cb && g->cb->render && g->cb->render(g))
|
||||
return -1;
|
||||
|
||||
if (g->child && gui_render(g->child))
|
||||
|
|
|
@ -23,12 +23,17 @@ static void get_dim(const struct gui_common *const g,
|
|||
|
||||
void gui_label_init(struct gui_label *const l)
|
||||
{
|
||||
static const struct gui_common_cb cb =
|
||||
{
|
||||
.get_dim = get_dim,
|
||||
.render = render
|
||||
};
|
||||
|
||||
*l = (const struct gui_label)
|
||||
{
|
||||
.common =
|
||||
{
|
||||
.get_dim = get_dim,
|
||||
.render = render
|
||||
.cb = &cb
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -83,11 +83,16 @@ static int render(const struct gui_common *const g)
|
|||
|
||||
void gui_progress_bar_init(struct gui_progress_bar *const pb)
|
||||
{
|
||||
static const struct gui_common_cb cb =
|
||||
{
|
||||
.render = render
|
||||
};
|
||||
|
||||
*pb = (const struct gui_progress_bar)
|
||||
{
|
||||
.common =
|
||||
{
|
||||
.render = render
|
||||
.cb = &cb
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -224,12 +224,17 @@ static void get_dim(const struct gui_common *const g, short *const w,
|
|||
|
||||
void gui_rounded_rect_init(struct gui_rounded_rect *const r)
|
||||
{
|
||||
static const struct gui_common_cb cb =
|
||||
{
|
||||
.get_dim = get_dim,
|
||||
.render = render
|
||||
};
|
||||
|
||||
*r = (const struct gui_rounded_rect)
|
||||
{
|
||||
.common =
|
||||
{
|
||||
.get_dim = get_dim,
|
||||
.render = render
|
||||
.cb = &cb
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <gfx.h>
|
||||
#include <gui.h>
|
||||
#include <gui/button.h>
|
||||
#include <gui/container.h>
|
||||
#include <system.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -15,22 +16,35 @@ static void on_pressed(void *const arg)
|
|||
int menu(void)
|
||||
{
|
||||
struct camera cam = {0};
|
||||
struct gui_button play;
|
||||
struct gui_button play, exit_btn;
|
||||
struct gui_container cnt;
|
||||
union peripheral p;
|
||||
bool start = false;
|
||||
bool start = false, exit = false;
|
||||
|
||||
if (game_resinit())
|
||||
return -1;
|
||||
|
||||
cursor_init(&cam.cursor);
|
||||
gui_container_init(&cnt);
|
||||
cnt.mode = GUI_CONTAINER_MODE_V;
|
||||
cnt.common.hcentered = true;
|
||||
cnt.common.vcentered = true;
|
||||
gui_button_init(&play);
|
||||
gui_button_init(&exit_btn);
|
||||
play.on_pressed = on_pressed;
|
||||
play.arg = &start;
|
||||
play.w = 140;
|
||||
play.common.hcentered = true;
|
||||
play.common.vcentered = true;
|
||||
play.label.text = "Play";
|
||||
|
||||
exit_btn.arg = &exit;
|
||||
exit_btn.w = 140;
|
||||
exit_btn.common.hcentered = true;
|
||||
exit_btn.label.text = "Exit";
|
||||
exit_btn.on_pressed = on_pressed;
|
||||
gui_add_child(&cnt.common, &play.common);
|
||||
gui_add_child(&cnt.common, &exit_btn.common);
|
||||
|
||||
{
|
||||
const struct peripheral_cfg cfg =
|
||||
{
|
||||
|
@ -46,9 +60,6 @@ int menu(void)
|
|||
peripheral_update(&p);
|
||||
camera_update(&cam, &p);
|
||||
|
||||
play.label.common.x = play.w / 2 - 20;
|
||||
play.label.common.y = 4;
|
||||
|
||||
if (gui_update(&play.common, &p, &cam))
|
||||
return -1;
|
||||
|
||||
|
@ -58,10 +69,10 @@ int menu(void)
|
|||
r->h = screen_h;
|
||||
rect_sort(r);
|
||||
|
||||
if (p.common.exit)
|
||||
if (p.common.exit || exit)
|
||||
return 0;
|
||||
|
||||
if (gui_render(&play.common)
|
||||
if (gui_render(&cnt.common)
|
||||
|| cursor_render(&cam.cursor)
|
||||
|| gfx_draw())
|
||||
return -1;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <unit.h>
|
||||
#include <gui.h>
|
||||
#include <gui/bar.h>
|
||||
#include <gui/container.h>
|
||||
#include <gui/label.h>
|
||||
#include <gui/progress_bar.h>
|
||||
#include <gui/rounded_rect.h>
|
||||
|
@ -265,9 +266,18 @@ static int render_sel(const struct human_player *const h)
|
|||
static int render_top(const struct human_player *const h)
|
||||
{
|
||||
const struct player *const pl = &h->pl;
|
||||
struct gui_container c;
|
||||
struct gui_bar b;
|
||||
|
||||
gui_bar_init(&b);
|
||||
b.w = screen_w;
|
||||
gui_container_init(&c);
|
||||
c.mode = GUI_CONTAINER_MODE_H;
|
||||
c.spacing = 16;
|
||||
c.common.hcentered = true;
|
||||
c.common.vcentered = true;
|
||||
gui_add_child(&b.common, &c.common);
|
||||
|
||||
char wood_str[sizeof "Wood=429496729"];
|
||||
|
||||
{
|
||||
|
@ -281,10 +291,9 @@ static int render_top(const struct human_player *const h)
|
|||
struct gui_label wl;
|
||||
|
||||
gui_label_init(&wl);
|
||||
wl.common.x = 16;
|
||||
wl.common.y = 6;
|
||||
wl.common.vcentered = true;
|
||||
wl.text = wood_str;
|
||||
gui_add_child(&b.common, &wl.common);
|
||||
gui_add_child(&c.common, &wl.common);
|
||||
|
||||
char gold_str[sizeof "Gold=429496729"];
|
||||
|
||||
|
@ -299,10 +308,9 @@ static int render_top(const struct human_player *const h)
|
|||
struct gui_label gl;
|
||||
|
||||
gui_label_init(&gl);
|
||||
gl.common.x = 108;
|
||||
gl.common.y = 6;
|
||||
wl.common.vcentered = true;
|
||||
gl.text = gold_str;
|
||||
gui_add_child(&b.common, &gl.common);
|
||||
gui_add_child(&c.common, &gl.common);
|
||||
|
||||
char pop_str[sizeof "Pop.=255/255"];
|
||||
|
||||
|
@ -317,10 +325,9 @@ static int render_top(const struct human_player *const h)
|
|||
struct gui_label popl;
|
||||
|
||||
gui_label_init(&popl);
|
||||
popl.common.x = 212;
|
||||
popl.common.y = 6;
|
||||
wl.common.vcentered = true;
|
||||
popl.text = pop_str;
|
||||
gui_add_child(&b.common, &popl.common);
|
||||
gui_add_child(&c.common, &popl.common);
|
||||
|
||||
if (gui_render(&b.common))
|
||||
return -1;
|
||||
|
|
Loading…
Reference in New Issue