added Editbox + removed c++ compile erros under gcc and clang
This commit is contained in:
parent
30ff356b73
commit
18f27e91a5
@ -6,7 +6,7 @@ application and does not have any direct dependencies.
|
|||||||
## Features
|
## Features
|
||||||
- Immediate mode graphical user interface toolkit
|
- Immediate mode graphical user interface toolkit
|
||||||
- Written in C89 (ANSI C)
|
- Written in C89 (ANSI C)
|
||||||
- Small codebase (~3kLOC)
|
- Small codebase (~4kLOC)
|
||||||
- Focus on portability, efficiency, simplicity and minimal internal state
|
- Focus on portability, efficiency, simplicity and minimal internal state
|
||||||
- Suited for embedding into graphical applications
|
- Suited for embedding into graphical applications
|
||||||
- No global or hidden state
|
- No global or hidden state
|
||||||
|
485
gui.c
485
gui.c
@ -5,9 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
|
||||||
#ifndef NULL
|
|
||||||
#define NULL ((void*)0)
|
|
||||||
#endif
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
@ -33,7 +30,18 @@
|
|||||||
#define gui_color_to_array(ar, c)\
|
#define gui_color_to_array(ar, c)\
|
||||||
(ar)[0] = (c).r, (ar)[1] = (c).g, (ar)[2] = (c).b, (ar)[3] = (c).a
|
(ar)[0] = (c).r, (ar)[1] = (c).g, (ar)[2] = (c).b, (ar)[3] = (c).a
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
template<typename T> struct gui_alignof;
|
||||||
|
template<typename T, int size_diff> struct gui_helper{enum {value = size_diff};};
|
||||||
|
template<typename T> struct gui_helper<T,0>{enum {value = gui_alignof<T>::value};};
|
||||||
|
template<typename T> struct gui_alignof{struct Big {T x; char c;}; enum {
|
||||||
|
diff = sizeof(Big) - sizeof(T), value = gui_helper<Big, diff>::value};};
|
||||||
|
#define GUI_ALIGNOF(t) (gui_alignof<t>::value);
|
||||||
|
#else
|
||||||
#define GUI_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
|
#define GUI_ALIGNOF(t) ((char*)(&((struct {char c; t _h;}*)0)->_h) - (char*)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define GUI_ALIGN_PTR(x, mask) (void*)((gui_size)((gui_byte*)(x) + (mask-1)) & ~(mask-1))
|
#define GUI_ALIGN_PTR(x, mask) (void*)((gui_size)((gui_byte*)(x) + (mask-1)) & ~(mask-1))
|
||||||
#define GUI_ALIGN(x, mask) ((x) + (mask-1)) & ~(mask-1)
|
#define GUI_ALIGN(x, mask) ((x) + (mask-1)) & ~(mask-1)
|
||||||
#define GUI_OFFSETOF(st, m) ((gui_size)(&((st *)0)->m))
|
#define GUI_OFFSETOF(st, m) ((gui_size)(&((st *)0)->m))
|
||||||
@ -78,8 +86,8 @@ static void*
|
|||||||
gui_memcopy(void *dst, const void *src, gui_size size)
|
gui_memcopy(void *dst, const void *src, gui_size size)
|
||||||
{
|
{
|
||||||
gui_size i = 0;
|
gui_size i = 0;
|
||||||
char *d = dst;
|
char *d = (char*)dst;
|
||||||
const char *s = src;
|
const char *s = (const char*)src;
|
||||||
for (i = 0; i < size; ++i)
|
for (i = 0; i < size; ++i)
|
||||||
d[i] = s[i];
|
d[i] = s[i];
|
||||||
return dst;
|
return dst;
|
||||||
@ -158,7 +166,7 @@ static void
|
|||||||
gui_zero(void *dst, gui_size size)
|
gui_zero(void *dst, gui_size size)
|
||||||
{
|
{
|
||||||
gui_size i;
|
gui_size i;
|
||||||
char *d = dst;
|
char *d = (char*)dst;
|
||||||
for (i = 0; i < size; ++i) d[i] = 0;
|
for (i = 0; i < size; ++i) d[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,32 +475,42 @@ gui_buffer_alloc(struct gui_buffer *b, gui_size size, gui_size align)
|
|||||||
void *memory;
|
void *memory;
|
||||||
|
|
||||||
GUI_ASSERT(b);
|
GUI_ASSERT(b);
|
||||||
if (!b || !size) return NULL;
|
if (!b || !size) return 0;
|
||||||
b->needed += size;
|
b->needed += size;
|
||||||
|
|
||||||
/* calculate total size with needed alignment + size */
|
/* calculate total size with needed alignment + size */
|
||||||
unaligned = gui_ptr_add(void, b->memory.ptr, b->allocated);
|
unaligned = gui_ptr_add(void, b->memory.ptr, b->allocated);
|
||||||
|
if (align) {
|
||||||
memory = GUI_ALIGN_PTR(unaligned, align);
|
memory = GUI_ALIGN_PTR(unaligned, align);
|
||||||
alignment = (gui_size)((gui_byte*)memory - (gui_byte*)unaligned);
|
alignment = (gui_size)((gui_byte*)memory - (gui_byte*)unaligned);
|
||||||
|
} else {
|
||||||
|
memory = unaligned;
|
||||||
|
alignment = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* check if buffer has enough memory*/
|
/* check if buffer has enough memory*/
|
||||||
if ((b->allocated + size + alignment) >= b->memory.size) {
|
if ((b->allocated + size + alignment) >= b->memory.size) {
|
||||||
void *temp;
|
void *temp;
|
||||||
if (b->type != GUI_BUFFER_DYNAMIC || !b->pool.realloc)
|
if (b->type != GUI_BUFFER_DYNAMIC || !b->pool.realloc)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
/* allocated new bigger block of memory if the buffer is dynamic */
|
/* allocated new bigger block of memory if the buffer is dynamic */
|
||||||
cap = (gui_size)((gui_float)b->memory.size * b->grow_factor);
|
cap = (gui_size)((gui_float)b->memory.size * b->grow_factor);
|
||||||
temp = b->pool.realloc(b->pool.userdata, b->memory.ptr, cap);
|
temp = b->pool.realloc(b->pool.userdata, b->memory.ptr, cap);
|
||||||
if (!temp) return NULL;
|
if (!temp) return 0;
|
||||||
|
|
||||||
b->memory.ptr = temp;
|
b->memory.ptr = temp;
|
||||||
b->memory.size = cap;
|
b->memory.size = cap;
|
||||||
|
|
||||||
/* align newly allocated pointer to memory */
|
/* align newly allocated pointer to memory */
|
||||||
unaligned = gui_ptr_add(gui_byte, b->memory.ptr, b->allocated);
|
unaligned = gui_ptr_add(gui_byte, b->memory.ptr, b->allocated);
|
||||||
|
if (align) {
|
||||||
memory = GUI_ALIGN_PTR(unaligned, align);
|
memory = GUI_ALIGN_PTR(unaligned, align);
|
||||||
alignment = (gui_size)((gui_byte*)memory - (gui_byte*)unaligned);
|
alignment = (gui_size)((gui_byte*)memory - (gui_byte*)unaligned);
|
||||||
|
} else {
|
||||||
|
memory = unaligned;
|
||||||
|
alignment = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b->allocated += size + alignment;
|
b->allocated += size + alignment;
|
||||||
@ -549,10 +567,10 @@ gui_command_buffer_push(struct gui_command_buffer* b,
|
|||||||
void *unaligned;
|
void *unaligned;
|
||||||
void *memory;
|
void *memory;
|
||||||
GUI_ASSERT(b);
|
GUI_ASSERT(b);
|
||||||
if (!b) return NULL;
|
if (!b) return 0;
|
||||||
|
|
||||||
cmd = gui_buffer_alloc(&b->base, size, align);
|
cmd = (struct gui_command*)gui_buffer_alloc(&b->base, size, align);
|
||||||
if (!cmd) return NULL;
|
if (!cmd) return 0;
|
||||||
|
|
||||||
/* make sure the offset to the next command is aligned */
|
/* make sure the offset to the next command is aligned */
|
||||||
unaligned = (gui_byte*)cmd + size;
|
unaligned = (gui_byte*)cmd + size;
|
||||||
@ -577,7 +595,8 @@ gui_command_buffer_push_scissor(struct gui_command_buffer *b, gui_float x, gui_f
|
|||||||
b->clip.w = w;
|
b->clip.w = w;
|
||||||
b->clip.h = h;
|
b->clip.h = h;
|
||||||
|
|
||||||
cmd = gui_command_buffer_push(b, GUI_COMMAND_SCISSOR, sizeof(*cmd));
|
cmd = (struct gui_command_scissor*)
|
||||||
|
gui_command_buffer_push(b, GUI_COMMAND_SCISSOR, sizeof(*cmd));
|
||||||
if (!cmd) return;
|
if (!cmd) return;
|
||||||
cmd->x = (gui_short)x;
|
cmd->x = (gui_short)x;
|
||||||
cmd->y = (gui_short)y;
|
cmd->y = (gui_short)y;
|
||||||
@ -593,7 +612,8 @@ gui_command_buffer_push_line(struct gui_command_buffer *b, gui_float x0, gui_flo
|
|||||||
GUI_ASSERT(buffer);
|
GUI_ASSERT(buffer);
|
||||||
if (!b) return;
|
if (!b) return;
|
||||||
|
|
||||||
cmd = gui_command_buffer_push(b, GUI_COMMAND_LINE, sizeof(*cmd));
|
cmd = (struct gui_command_line*)
|
||||||
|
gui_command_buffer_push(b, GUI_COMMAND_LINE, sizeof(*cmd));
|
||||||
if (!cmd) return;
|
if (!cmd) return;
|
||||||
cmd->begin[0] = (gui_short)x0;
|
cmd->begin[0] = (gui_short)x0;
|
||||||
cmd->begin[1] = (gui_short)y0;
|
cmd->begin[1] = (gui_short)y0;
|
||||||
@ -616,7 +636,8 @@ gui_command_buffer_push_rect(struct gui_command_buffer *b, gui_float x, gui_floa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = gui_command_buffer_push(b, GUI_COMMAND_RECT, sizeof(*cmd));
|
cmd = (struct gui_command_rect*)
|
||||||
|
gui_command_buffer_push(b, GUI_COMMAND_RECT, sizeof(*cmd));
|
||||||
if (!cmd) return;
|
if (!cmd) return;
|
||||||
cmd->r = (gui_uint)rounding;
|
cmd->r = (gui_uint)rounding;
|
||||||
cmd->x = (gui_short)x;
|
cmd->x = (gui_short)x;
|
||||||
@ -640,7 +661,8 @@ gui_command_buffer_push_circle(struct gui_command_buffer *b, gui_float x, gui_fl
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = gui_command_buffer_push(b, GUI_COMMAND_CIRCLE, sizeof(*cmd));
|
cmd = (struct gui_command_circle*)
|
||||||
|
gui_command_buffer_push(b, GUI_COMMAND_CIRCLE, sizeof(*cmd));
|
||||||
if (!cmd) return;
|
if (!cmd) return;
|
||||||
cmd->x = (gui_short)x;
|
cmd->x = (gui_short)x;
|
||||||
cmd->y = (gui_short)y;
|
cmd->y = (gui_short)y;
|
||||||
@ -665,7 +687,8 @@ gui_command_buffer_push_triangle(struct gui_command_buffer *b, gui_float x0, gui
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = gui_command_buffer_push(b, GUI_COMMAND_TRIANGLE, sizeof(*cmd));
|
cmd = (struct gui_command_triangle*)
|
||||||
|
gui_command_buffer_push(b, GUI_COMMAND_TRIANGLE, sizeof(*cmd));
|
||||||
if (!cmd) return;
|
if (!cmd) return;
|
||||||
cmd->a[0] = (gui_short)x0;
|
cmd->a[0] = (gui_short)x0;
|
||||||
cmd->a[1] = (gui_short)y0;
|
cmd->a[1] = (gui_short)y0;
|
||||||
@ -690,7 +713,8 @@ gui_command_buffer_push_image(struct gui_command_buffer *b, gui_float x, gui_flo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = gui_command_buffer_push(b, GUI_COMMAND_IMAGE, sizeof(*cmd));
|
cmd = (struct gui_command_image*)
|
||||||
|
gui_command_buffer_push(b, GUI_COMMAND_IMAGE, sizeof(*cmd));
|
||||||
if (!cmd) return;
|
if (!cmd) return;
|
||||||
cmd->x = (gui_short)x;
|
cmd->x = (gui_short)x;
|
||||||
cmd->y = (gui_short)y;
|
cmd->y = (gui_short)y;
|
||||||
@ -715,7 +739,8 @@ gui_command_buffer_push_text(struct gui_command_buffer *b, gui_float x, gui_floa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = gui_command_buffer_push(b, GUI_COMMAND_TEXT, sizeof(*cmd) + length + 1);
|
cmd = (struct gui_command_text*)
|
||||||
|
gui_command_buffer_push(b, GUI_COMMAND_TEXT, sizeof(*cmd) + length + 1);
|
||||||
if (!cmd) return;
|
if (!cmd) return;
|
||||||
cmd->x = (gui_short)x;
|
cmd->x = (gui_short)x;
|
||||||
cmd->y = (gui_short)y;
|
cmd->y = (gui_short)y;
|
||||||
@ -729,6 +754,166 @@ gui_command_buffer_push_text(struct gui_command_buffer *b, gui_float x, gui_floa
|
|||||||
cmd->string[length] = '\0';
|
cmd->string[length] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==============================================================
|
||||||
|
*
|
||||||
|
* Edit Box
|
||||||
|
*
|
||||||
|
* ===============================================================
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gui_edit_buffer_append(gui_edit_buffer *buffer, const char *str, gui_size len)
|
||||||
|
{
|
||||||
|
char *mem;
|
||||||
|
GUI_ASSERT(buffer);
|
||||||
|
if (!buffer || !str || !len) return;
|
||||||
|
mem = (char*)gui_buffer_alloc(buffer, len * sizeof(char), 0);
|
||||||
|
if (!mem) return;
|
||||||
|
gui_memcopy(mem, str, len * sizeof(char));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_edit_buffer_insert(gui_edit_buffer *buffer, gui_size pos, const char *str, gui_size len)
|
||||||
|
{
|
||||||
|
void *mem;
|
||||||
|
gui_size i;
|
||||||
|
char *src, *dst;
|
||||||
|
|
||||||
|
gui_size copylen;
|
||||||
|
GUI_ASSERT(buffer);
|
||||||
|
if (!buffer || !str || !len || pos > buffer->allocated) return;
|
||||||
|
|
||||||
|
copylen = buffer->allocated - pos;
|
||||||
|
if (!copylen) {
|
||||||
|
gui_edit_buffer_append(buffer, str, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* memmove */
|
||||||
|
mem = gui_buffer_alloc(buffer, len * sizeof(char), 0);
|
||||||
|
if (!mem) return;
|
||||||
|
dst = gui_ptr_add(char, buffer->memory.ptr, pos + len + copylen);
|
||||||
|
src = gui_ptr_add(char, buffer->memory.ptr, pos + copylen);
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
*dst-- = *src--;
|
||||||
|
mem = gui_ptr_add(void, buffer->memory.ptr, pos);
|
||||||
|
gui_memcopy(mem, str, len * sizeof(char));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_edit_buffer_remove(gui_edit_buffer *buffer, gui_size len)
|
||||||
|
{
|
||||||
|
GUI_ASSERT(buffer);
|
||||||
|
if (!buffer || len > buffer->allocated) return;
|
||||||
|
buffer->allocated -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_edit_buffer_del(gui_edit_buffer *buffer, gui_size pos, gui_size len)
|
||||||
|
{
|
||||||
|
char *src, *dst;
|
||||||
|
GUI_ASSERT(buffer);
|
||||||
|
if (!buffer || !len || pos > buffer->allocated ||
|
||||||
|
pos + len > buffer->allocated) return;
|
||||||
|
|
||||||
|
/* memmove */
|
||||||
|
dst = gui_ptr_add(char, buffer->memory.ptr, pos);
|
||||||
|
src = gui_ptr_add(char, buffer->memory.ptr, pos + len);
|
||||||
|
gui_memcopy(dst, src, len * sizeof(char));
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
gui_edit_buffer_at(gui_edit_buffer *buffer, gui_size pos)
|
||||||
|
{
|
||||||
|
GUI_ASSERT(buffer);
|
||||||
|
if (!buffer || pos > buffer->allocated) return 0;
|
||||||
|
return gui_ptr_add(char, buffer->memory.ptr, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_edit_box_init(struct gui_edit_box *eb, struct gui_allocator *a, gui_size initial_size,
|
||||||
|
gui_float grow_fac, const struct gui_clipboard *clip, gui_filter f)
|
||||||
|
{
|
||||||
|
GUI_ASSERT(eb);
|
||||||
|
GUI_ASSERT(a);
|
||||||
|
GUI_ASSERT(grow_fac);
|
||||||
|
if (!eb || !a) return;
|
||||||
|
|
||||||
|
gui_zero(eb, sizeof(*eb));
|
||||||
|
gui_buffer_init(&eb->buffer, a, initial_size, grow_fac);
|
||||||
|
if (clip) eb->clip = *clip;
|
||||||
|
eb->filter = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_edit_box_init_fixed(struct gui_edit_box *eb, void *memory, gui_size size,
|
||||||
|
const struct gui_clipboard *clip, gui_filter f)
|
||||||
|
{
|
||||||
|
GUI_ASSERT(eb);
|
||||||
|
GUI_ASSERT(a);
|
||||||
|
GUI_ASSERT(grow_fac);
|
||||||
|
GUI_ASSERT(clip);
|
||||||
|
if (!eb) return;
|
||||||
|
|
||||||
|
gui_zero(eb, sizeof(*eb));
|
||||||
|
gui_buffer_init_fixed(&eb->buffer, memory, size);
|
||||||
|
if (clip) eb->clip = *clip;
|
||||||
|
eb->filter = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_edit_box_add(struct gui_edit_box *eb, const char *str, gui_size len)
|
||||||
|
{
|
||||||
|
GUI_ASSERT(eb);
|
||||||
|
if (!eb || !str || !len) return;
|
||||||
|
gui_edit_buffer_insert(&eb->buffer, eb->buffer.allocated, str, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gui_edit_box_buffer_input(struct gui_edit_box *box, const struct gui_input *i)
|
||||||
|
{
|
||||||
|
gui_long unicode;
|
||||||
|
gui_size src_len = 0;
|
||||||
|
gui_size text_len = 0, glyph_len = 0;
|
||||||
|
GUI_ASSERT(buffer);
|
||||||
|
GUI_ASSERT(i);
|
||||||
|
|
||||||
|
/* add user provided text to buffer until either no input or buffer space left*/
|
||||||
|
glyph_len = gui_utf_decode(i->text, &unicode, i->text_len);
|
||||||
|
while (glyph_len && ((text_len+glyph_len) <= i->text_len)) {
|
||||||
|
/* filter value to make sure the value is correct */
|
||||||
|
if (box->filter(unicode)) {
|
||||||
|
gui_size n = 0;
|
||||||
|
for (n = 0; n < glyph_len; n++)
|
||||||
|
gui_edit_box_add(box, &i->text[text_len + n], glyph_len);
|
||||||
|
text_len += glyph_len;
|
||||||
|
}
|
||||||
|
src_len = src_len + glyph_len;
|
||||||
|
glyph_len = gui_utf_decode(i->text + src_len, &unicode, i->text_len - src_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_edit_box_remove(struct gui_edit_box *eb)
|
||||||
|
{
|
||||||
|
GUI_ASSERT(eb);
|
||||||
|
gui_edit_buffer_remove(&eb->buffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_char*
|
||||||
|
gui_edit_box_get(struct gui_edit_box *eb)
|
||||||
|
{
|
||||||
|
GUI_ASSERT(eb);
|
||||||
|
return (gui_char*)eb->buffer.memory.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_size
|
||||||
|
gui_edit_box_len(struct gui_edit_box *eb)
|
||||||
|
{
|
||||||
|
GUI_ASSERT(eb);
|
||||||
|
return eb->buffer.allocated;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ==============================================================
|
* ==============================================================
|
||||||
*
|
*
|
||||||
@ -1158,107 +1343,22 @@ gui_progress(struct gui_command_buffer *out, gui_float x, gui_float y,
|
|||||||
return prog_value;
|
return prog_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gui_bool
|
void
|
||||||
gui_filter_input_default(gui_long unicode)
|
gui_editbox(struct gui_command_buffer *out, gui_float x, gui_float y, gui_float w,
|
||||||
{
|
gui_float h, struct gui_edit_box *box, const struct gui_edit *field,
|
||||||
(void)unicode;
|
const struct gui_input *in, const struct gui_font *font)
|
||||||
return gui_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gui_bool
|
|
||||||
gui_filter_input_ascii(gui_long unicode)
|
|
||||||
{
|
|
||||||
if (unicode < 0 || unicode > 128)
|
|
||||||
return gui_false;
|
|
||||||
return gui_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gui_bool
|
|
||||||
gui_filter_input_float(gui_long unicode)
|
|
||||||
{
|
|
||||||
if ((unicode < '0' || unicode > '9') && unicode != '.' && unicode != '-')
|
|
||||||
return gui_false;
|
|
||||||
return gui_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gui_bool
|
|
||||||
gui_filter_input_decimal(gui_long unicode)
|
|
||||||
{
|
|
||||||
if (unicode < '0' || unicode > '9')
|
|
||||||
return gui_false;
|
|
||||||
return gui_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gui_bool
|
|
||||||
gui_filter_input_hex(gui_long unicode)
|
|
||||||
{
|
|
||||||
if ((unicode < '0' || unicode > '9') &&
|
|
||||||
(unicode < 'a' || unicode > 'f') &&
|
|
||||||
(unicode < 'A' || unicode > 'B'))
|
|
||||||
return gui_false;
|
|
||||||
return gui_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gui_bool
|
|
||||||
gui_filter_input_oct(gui_long unicode)
|
|
||||||
{
|
|
||||||
if (unicode < '0' || unicode > '7')
|
|
||||||
return gui_false;
|
|
||||||
return gui_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gui_bool
|
|
||||||
gui_filter_input_binary(gui_long unicode)
|
|
||||||
{
|
|
||||||
if (unicode < '0' || unicode > '1')
|
|
||||||
return gui_false;
|
|
||||||
return gui_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gui_size
|
|
||||||
gui_buffer_input(gui_char *buffer, gui_size length, gui_size max,
|
|
||||||
gui_filter filter, const struct gui_input *i)
|
|
||||||
{
|
|
||||||
gui_long unicode;
|
|
||||||
gui_size src_len = 0;
|
|
||||||
gui_size text_len = 0, glyph_len = 0;
|
|
||||||
GUI_ASSERT(buffer);
|
|
||||||
GUI_ASSERT(i);
|
|
||||||
|
|
||||||
/* add user provided text to buffer until either no input or buffer space left*/
|
|
||||||
glyph_len = gui_utf_decode(i->text, &unicode, i->text_len);
|
|
||||||
while (glyph_len && ((text_len+glyph_len) <= i->text_len) && (length+src_len)<max) {
|
|
||||||
/* filter value to make sure the value is correct */
|
|
||||||
if (filter(unicode)) {
|
|
||||||
gui_size n = 0;
|
|
||||||
for (n = 0; n < glyph_len; n++)
|
|
||||||
buffer[length++] = i->text[text_len + n];
|
|
||||||
text_len += glyph_len;
|
|
||||||
}
|
|
||||||
src_len = src_len + glyph_len;
|
|
||||||
glyph_len = gui_utf_decode(i->text + src_len, &unicode, i->text_len - src_len);
|
|
||||||
}
|
|
||||||
return text_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
gui_size
|
|
||||||
gui_edit_filtered(struct gui_command_buffer *out, gui_float x, gui_float y, gui_float w,
|
|
||||||
gui_float h, gui_char *buffer, gui_size len, gui_size max, gui_bool *active,
|
|
||||||
const struct gui_edit *field, gui_filter filter, const struct gui_input *in,
|
|
||||||
const struct gui_font *font)
|
|
||||||
{
|
{
|
||||||
gui_float input_w, input_h;
|
gui_float input_w, input_h;
|
||||||
gui_bool input_active;
|
gui_char *buffer;
|
||||||
|
gui_size len, max;
|
||||||
GUI_ASSERT(out);
|
GUI_ASSERT(out);
|
||||||
GUI_ASSERT(buffer);
|
GUI_ASSERT(buffer);
|
||||||
GUI_ASSERT(field);
|
GUI_ASSERT(field);
|
||||||
if (!out || !buffer || !field)
|
if (!out || !box || !field)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
input_w = MAX(w, 2 * field->padding.x);
|
input_w = MAX(w, 2 * field->padding.x);
|
||||||
input_h = MAX(h, font->height);
|
input_h = MAX(h, font->height);
|
||||||
input_active = *active;
|
|
||||||
|
|
||||||
/* draw editbox background and border */
|
/* draw editbox background and border */
|
||||||
gui_command_buffer_push_rect(out, x, y, input_w, input_h,field->rounding, field->border);
|
gui_command_buffer_push_rect(out, x, y, input_w, input_h,field->rounding, field->border);
|
||||||
@ -1266,38 +1366,47 @@ gui_edit_filtered(struct gui_command_buffer *out, gui_float x, gui_float y, gui_
|
|||||||
input_w - 2 * field->border_size, input_h - 2 * field->border_size,
|
input_w - 2 * field->border_size, input_h - 2 * field->border_size,
|
||||||
field->rounding, field->background);
|
field->rounding, field->background);
|
||||||
|
|
||||||
/* check if editbox is not active */
|
/* check if editbox was activated/deactivated */
|
||||||
if (in && in->mouse_clicked && in->mouse_down)
|
if (in && in->mouse_clicked && in->mouse_down)
|
||||||
input_active = GUI_INBOX(in->mouse_pos.x, in->mouse_pos.y, x, y, input_w, input_h);
|
box->active = GUI_INBOX(in->mouse_pos.x, in->mouse_pos.y, x, y, input_w, input_h);
|
||||||
|
|
||||||
if (input_active && in) {
|
max = box->buffer.memory.size;
|
||||||
|
len = gui_edit_box_len(box);
|
||||||
|
buffer = gui_edit_box_get(box);
|
||||||
|
if (box->active && in) {
|
||||||
const struct gui_key *bs = &in->keys[GUI_KEY_BACKSPACE];
|
const struct gui_key *bs = &in->keys[GUI_KEY_BACKSPACE];
|
||||||
const struct gui_key *del = &in->keys[GUI_KEY_DEL];
|
const struct gui_key *del = &in->keys[GUI_KEY_DEL];
|
||||||
const struct gui_key *esc = &in->keys[GUI_KEY_ESCAPE];
|
|
||||||
const struct gui_key *enter = &in->keys[GUI_KEY_ENTER];
|
const struct gui_key *enter = &in->keys[GUI_KEY_ENTER];
|
||||||
const struct gui_key *space = &in->keys[GUI_KEY_SPACE];
|
const struct gui_key *space = &in->keys[GUI_KEY_SPACE];
|
||||||
|
const struct gui_key *copy = &in->keys[GUI_KEY_COPY];
|
||||||
|
const struct gui_key *paste = &in->keys[GUI_KEY_PASTE];
|
||||||
|
|
||||||
/* update input buffer by user input */
|
/* update input buffer by user input */
|
||||||
if ((del->down && del->clicked) || (bs->down && bs->clicked))
|
if ((del->down && del->clicked) || (bs->down && bs->clicked))
|
||||||
if (len > 0) len = len - 1;
|
gui_edit_box_remove(box);
|
||||||
if ((enter->down && enter->clicked) || (esc->down && esc->clicked))
|
if (enter->down && enter->clicked)
|
||||||
input_active = gui_false;
|
box->active = gui_false;
|
||||||
if ((space->down && space->clicked) && (len < max))
|
if (copy->down && copy->clicked && box->clip.copy)
|
||||||
buffer[len++] = ' ';
|
box->clip.copy(box->clip.userdata, buffer, len);
|
||||||
if (in->text_len && len < max)
|
if (paste->down && paste->clicked && box->clip.paste)
|
||||||
len += gui_buffer_input(buffer, len, max, filter, in);
|
box->buffer.allocated = box->clip.paste(box->clip.userdata, buffer, max);
|
||||||
|
if (space->down && space->clicked)
|
||||||
|
gui_edit_box_add(box, " ", 1);
|
||||||
|
if (in->text_len)
|
||||||
|
gui_edit_box_buffer_input(box, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (font && buffer) {
|
if (font) {
|
||||||
gui_size offset = 0;
|
gui_size offset = 0;
|
||||||
gui_float label_x, label_y, label_h;
|
gui_float label_x, label_y, label_h;
|
||||||
gui_float label_w = input_w - 2 * field->padding.x - 2 * field->border_size;
|
gui_float label_w = input_w - 2 * field->padding.x - 2 * field->border_size;
|
||||||
gui_size cursor_w =(gui_size)font->width(font->userdata,(const gui_char*)"X", 1);
|
gui_size cursor_w = font->width(font->userdata,(const gui_char*)"X", 1);
|
||||||
|
|
||||||
/* calculate the visible text range */
|
/* calculate the visible text range */
|
||||||
gui_size text_len = len;
|
gui_size text_len = len;
|
||||||
|
gui_float space = label_w - (gui_float)cursor_w;
|
||||||
gui_size text_width = font->width(font->userdata, buffer, text_len);
|
gui_size text_width = font->width(font->userdata, buffer, text_len);
|
||||||
while (text_len && (text_width + cursor_w) > (gui_size)label_w) {
|
while (text_len && (text_width > space)) {
|
||||||
gui_long unicode;
|
gui_long unicode;
|
||||||
offset += gui_utf_decode(&buffer[offset], &unicode, text_len);
|
offset += gui_utf_decode(&buffer[offset], &unicode, text_len);
|
||||||
text_len = len - offset;
|
text_len = len - offset;
|
||||||
@ -1312,14 +1421,83 @@ gui_edit_filtered(struct gui_command_buffer *out, gui_float x, gui_float y, gui_
|
|||||||
&buffer[offset], text_len, font, field->background, field->text);
|
&buffer[offset], text_len, font, field->background, field->text);
|
||||||
|
|
||||||
/* if wanted draw the cursor at the end of the text input */
|
/* if wanted draw the cursor at the end of the text input */
|
||||||
if (input_active && field->show_cursor) {
|
if (box->active && field->show_cursor) {
|
||||||
gui_command_buffer_push_rect(out, label_x + (gui_float)text_width, label_y,
|
gui_command_buffer_push_rect(out, label_x + (gui_float)text_width, label_y,
|
||||||
(gui_float)cursor_w, label_h,0, field->cursor);
|
(gui_float)cursor_w, label_h, 0, field->cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*active = input_active;
|
}
|
||||||
return len;
|
|
||||||
|
|
||||||
|
gui_bool
|
||||||
|
gui_filter_input_default(gui_long unicode)
|
||||||
|
{
|
||||||
|
(void)unicode;
|
||||||
|
return gui_true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_bool
|
||||||
|
gui_filter_input_ascii(gui_long unicode)
|
||||||
|
{
|
||||||
|
if (unicode < 0 || unicode > 128)
|
||||||
|
return gui_false;
|
||||||
|
return gui_true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_bool
|
||||||
|
gui_filter_input_float(gui_long unicode)
|
||||||
|
{
|
||||||
|
if ((unicode < '0' || unicode > '9') && unicode != '.' && unicode != '-')
|
||||||
|
return gui_false;
|
||||||
|
return gui_true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_bool
|
||||||
|
gui_filter_input_decimal(gui_long unicode)
|
||||||
|
{
|
||||||
|
if (unicode < '0' || unicode > '9')
|
||||||
|
return gui_false;
|
||||||
|
return gui_true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_bool
|
||||||
|
gui_filter_input_hex(gui_long unicode)
|
||||||
|
{
|
||||||
|
if ((unicode < '0' || unicode > '9') &&
|
||||||
|
(unicode < 'a' || unicode > 'f') &&
|
||||||
|
(unicode < 'A' || unicode > 'B'))
|
||||||
|
return gui_false;
|
||||||
|
return gui_true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_bool
|
||||||
|
gui_filter_input_oct(gui_long unicode)
|
||||||
|
{
|
||||||
|
if (unicode < '0' || unicode > '7')
|
||||||
|
return gui_false;
|
||||||
|
return gui_true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_bool
|
||||||
|
gui_filter_input_binary(gui_long unicode)
|
||||||
|
{
|
||||||
|
if (unicode < '0' || unicode > '1')
|
||||||
|
return gui_false;
|
||||||
|
return gui_true;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui_size
|
||||||
|
gui_edit_filtered(struct gui_command_buffer *out, gui_float x, gui_float y, gui_float w,
|
||||||
|
gui_float h, gui_char *buffer, gui_size len, gui_size max, gui_bool *active,
|
||||||
|
const struct gui_edit *field, gui_filter filter, const struct gui_input *in,
|
||||||
|
const struct gui_font *font)
|
||||||
|
{
|
||||||
|
struct gui_edit_box box;
|
||||||
|
gui_edit_box_init_fixed(&box, buffer, max, 0, filter);
|
||||||
|
box.buffer.allocated = len;
|
||||||
|
box.active = *active;
|
||||||
|
gui_editbox(out, x, y, w, h, &box, field, in, font);
|
||||||
|
*active = box.active;
|
||||||
|
return gui_edit_box_len(&box);
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_size
|
gui_size
|
||||||
@ -1338,7 +1516,7 @@ gui_edit(struct gui_command_buffer *out, gui_float x, gui_float y, gui_float w,
|
|||||||
gui_filter_input_binary,
|
gui_filter_input_binary,
|
||||||
};
|
};
|
||||||
return gui_edit_filtered(out, x, y, w, h, buffer, len, max, active,
|
return gui_edit_filtered(out, x, y, w, h, buffer, len, max, active,
|
||||||
field,filter[f], in, font);
|
field, filter[f], in, font);
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_float
|
gui_float
|
||||||
@ -1921,7 +2099,7 @@ gui_panel_begin(struct gui_panel_layout *l, struct gui_panel *p,
|
|||||||
l->buffer = p->buffer;
|
l->buffer = p->buffer;
|
||||||
l->row.columns = 0;
|
l->row.columns = 0;
|
||||||
l->row.height = 0;
|
l->row.height = 0;
|
||||||
l->row.ratio = NULL;
|
l->row.ratio = 0;
|
||||||
l->row.item_ratio = 0;
|
l->row.item_ratio = 0;
|
||||||
l->offset = p->offset;
|
l->offset = p->offset;
|
||||||
out = p->buffer;
|
out = p->buffer;
|
||||||
@ -1985,8 +2163,8 @@ gui_panel_begin(struct gui_panel_layout *l, struct gui_panel *p,
|
|||||||
/* check if the close icon has been pressed and set the panel to hidden */
|
/* check if the close icon has been pressed and set the panel to hidden */
|
||||||
header_w -= close_w;
|
header_w -= close_w;
|
||||||
header_x += close_h - item_padding.x;
|
header_x += close_h - item_padding.x;
|
||||||
if (i && GUI_INBOX(mouse_x, mouse_y, close_x, close_y, text_width, close_h)) {
|
if (i && GUI_INBOX(mouse_x, mouse_y, close_x, close_y, (gui_float)text_width, close_h)) {
|
||||||
if (GUI_INBOX(clicked_x, clicked_y, close_x, close_y, text_width, close_h)) {
|
if (GUI_INBOX(clicked_x, clicked_y, close_x, close_y, (gui_float)text_width, close_h)) {
|
||||||
ret = !(i->mouse_down && i->mouse_clicked);
|
ret = !(i->mouse_down && i->mouse_clicked);
|
||||||
if (!ret) p->flags |= GUI_PANEL_HIDDEN;
|
if (!ret) p->flags |= GUI_PANEL_HIDDEN;
|
||||||
}
|
}
|
||||||
@ -2014,8 +2192,8 @@ gui_panel_begin(struct gui_panel_layout *l, struct gui_panel *p,
|
|||||||
/* minize the panel if the minimize icon has been pressed */
|
/* minize the panel if the minimize icon has been pressed */
|
||||||
header_w -= min_w;
|
header_w -= min_w;
|
||||||
header_x += min_w - item_padding.x;
|
header_x += min_w - item_padding.x;
|
||||||
if (i && GUI_INBOX(mouse_x, mouse_y, min_x, min_y, text_width, min_h)) {
|
if (i && GUI_INBOX(mouse_x, mouse_y, min_x, min_y, (gui_float)text_width, min_h)) {
|
||||||
if (GUI_INBOX(clicked_x, clicked_y, min_x, min_y, min_w, min_h))
|
if (GUI_INBOX(clicked_x, clicked_y, min_x, min_y, (gui_float)text_width, min_h))
|
||||||
if (i->mouse_down && i->mouse_clicked)
|
if (i->mouse_down && i->mouse_clicked)
|
||||||
p->minimized = !p->minimized;
|
p->minimized = !p->minimized;
|
||||||
}
|
}
|
||||||
@ -2093,7 +2271,7 @@ gui_panel_begin_stacked(struct gui_panel_layout *l, struct gui_panel* p,
|
|||||||
gui_stack_push(s, p);
|
gui_stack_push(s, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gui_panel_begin(l, p, title, (s->end == p) ? i : NULL);
|
return gui_panel_begin(l, p, title, (s->end == p) ? i : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_bool
|
gui_bool
|
||||||
@ -2269,7 +2447,7 @@ gui_panel_begin_tiled(struct gui_panel_layout *tile, struct gui_panel *panel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gui_stack_push(&layout->stack, panel);
|
gui_stack_push(&layout->stack, panel);
|
||||||
res = gui_panel_begin(tile,panel,title,(layout->flags&GUI_LAYOUT_INACTIVE)?NULL:in);
|
res = gui_panel_begin(tile,panel,title,(layout->flags&GUI_LAYOUT_INACTIVE)?0:in);
|
||||||
panel->flags &= ~(gui_flags)GUI_PANEL_DO_NOT_RESET;
|
panel->flags &= ~(gui_flags)GUI_PANEL_DO_NOT_RESET;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -2299,7 +2477,7 @@ gui_panel_row(struct gui_panel_layout *layout, gui_float height, gui_size cols)
|
|||||||
/* draw the current row and set the current row layout */
|
/* draw the current row and set the current row layout */
|
||||||
layout->index = 0;
|
layout->index = 0;
|
||||||
layout->at_y += layout->row.height;
|
layout->at_y += layout->row.height;
|
||||||
layout->row.ratio = NULL;
|
layout->row.ratio = 0;
|
||||||
layout->row.columns = cols;
|
layout->row.columns = cols;
|
||||||
layout->row.height = height + item_spacing.y;
|
layout->row.height = height + item_spacing.y;
|
||||||
gui_command_buffer_push_rect(out, layout->at_x, layout->at_y,
|
gui_command_buffer_push_rect(out, layout->at_x, layout->at_y,
|
||||||
@ -2445,7 +2623,7 @@ gui_panel_spacing(struct gui_panel_layout *l, gui_size cols)
|
|||||||
gui_bool
|
gui_bool
|
||||||
gui_panel_widget(struct gui_rect *bounds, struct gui_panel_layout *layout)
|
gui_panel_widget(struct gui_rect *bounds, struct gui_panel_layout *layout)
|
||||||
{
|
{
|
||||||
struct gui_rect *c = NULL;
|
struct gui_rect *c = 0;
|
||||||
GUI_ASSERT(layout);
|
GUI_ASSERT(layout);
|
||||||
GUI_ASSERT(layout->config);
|
GUI_ASSERT(layout->config);
|
||||||
GUI_ASSERT(layout->buffer);
|
GUI_ASSERT(layout->buffer);
|
||||||
@ -2817,6 +2995,17 @@ gui_panel_edit_base(struct gui_rect *bounds, struct gui_edit *field,
|
|||||||
return gui_true;
|
return gui_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gui_panel_editbox(struct gui_panel_layout *layout, struct gui_edit_box *box)
|
||||||
|
{
|
||||||
|
struct gui_rect bounds;
|
||||||
|
struct gui_edit field;
|
||||||
|
const struct gui_config *config = layout->config;
|
||||||
|
if (!gui_panel_edit_base(&bounds, &field, layout)) return;
|
||||||
|
gui_editbox(layout->buffer, bounds.x, bounds.y, bounds.w, bounds.h,
|
||||||
|
box, &field, layout->input, &config->font);
|
||||||
|
}
|
||||||
|
|
||||||
gui_size
|
gui_size
|
||||||
gui_panel_edit(struct gui_panel_layout *layout, gui_char *buffer, gui_size len,
|
gui_panel_edit(struct gui_panel_layout *layout, gui_char *buffer, gui_size len,
|
||||||
gui_size max, gui_bool *active, enum gui_input_filter filter)
|
gui_size max, gui_bool *active, enum gui_input_filter filter)
|
||||||
@ -3471,7 +3660,7 @@ gui_panel_shelf_begin(struct gui_panel_layout *parent, struct gui_panel_layout *
|
|||||||
/* setup fake panel to create a panel layout from */
|
/* setup fake panel to create a panel layout from */
|
||||||
flags = GUI_PANEL_BORDER|GUI_PANEL_SCROLLBAR|GUI_PANEL_TAB|GUI_PANEL_NO_HEADER;
|
flags = GUI_PANEL_BORDER|GUI_PANEL_SCROLLBAR|GUI_PANEL_TAB|GUI_PANEL_NO_HEADER;
|
||||||
gui_panel_init(&panel, bounds.x, bounds.y, bounds.w, bounds.h, flags, out, config);
|
gui_panel_init(&panel, bounds.x, bounds.y, bounds.w, bounds.h, flags, out, config);
|
||||||
gui_panel_begin(shelf, &panel, NULL, parent->input);
|
gui_panel_begin(shelf, &panel, 0, parent->input);
|
||||||
shelf->offset = offset;
|
shelf->offset = offset;
|
||||||
|
|
||||||
/* setup clip rect for the shelf panel */
|
/* setup clip rect for the shelf panel */
|
||||||
@ -3608,8 +3797,8 @@ gui_panel_end(struct gui_panel_layout *layout, struct gui_panel *panel)
|
|||||||
void
|
void
|
||||||
gui_stack_clear(struct gui_stack *stack)
|
gui_stack_clear(struct gui_stack *stack)
|
||||||
{
|
{
|
||||||
stack->begin = NULL;
|
stack->begin = 0;
|
||||||
stack->end = NULL;
|
stack->end = 0;
|
||||||
stack->count = 0;
|
stack->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3624,8 +3813,8 @@ gui_stack_push(struct gui_stack *stack, struct gui_panel *panel)
|
|||||||
if (iter == panel) return;
|
if (iter == panel) return;
|
||||||
|
|
||||||
if (!stack->begin) {
|
if (!stack->begin) {
|
||||||
panel->next = NULL;
|
panel->next = 0;
|
||||||
panel->prev = NULL;
|
panel->prev = 0;
|
||||||
stack->begin = panel;
|
stack->begin = panel;
|
||||||
stack->end = panel;
|
stack->end = panel;
|
||||||
stack->count = 1;
|
stack->count = 1;
|
||||||
@ -3634,7 +3823,7 @@ gui_stack_push(struct gui_stack *stack, struct gui_panel *panel)
|
|||||||
|
|
||||||
stack->end->next = panel;
|
stack->end->next = panel;
|
||||||
panel->prev = stack->end;
|
panel->prev = stack->end;
|
||||||
panel->next = NULL;
|
panel->next = 0;
|
||||||
stack->end = panel;
|
stack->end = panel;
|
||||||
stack->count++;
|
stack->count++;
|
||||||
}
|
}
|
||||||
@ -3655,8 +3844,8 @@ gui_stack_pop(struct gui_stack *stack, struct gui_panel*panel)
|
|||||||
if (stack->end == panel)
|
if (stack->end == panel)
|
||||||
stack->end = panel->prev;
|
stack->end = panel->prev;
|
||||||
|
|
||||||
panel->next = NULL;
|
panel->next = 0;
|
||||||
panel->prev = NULL;
|
panel->prev = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
96
gui.h
96
gui.h
@ -86,6 +86,9 @@ struct gui_image {gui_handle handle; struct gui_rect region;};
|
|||||||
struct gui_font;
|
struct gui_font;
|
||||||
typedef gui_bool(*gui_filter)(gui_long unicode);
|
typedef gui_bool(*gui_filter)(gui_long unicode);
|
||||||
typedef gui_size(*gui_text_width_f)(gui_handle, const gui_char*, gui_size);
|
typedef gui_size(*gui_text_width_f)(gui_handle, const gui_char*, gui_size);
|
||||||
|
typedef gui_size(*gui_paste_f)(gui_handle, char *buffer, gui_size max);
|
||||||
|
typedef void(*gui_copy_f)(gui_handle, const char*, gui_size size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ==============================================================
|
* ==============================================================
|
||||||
*
|
*
|
||||||
@ -93,6 +96,27 @@ typedef gui_size(*gui_text_width_f)(gui_handle, const gui_char*, gui_size);
|
|||||||
*
|
*
|
||||||
* ===============================================================
|
* ===============================================================
|
||||||
*/
|
*/
|
||||||
|
/* Utility
|
||||||
|
----------------------------
|
||||||
|
The utility API provides mainly a number of object construction function
|
||||||
|
for some gui specific objects like image handle, vector, color and rectangle.
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
----------------------------
|
||||||
|
Utility function API
|
||||||
|
gui_get_null_rect() -- returns a default clipping rectangle
|
||||||
|
gui_utf_decode() -- decodes a utf-8 glyph into u32 unicode glyph and len
|
||||||
|
gui_utf_encode() -- encodes a u32 unicode glyph into a utf-8 glyph
|
||||||
|
gui_image_ptr() -- create a image handle from pointer
|
||||||
|
gui_image_id() -- create a image handle from integer id
|
||||||
|
gui_subimage_ptr() -- create a sub-image handle from pointer and region
|
||||||
|
gui_subimage_id() -- create a sub-image handle from integer id and region
|
||||||
|
gui_rect_is_valid() -- check if a rectangle inside the image command is valid
|
||||||
|
gui_rect() -- creates a rectangle from x,y-Position and width and height
|
||||||
|
gui_vec2() -- creates a 2D vector, in the best case should not be needed by the user
|
||||||
|
gui_rgba() -- create a gui color struct from rgba color code
|
||||||
|
gui_rgb() -- create a gui color struct from rgb color code
|
||||||
|
*/
|
||||||
struct gui_rect gui_get_null_rect(void);
|
struct gui_rect gui_get_null_rect(void);
|
||||||
gui_size gui_utf_decode(const gui_char*, gui_long*, gui_size);
|
gui_size gui_utf_decode(const gui_char*, gui_long*, gui_size);
|
||||||
gui_size gui_utf_encode(gui_long, gui_char*, gui_size);
|
gui_size gui_utf_encode(gui_long, gui_char*, gui_size);
|
||||||
@ -174,8 +198,9 @@ enum gui_keys {
|
|||||||
GUI_KEY_DEL,
|
GUI_KEY_DEL,
|
||||||
GUI_KEY_ENTER,
|
GUI_KEY_ENTER,
|
||||||
GUI_KEY_BACKSPACE,
|
GUI_KEY_BACKSPACE,
|
||||||
GUI_KEY_ESCAPE,
|
|
||||||
GUI_KEY_SPACE,
|
GUI_KEY_SPACE,
|
||||||
|
GUI_KEY_COPY,
|
||||||
|
GUI_KEY_PASTE,
|
||||||
GUI_KEY_MAX
|
GUI_KEY_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -679,6 +704,58 @@ void gui_command_buffer_push_text(struct gui_command_buffer*, gui_float, gui_flo
|
|||||||
#define gui_foreach_command(i, b)\
|
#define gui_foreach_command(i, b)\
|
||||||
for((i)=gui_command_buffer_begin(b); (i)!=NULL; (i)=gui_command_buffer_next(b,i))
|
for((i)=gui_command_buffer_begin(b); (i)!=NULL; (i)=gui_command_buffer_next(b,i))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==============================================================
|
||||||
|
*
|
||||||
|
* Edit Buffer
|
||||||
|
*
|
||||||
|
* ===============================================================
|
||||||
|
*/
|
||||||
|
typedef struct gui_buffer gui_edit_buffer;
|
||||||
|
void gui_edit_buffer_append(gui_edit_buffer*, const char*, gui_size);
|
||||||
|
void gui_edit_buffer_insert(gui_edit_buffer*, gui_size pos, const char*, gui_size);
|
||||||
|
void gui_edit_buffer_remove(gui_edit_buffer*, gui_size);
|
||||||
|
void gui_edit_buffer_del(gui_edit_buffer*, gui_size pos, gui_size len);
|
||||||
|
char *gui_edit_buffer_at(gui_edit_buffer*, gui_size pos);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==============================================================
|
||||||
|
*
|
||||||
|
* Edit Box
|
||||||
|
*
|
||||||
|
* ===============================================================
|
||||||
|
*/
|
||||||
|
struct gui_clipboard {
|
||||||
|
gui_handle userdata;
|
||||||
|
gui_paste_f paste;
|
||||||
|
gui_copy_f copy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gui_edit_box {
|
||||||
|
gui_edit_buffer buffer;
|
||||||
|
gui_bool active;
|
||||||
|
struct gui_clipboard clip;
|
||||||
|
gui_filter filter;
|
||||||
|
};
|
||||||
|
|
||||||
|
gui_bool gui_filter_input_default(gui_long unicode);
|
||||||
|
gui_bool gui_filter_input_ascii(gui_long unicode);
|
||||||
|
gui_bool gui_filter_input_float(gui_long unicode);
|
||||||
|
gui_bool gui_filter_input_decimal(gui_long unicode);
|
||||||
|
gui_bool gui_filter_input_hex(gui_long unicode);
|
||||||
|
gui_bool gui_filter_input_oct(gui_long unicode);
|
||||||
|
gui_bool gui_filter_input_binary(gui_long unicode);
|
||||||
|
|
||||||
|
void gui_edit_box_init(struct gui_edit_box*, struct gui_allocator*, gui_size initial,
|
||||||
|
gui_float grow_fac, const struct gui_clipboard*, gui_filter);
|
||||||
|
void gui_edit_box_init_fixed(struct gui_edit_box*, void *memory, gui_size size,
|
||||||
|
const struct gui_clipboard*, gui_filter);
|
||||||
|
#define gui_edit_box_reset(b) gui_buffer_reset(&(b)->buffer)
|
||||||
|
#define gui_edit_box_clear(b) gui_buffer_clear(&(b)->buffer)
|
||||||
|
void gui_edit_box_add(struct gui_edit_box*, const char*, gui_size);
|
||||||
|
void gui_edit_box_remove(struct gui_edit_box*);
|
||||||
|
gui_char *gui_edit_box_get(struct gui_edit_box*);
|
||||||
|
gui_size gui_edit_box_len(struct gui_edit_box*);
|
||||||
/*
|
/*
|
||||||
* ==============================================================
|
* ==============================================================
|
||||||
*
|
*
|
||||||
@ -1086,6 +1163,19 @@ gui_size gui_progress(struct gui_command_buffer*, gui_float x, gui_float y,
|
|||||||
Output:
|
Output:
|
||||||
- returns the from the user input updated value
|
- returns the from the user input updated value
|
||||||
*/
|
*/
|
||||||
|
void gui_editbox(struct gui_command_buffer*, gui_float x, gui_float y, gui_float w,
|
||||||
|
gui_float h, struct gui_edit_box*, const struct gui_edit*,
|
||||||
|
const struct gui_input*, const struct gui_font*);
|
||||||
|
/* this function executes a editbox widget
|
||||||
|
Input:
|
||||||
|
- output command buffer for drawing
|
||||||
|
- (x,y) position
|
||||||
|
- (width, height) size
|
||||||
|
- edit box structure containing the state to update
|
||||||
|
- visual widget style structure describing the editbox
|
||||||
|
- input structure to update the editbox with
|
||||||
|
- font structure for text drawing
|
||||||
|
*/
|
||||||
gui_size gui_edit(struct gui_command_buffer*, gui_float x, gui_float y, gui_float w,
|
gui_size gui_edit(struct gui_command_buffer*, gui_float x, gui_float y, gui_float w,
|
||||||
gui_float h, gui_char*, gui_size, gui_size max, gui_bool*,
|
gui_float h, gui_char*, gui_size, gui_size max, gui_bool*,
|
||||||
const struct gui_edit*, enum gui_input_filter filter,
|
const struct gui_edit*, enum gui_input_filter filter,
|
||||||
@ -1942,6 +2032,8 @@ gui_size gui_panel_progress(struct gui_panel_layout*, gui_size cur, gui_size max
|
|||||||
Output:
|
Output:
|
||||||
- the from user input updated progressbar value if modifyable progressbar
|
- the from user input updated progressbar value if modifyable progressbar
|
||||||
*/
|
*/
|
||||||
|
void gui_panel_editbox(struct gui_panel_layout*, struct gui_edit_box*);
|
||||||
|
/* this function creates an editbox with copy & paste functionality and text buffering */
|
||||||
gui_size gui_panel_edit(struct gui_panel_layout*, gui_char *buffer, gui_size len,
|
gui_size gui_panel_edit(struct gui_panel_layout*, gui_char *buffer, gui_size len,
|
||||||
gui_size max, gui_bool *active, enum gui_input_filter);
|
gui_size max, gui_bool *active, enum gui_input_filter);
|
||||||
/* this function creates an editbox to updated/insert user text input
|
/* this function creates an editbox to updated/insert user text input
|
||||||
@ -2123,7 +2215,7 @@ void gui_stack_push(struct gui_stack*, struct gui_panel*);
|
|||||||
* the stack */
|
* the stack */
|
||||||
void gui_stack_pop(struct gui_stack*, struct gui_panel*);
|
void gui_stack_pop(struct gui_stack*, struct gui_panel*);
|
||||||
/* this function removes a panel from the stack */
|
/* this function removes a panel from the stack */
|
||||||
#define gui_foreach_panel(i, s) for (i = (s)->begin; i != NULL; i = (i)->next)
|
#define gui_foreach_panel(i, s) for (i = (s)->begin; i != 0; i = (i)->next)
|
||||||
/* iterates over each panel inside the stack */
|
/* iterates over each panel inside the stack */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user