Implement GUI line edit
This commit is contained in:
parent
e3356fde2d
commit
8f9737b776
|
@ -184,6 +184,30 @@ sprite(NAME btn_mid
|
||||||
CY 493
|
CY 493
|
||||||
TRANSPARENT FALSE)
|
TRANSPARENT FALSE)
|
||||||
|
|
||||||
|
sprite(NAME line_edit_left
|
||||||
|
X 368
|
||||||
|
Y 148
|
||||||
|
BPP 4
|
||||||
|
CX 368
|
||||||
|
CY 492
|
||||||
|
TRANSPARENT FALSE)
|
||||||
|
|
||||||
|
sprite(NAME line_edit_mid
|
||||||
|
X 370
|
||||||
|
Y 148
|
||||||
|
BPP 4
|
||||||
|
CX 368
|
||||||
|
CY 491
|
||||||
|
TRANSPARENT FALSE)
|
||||||
|
|
||||||
|
sprite(NAME line_edit_right
|
||||||
|
X 378
|
||||||
|
Y 148
|
||||||
|
BPP 4
|
||||||
|
CX 368
|
||||||
|
CY 491
|
||||||
|
TRANSPARENT FALSE)
|
||||||
|
|
||||||
sound(NAME acknowledge_01)
|
sound(NAME acknowledge_01)
|
||||||
sound(NAME acknowledge_02)
|
sound(NAME acknowledge_02)
|
||||||
sound(NAME selected_01)
|
sound(NAME selected_01)
|
||||||
|
@ -213,6 +237,9 @@ container(NAME rts
|
||||||
sel_down_right
|
sel_down_right
|
||||||
sel_mid
|
sel_mid
|
||||||
sel_mid_v
|
sel_mid_v
|
||||||
|
line_edit_left
|
||||||
|
line_edit_mid
|
||||||
|
line_edit_right
|
||||||
SOUNDS
|
SOUNDS
|
||||||
acknowledge_01
|
acknowledge_01
|
||||||
acknowledge_02
|
acknowledge_02
|
||||||
|
|
|
@ -51,6 +51,12 @@ btn_mid.bmp:
|
||||||
btn_mid_24.bmp:
|
btn_mid_24.bmp:
|
||||||
btn_right.bmp:
|
btn_right.bmp:
|
||||||
btn_right_24.bmp:
|
btn_right_24.bmp:
|
||||||
|
line_edit_left.bmp:
|
||||||
|
line_edit_left_24.bmp:
|
||||||
|
line_edit_mid.bmp:
|
||||||
|
line_edit_mid_24.bmp:
|
||||||
|
line_edit_right.bmp:
|
||||||
|
line_edit_right_24.bmp:
|
||||||
Derived works from ui_sheet.png
|
Derived works from ui_sheet.png
|
||||||
|
|
||||||
font.bmp:
|
font.bmp:
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 250 B |
Binary file not shown.
After Width: | Height: | Size: 654 B |
Binary file not shown.
After Width: | Height: | Size: 546 B |
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 250 B |
Binary file not shown.
After Width: | Height: | Size: 654 B |
|
@ -5,6 +5,7 @@
|
||||||
#include <gfx.h>
|
#include <gfx.h>
|
||||||
#include <gui/bar.h>
|
#include <gui/bar.h>
|
||||||
#include <gui/button.h>
|
#include <gui/button.h>
|
||||||
|
#include <gui/line_edit.h>
|
||||||
#include <gui/rounded_rect.h>
|
#include <gui/rounded_rect.h>
|
||||||
#include <resource.h>
|
#include <resource.h>
|
||||||
#include <terrain.h>
|
#include <terrain.h>
|
||||||
|
@ -246,6 +247,33 @@ static const struct container c[] =
|
||||||
.sprite = &gui_button_sprites[GUI_BUTTON_RIGHT]
|
.sprite = &gui_button_sprites[GUI_BUTTON_RIGHT]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
.path = "line_edit_left",
|
||||||
|
.type = CONTAINER_TYPE_SPRITE,
|
||||||
|
.data =
|
||||||
|
{
|
||||||
|
.sprite = &gui_line_edit_sprites[GUI_LINE_EDIT_LEFT]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
.path = "line_edit_mid",
|
||||||
|
.type = CONTAINER_TYPE_SPRITE,
|
||||||
|
.data =
|
||||||
|
{
|
||||||
|
.sprite = &gui_line_edit_sprites[GUI_LINE_EDIT_MID]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
.path = "line_edit_right",
|
||||||
|
.type = CONTAINER_TYPE_SPRITE,
|
||||||
|
.data =
|
||||||
|
{
|
||||||
|
.sprite = &gui_line_edit_sprites[GUI_LINE_EDIT_RIGHT]
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool init;
|
static bool init;
|
||||||
|
|
|
@ -5,6 +5,7 @@ add_library(gui
|
||||||
"src/container.c"
|
"src/container.c"
|
||||||
"src/gui.c"
|
"src/gui.c"
|
||||||
"src/label.c"
|
"src/label.c"
|
||||||
|
"src/line_edit.c"
|
||||||
"src/progress_bar.c"
|
"src/progress_bar.c"
|
||||||
"src/rounded_rect.c"
|
"src/rounded_rect.c"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef GUI_LINE_EDIT_H
|
||||||
|
#define GUI_LINE_EDIT_H
|
||||||
|
|
||||||
|
#include <gui.h>
|
||||||
|
#include <gui/label.h>
|
||||||
|
#include <gfx.h>
|
||||||
|
#include <util.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct gui_line_edit
|
||||||
|
{
|
||||||
|
struct gui_common common;
|
||||||
|
struct gui_label label;
|
||||||
|
short w;
|
||||||
|
bool focus, blink;
|
||||||
|
unsigned blt;
|
||||||
|
char *text;
|
||||||
|
size_t i, sz;
|
||||||
|
};
|
||||||
|
|
||||||
|
void gui_line_edit_init(struct gui_line_edit *l, char *buf, size_t sz);
|
||||||
|
|
||||||
|
UTIL_STATIC_ASSERT(!offsetof(struct gui_line_edit, common),
|
||||||
|
"unexpected offset for struct gui_line_edit");
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GUI_LINE_EDIT_LEFT,
|
||||||
|
GUI_LINE_EDIT_MID,
|
||||||
|
GUI_LINE_EDIT_RIGHT,
|
||||||
|
|
||||||
|
MAX_GUI_LINE_EDIT_SPRITES
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct sprite gui_line_edit_sprites[MAX_GUI_LINE_EDIT_SPRITES];
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GUI_LINE_EDIT_H */
|
|
@ -0,0 +1,195 @@
|
||||||
|
#include <gui.h>
|
||||||
|
#include <gui_private.h>
|
||||||
|
#include <gui/label.h>
|
||||||
|
#include <gui/line_edit.h>
|
||||||
|
#include <camera.h>
|
||||||
|
#include <gfx.h>
|
||||||
|
#include <input.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <pad.h>
|
||||||
|
#include <peripheral.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct sprite gui_line_edit_sprites[MAX_GUI_LINE_EDIT_SPRITES];
|
||||||
|
|
||||||
|
/* Alias for readability. */
|
||||||
|
static const struct sprite *const refs = gui_line_edit_sprites;
|
||||||
|
|
||||||
|
static int render_left(const struct gui_line_edit *const l,
|
||||||
|
short *const x, const short y)
|
||||||
|
{
|
||||||
|
sprite_get_or_ret(s, -1);
|
||||||
|
|
||||||
|
if (sprite_clone(&refs[GUI_LINE_EDIT_LEFT], s))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
s->x = *x;
|
||||||
|
s->y = y;
|
||||||
|
sprite_sort(s);
|
||||||
|
*x = s->x + s->w;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int render_mid(const struct gui_line_edit *const l,
|
||||||
|
short *const x, const short y)
|
||||||
|
{
|
||||||
|
const short mid_w = refs[GUI_LINE_EDIT_MID].w,
|
||||||
|
lw = refs[GUI_LINE_EDIT_LEFT].w,
|
||||||
|
rw = refs[GUI_LINE_EDIT_RIGHT].w,
|
||||||
|
w = l->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_LINE_EDIT_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
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int render_right(const short x, const short y)
|
||||||
|
{
|
||||||
|
sprite_get_or_ret(s, -1);
|
||||||
|
|
||||||
|
if (sprite_clone(&refs[GUI_LINE_EDIT_RIGHT], s))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
s->x = x;
|
||||||
|
s->y = y;
|
||||||
|
sprite_sort(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int render(const struct gui_common *const g)
|
||||||
|
{
|
||||||
|
const struct gui_line_edit *const l = (const struct gui_line_edit *)g;
|
||||||
|
short x, y;
|
||||||
|
|
||||||
|
gui_coords(&l->common, &x, &y);
|
||||||
|
|
||||||
|
if (render_left(l, &x, y)
|
||||||
|
|| render_mid(l, &x, y)
|
||||||
|
|| render_right(x, y))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_dim(const struct gui_common *const g,
|
||||||
|
short *const w, short *const h)
|
||||||
|
{
|
||||||
|
struct gui_line_edit *const l = (struct gui_line_edit *)g;
|
||||||
|
|
||||||
|
*w = l->w;
|
||||||
|
*h = refs->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_char(const char ch, void *const user)
|
||||||
|
{
|
||||||
|
struct gui_line_edit *const l = user;
|
||||||
|
|
||||||
|
if (l->i + 1 < l->sz)
|
||||||
|
l->text[l->i++] = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_erase(void *const user)
|
||||||
|
{
|
||||||
|
struct gui_line_edit *const l = user;
|
||||||
|
|
||||||
|
if (l->i)
|
||||||
|
l->text[--l->i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int update(struct gui_common *const g,
|
||||||
|
const union peripheral *const p, const struct camera *const c,
|
||||||
|
struct input *const in)
|
||||||
|
{
|
||||||
|
struct gui_line_edit *const l = (struct gui_line_edit *)g;
|
||||||
|
|
||||||
|
if (gui_pressed(&l->common, in, p, c, l->w, refs->h))
|
||||||
|
{
|
||||||
|
l->focus = true;
|
||||||
|
|
||||||
|
*in = (const struct input)
|
||||||
|
{
|
||||||
|
.cb = on_char,
|
||||||
|
.erase = on_erase,
|
||||||
|
.user = l
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (l->focus && gui_released(&l->common, p, c, l->w, refs->h))
|
||||||
|
{
|
||||||
|
l->focus = false;
|
||||||
|
|
||||||
|
if (in->user == l)
|
||||||
|
*in = (const struct input){0};
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit(struct gui_common *const g, struct input *const in)
|
||||||
|
{
|
||||||
|
struct gui_line_edit *const l = (struct gui_line_edit *)g;
|
||||||
|
|
||||||
|
if (l->focus)
|
||||||
|
*in = (const struct input){0};
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui_line_edit_init(struct gui_line_edit *const l, char *const buf,
|
||||||
|
const size_t sz)
|
||||||
|
{
|
||||||
|
static const struct gui_common_cb cb =
|
||||||
|
{
|
||||||
|
.get_dim = get_dim,
|
||||||
|
.update = update,
|
||||||
|
.render = render,
|
||||||
|
.deinit = deinit
|
||||||
|
};
|
||||||
|
|
||||||
|
*l = (const struct gui_line_edit)
|
||||||
|
{
|
||||||
|
.common =
|
||||||
|
{
|
||||||
|
.cb = &cb
|
||||||
|
},
|
||||||
|
|
||||||
|
.text = buf,
|
||||||
|
.sz = sz
|
||||||
|
};
|
||||||
|
|
||||||
|
gui_label_init(&l->label);
|
||||||
|
memset(l->text, '\0', l->sz);
|
||||||
|
l->label.common.hcentered = true;
|
||||||
|
l->label.common.vcentered = true;
|
||||||
|
l->label.text = l->text;
|
||||||
|
gui_add_child(&l->common, &l->label.common);
|
||||||
|
}
|
Loading…
Reference in New Issue