gui/bar: support arbitrary x/y and width

This commit is contained in:
Xavier Del Campo Romero 2022-07-02 04:41:22 +02:00
parent b0eb562b9b
commit 93d2c39b1b
2 changed files with 46 additions and 20 deletions

View File

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

View File

@ -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,19 +74,34 @@ 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
.render = render,
.get_dim = get_dim
};
*b = (const struct gui_bar)