126 lines
2.6 KiB
C
126 lines
2.6 KiB
C
#include <gui.h>
|
|
#include <gui/button.h>
|
|
#include <gui_private.h>
|
|
#include <gui_button_private.h>
|
|
#include <stdio.h>
|
|
|
|
struct sprite gui_button_sprites[MAX_GUI_BUTTON_SPRITES];
|
|
|
|
/* Alias for readability. */
|
|
static const struct sprite *const refs = gui_button_sprites;
|
|
|
|
static int render_left(const struct gui_button *const b,
|
|
short *const x, const short y)
|
|
{
|
|
sprite_get_or_ret(s, -1);
|
|
|
|
if (sprite_clone(&refs[GUI_BUTTON_LEFT], s))
|
|
return -1;
|
|
|
|
s->x = *x;
|
|
s->y = y;
|
|
|
|
if (sprite_sort(s))
|
|
{
|
|
fprintf(stderr, "%s: sprite_sort failed\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
*x = s->x + s->w;
|
|
return 0;
|
|
}
|
|
|
|
static int render_mid(const struct gui_button *const b,
|
|
short *const x, const short y)
|
|
{
|
|
const short mid_w = refs[GUI_BUTTON_MID].w,
|
|
lw = refs[GUI_BUTTON_LEFT].w,
|
|
rw = refs[GUI_BUTTON_RIGHT].w,
|
|
w = b->u.type1.w - lw - rw;
|
|
|
|
if (w > 0)
|
|
{
|
|
const short rem_mid = w > 0 ? w % mid_w : 0,
|
|
whole_mid = w / mid_w,
|
|
n_mid = rem_mid ? whole_mid + 1 : whole_mid;
|
|
|
|
for (struct
|
|
{
|
|
size_t i;
|
|
short x;
|
|
} a = {.x = lw};
|
|
a.i < n_mid;
|
|
a.i++, a.x += mid_w)
|
|
{
|
|
sprite_get_or_ret(m, -1);
|
|
|
|
if (sprite_clone(&refs[GUI_BUTTON_MID], m))
|
|
return -1;
|
|
|
|
m->x = *x;
|
|
m->y = y;
|
|
|
|
if (rem_mid && a.i + 1 == n_mid)
|
|
m->w = rem_mid;
|
|
else
|
|
m->w = mid_w;
|
|
|
|
sprite_sort(m);
|
|
*x += m->w;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "%s: unexpected zero or negative size for button %p\n",
|
|
__func__, (void *)b);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int render_right(const struct gui_button *const b,
|
|
const short x, const short y)
|
|
{
|
|
sprite_get_or_ret(s, -1);
|
|
|
|
if (sprite_clone(&refs[GUI_BUTTON_RIGHT], s))
|
|
return -1;
|
|
|
|
s->x = x;
|
|
s->y = y;
|
|
sprite_sort(s);
|
|
return 0;
|
|
}
|
|
|
|
int gui_button_render_type1(const struct gui_button *const b)
|
|
{
|
|
short x, y;
|
|
|
|
gui_coords(&b->common, &x, &y);
|
|
|
|
if (render_left(b, &x, y)
|
|
|| render_mid(b, &x, y)
|
|
|| render_right(b, x, y))
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void gui_button_get_dim_type1(const struct gui_button *const b,
|
|
short *const w, short *const h)
|
|
{
|
|
*w = b->u.type1.w;
|
|
*h = refs[GUI_BUTTON_MID].h;
|
|
}
|
|
|
|
void gui_button_init_type1(struct gui_button *const b)
|
|
{
|
|
struct gui_label *const l = &b->u.type1.label;
|
|
|
|
gui_label_init(l);
|
|
l->common.hcentered = true;
|
|
l->common.vcentered = true;
|
|
gui_add_child(&b->common, &l->common);
|
|
}
|