text box
This commit is contained in:
parent
39cfa35bfd
commit
094b0efc33
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
*****************************************************************/
|
||||
#include<stdlib.h>
|
||||
#include<string.h>
|
||||
#include"milepost.h"
|
||||
|
||||
#define LOG_SUBSYSTEM "Main"
|
||||
|
@ -137,36 +138,24 @@ int main()
|
|||
|
||||
mp_rect windowRect = mp_window_get_content_rect(window);
|
||||
|
||||
ui_style defaultStyle = {.borderSize = 2,
|
||||
ui_style defaultStyle = {.bgColor = {0.9, 0.9, 0.9, 1},
|
||||
.borderSize = 2,
|
||||
.borderColor = {0, 0, 1, 1},
|
||||
.textColor = {0, 0, 0, 1},
|
||||
.fontColor = {0, 0, 0, 1},
|
||||
.font = font,
|
||||
.fontSize = 32};
|
||||
|
||||
ui_style buttonStyle[UI_STYLE_SELECTOR_COUNT];
|
||||
for(int i=0; i<UI_STYLE_SELECTOR_COUNT; i++)
|
||||
{
|
||||
buttonStyle[i] = (ui_style){ .backgroundColor = {0.8, 0.8, 0.8, 1},
|
||||
.foregroundColor = {0.5, 0.5, 0.5, 1},
|
||||
.borderSize = 2,
|
||||
.borderColor = {0, 0, 1, 1},
|
||||
.textColor = {0, 0, 0, 1},
|
||||
.font = font,
|
||||
.fontSize = 32 };
|
||||
}
|
||||
buttonStyle[UI_STYLE_HOT].borderColor = (mg_color){1, 0, 0, 1};
|
||||
buttonStyle[UI_STYLE_ACTIVE].borderColor = (mg_color){1, 0, 0, 1};
|
||||
buttonStyle[UI_STYLE_ACTIVE].foregroundColor = (mg_color){0.1, 0.1, 0.1, 1};
|
||||
|
||||
ui_begin_frame(windowRect.w, windowRect.h, defaultStyle);
|
||||
{
|
||||
ui_size_push(UI_AXIS_X, UI_SIZE_PIXELS, 600, 0);
|
||||
ui_size_push(UI_AXIS_Y, UI_SIZE_PIXELS, 200, 0);
|
||||
ui_push_bg_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_ANY, (mg_color){0.8, 0.8, 0.8, 1});
|
||||
ui_push_fg_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_ANY, (mg_color){0.5, 0.5, 0.5, 1});
|
||||
ui_push_border_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_ANY, (mg_color){0, 0, 1, 1});
|
||||
|
||||
for(int i=0; i<UI_STYLE_SELECTOR_COUNT; i++)
|
||||
{
|
||||
ui_style_push(i, buttonStyle[i]);
|
||||
}
|
||||
ui_push_border_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_HOT|UI_STYLE_SEL_ACTIVE, (mg_color){1, 0, 0, 1});
|
||||
ui_push_fg_color_ext(UI_STYLE_TAG_BUTTON, UI_STYLE_SEL_ACTIVE, (mg_color){0.1, 0.1, 0.1, 1});
|
||||
|
||||
ui_push_size(UI_AXIS_X, UI_SIZE_PIXELS, 600, 0);
|
||||
ui_push_size(UI_AXIS_Y, UI_SIZE_PIXELS, 200, 0);
|
||||
|
||||
ui_menu_bar("menu")
|
||||
{
|
||||
|
@ -194,8 +183,8 @@ int main()
|
|||
ui_box* container = ui_box_begin("Test", UI_FLAG_DRAW_BORDER | UI_FLAG_DRAW_BACKGROUND);
|
||||
ui_box_set_layout(container, UI_AXIS_X, UI_ALIGN_END, UI_ALIGN_CENTER);
|
||||
{
|
||||
ui_size_push(UI_AXIS_X, UI_SIZE_TEXT, 0, 0);
|
||||
ui_size_push(UI_AXIS_Y, UI_SIZE_PARENT_RATIO, 0.25, 0);
|
||||
ui_push_size(UI_AXIS_X, UI_SIZE_TEXT, 0, 0);
|
||||
ui_push_size(UI_AXIS_Y, UI_SIZE_PARENT_RATIO, 0.25, 0);
|
||||
|
||||
ui_sig sig1 = ui_button("Child1");
|
||||
if(sig1.hovering)
|
||||
|
@ -220,29 +209,29 @@ int main()
|
|||
ui_box_set_floating(block, UI_AXIS_X, 100);
|
||||
ui_box_set_floating(block, UI_AXIS_Y, 100);
|
||||
|
||||
ui_size_push(UI_AXIS_X, UI_SIZE_PIXELS, 200, 0);
|
||||
ui_size_push(UI_AXIS_Y, UI_SIZE_PIXELS, 20, 0);
|
||||
ui_push_size(UI_AXIS_X, UI_SIZE_PIXELS, 200, 0);
|
||||
ui_push_size(UI_AXIS_Y, UI_SIZE_PIXELS, 20, 0);
|
||||
|
||||
static f32 scrollValue = 0.;
|
||||
ui_scrollbar("scroll", .25, &scrollValue);
|
||||
|
||||
ui_size_pop(UI_AXIS_X);
|
||||
ui_size_pop(UI_AXIS_Y);
|
||||
ui_pop_size(UI_AXIS_X);
|
||||
ui_pop_size(UI_AXIS_Y);
|
||||
|
||||
ui_size_pop(UI_AXIS_X);
|
||||
ui_size_pop(UI_AXIS_Y);
|
||||
ui_pop_size(UI_AXIS_X);
|
||||
ui_pop_size(UI_AXIS_Y);
|
||||
|
||||
} ui_box_end();
|
||||
|
||||
ui_size_pop(UI_AXIS_X);
|
||||
ui_size_pop(UI_AXIS_Y);
|
||||
ui_pop_size(UI_AXIS_X);
|
||||
ui_pop_size(UI_AXIS_Y);
|
||||
|
||||
ui_size_push(UI_AXIS_X, UI_SIZE_PIXELS, 200, 0);
|
||||
ui_size_push(UI_AXIS_Y, UI_SIZE_PIXELS, 200, 0);
|
||||
ui_push_size(UI_AXIS_X, UI_SIZE_PIXELS, 200, 0);
|
||||
ui_push_size(UI_AXIS_Y, UI_SIZE_PIXELS, 200, 0);
|
||||
ui_panel_begin("panel");
|
||||
|
||||
ui_size_push(UI_AXIS_X, UI_SIZE_TEXT, 0, 0);
|
||||
ui_size_push(UI_AXIS_Y, UI_SIZE_TEXT, 0, 0);
|
||||
ui_push_size(UI_AXIS_X, UI_SIZE_TEXT, 0, 0);
|
||||
ui_push_size(UI_AXIS_Y, UI_SIZE_TEXT, 0, 0);
|
||||
|
||||
ui_box* b = ui_box_begin("container", 0);
|
||||
ui_box_set_size(b, UI_AXIS_X, UI_SIZE_CHILDREN, 0, 0);
|
||||
|
@ -250,19 +239,24 @@ int main()
|
|||
ui_button("Hello 1");
|
||||
ui_button("Hello 2");
|
||||
ui_button("Hello 3");
|
||||
|
||||
const u32 backingMaxSize = 4096;
|
||||
static char backing[4096];
|
||||
static str8 text = {};
|
||||
|
||||
ui_text_box_result res = ui_text_box("textbox", mem_scratch(), text);
|
||||
memcpy(backing, res.text.ptr, minimum(res.text.len, backingMaxSize));
|
||||
text = str8_from_buffer(res.text.len, backing);
|
||||
|
||||
ui_box_end();
|
||||
|
||||
ui_size_pop(UI_AXIS_X);
|
||||
ui_size_pop(UI_AXIS_Y);
|
||||
ui_pop_size(UI_AXIS_X);
|
||||
ui_pop_size(UI_AXIS_Y);
|
||||
|
||||
ui_panel_end();
|
||||
ui_size_pop(UI_AXIS_X);
|
||||
ui_size_pop(UI_AXIS_Y);
|
||||
ui_pop_size(UI_AXIS_X);
|
||||
ui_pop_size(UI_AXIS_Y);
|
||||
|
||||
for(int i=0; i<UI_STYLE_SELECTOR_COUNT; i++)
|
||||
{
|
||||
ui_style_pop(i);
|
||||
}
|
||||
|
||||
} ui_end_frame();
|
||||
|
||||
|
@ -271,6 +265,8 @@ int main()
|
|||
mg_canvas_flush(canvas);
|
||||
|
||||
mg_surface_present(surface);
|
||||
|
||||
mem_arena_clear(mem_scratch());
|
||||
}
|
||||
|
||||
mg_surface_destroy(surface);
|
||||
|
|
|
@ -3215,9 +3215,9 @@ int mg_font_get_codepoint_extents(mg_font font, utf32 codePoint, mg_text_extents
|
|||
return(0);
|
||||
}
|
||||
|
||||
mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text)
|
||||
mp_rect mg_text_bounding_box_utf32(mg_font font, f32 fontSize, str32 codePoints)
|
||||
{
|
||||
if(!text.len || !text.ptr)
|
||||
if(!codePoints.len || !codePoints.ptr)
|
||||
{
|
||||
return((mp_rect){});
|
||||
}
|
||||
|
@ -3229,7 +3229,6 @@ mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text)
|
|||
}
|
||||
|
||||
mem_arena* scratch = mem_scratch();
|
||||
str32 codePoints = utf8_push_to_codepoints(scratch, text);
|
||||
str32 glyphIndices = mg_font_push_glyph_indices(font, scratch, codePoints);
|
||||
|
||||
//NOTE(martin): find width of missing character
|
||||
|
@ -3302,6 +3301,18 @@ mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text)
|
|||
return(rect);
|
||||
}
|
||||
|
||||
mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text)
|
||||
{
|
||||
if(!text.len || !text.ptr)
|
||||
{
|
||||
return((mp_rect){});
|
||||
}
|
||||
|
||||
mem_arena* scratch = mem_scratch();
|
||||
str32 codePoints = utf8_push_to_codepoints(scratch, text);
|
||||
return(mg_text_bounding_box_utf32(font, fontSize, codePoints));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
// Transform matrix settings
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -135,6 +135,7 @@ int mg_font_get_codepoint_extents(mg_font font, utf32 codePoint, mg_text_extents
|
|||
|
||||
int mg_font_get_glyph_extents(mg_font font, str32 glyphIndices, mg_text_extents* outExtents);
|
||||
|
||||
mp_rect mg_text_bounding_box_utf32(mg_font font, f32 fontSize, str32 text);
|
||||
mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text);
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -636,7 +636,9 @@ static void mp_update_text(utf32 codepoint)
|
|||
if(text->lastUpdate != frameCounter)
|
||||
{
|
||||
text->codePoints.len = 0;
|
||||
text->lastUpdate = frameCounter;
|
||||
}
|
||||
|
||||
text->codePoints.ptr = text->backing;
|
||||
if(text->codePoints.len < MP_INPUT_TEXT_BACKING_SIZE)
|
||||
{
|
||||
|
|
89
src/ui.h
89
src/ui.h
|
@ -74,17 +74,22 @@ typedef struct ui_size
|
|||
f32 strictness;
|
||||
} ui_size;
|
||||
|
||||
typedef enum { UI_STYLE_NORMAL,
|
||||
UI_STYLE_HOT,
|
||||
UI_STYLE_ACTIVE,
|
||||
UI_STYLE_SELECTOR_COUNT } ui_style_selector;
|
||||
typedef enum { UI_STYLE_SEL_NORMAL = 1<<0,
|
||||
UI_STYLE_SEL_HOT = 1<<1,
|
||||
UI_STYLE_SEL_ACTIVE = 1<<2,
|
||||
UI_STYLE_SEL_ANY = UI_STYLE_SEL_NORMAL|UI_STYLE_SEL_HOT|UI_STYLE_SEL_ACTIVE,
|
||||
} ui_style_selector;
|
||||
|
||||
typedef u32 ui_style_tag;
|
||||
#define UI_STYLE_TAG_ANY (ui_style_tag)0
|
||||
|
||||
typedef struct ui_style
|
||||
{
|
||||
mg_color backgroundColor;
|
||||
mg_color foregroundColor;
|
||||
ui_size size[UI_AXIS_COUNT];
|
||||
mg_color bgColor;
|
||||
mg_color fgColor;
|
||||
mg_color borderColor;
|
||||
mg_color textColor;
|
||||
mg_color fontColor;
|
||||
mg_font font;
|
||||
f32 fontSize;
|
||||
f32 borderSize;
|
||||
|
@ -129,18 +134,15 @@ struct ui_box
|
|||
ui_flags flags;
|
||||
str8 string;
|
||||
|
||||
// layout
|
||||
// styling and layout
|
||||
ui_style_tag tag;
|
||||
ui_style* targetStyle;
|
||||
ui_style computedStyle;
|
||||
u32 z;
|
||||
bool floating[UI_AXIS_COUNT];
|
||||
ui_size desiredSize[UI_AXIS_COUNT];
|
||||
ui_layout layout;
|
||||
mp_rect rect;
|
||||
f32 childrenSum[2];
|
||||
|
||||
// styling
|
||||
ui_style* styles[UI_STYLE_SELECTOR_COUNT];
|
||||
ui_style computedStyle;
|
||||
ui_style_selector styleSelector;
|
||||
mp_rect rect;
|
||||
|
||||
// signals
|
||||
ui_sig* sig;
|
||||
|
@ -149,6 +151,7 @@ struct ui_box
|
|||
bool closed;
|
||||
bool parentClosed;
|
||||
bool dragging;
|
||||
bool hot;
|
||||
bool active;
|
||||
vec2 scroll;
|
||||
|
||||
|
@ -178,14 +181,50 @@ void ui_box_set_style_selector(ui_box* box, ui_style_selector selector);
|
|||
|
||||
ui_sig ui_box_sig(ui_box* box);
|
||||
|
||||
void ui_size_push(ui_axis axis, ui_size_kind kind, f32 value, f32 strictness);
|
||||
void ui_size_pop(ui_axis axis);
|
||||
void ui_style_push(ui_style_selector selector, ui_style style);
|
||||
void ui_style_pop(ui_style_selector selector);
|
||||
void ui_push_size(ui_axis axis, ui_size_kind kind, f32 value, f32 strictness);
|
||||
void ui_push_size_ext(ui_style_tag tag, ui_style_selector selector, ui_axis axis, ui_size_kind kind, f32 value, f32 strictness);
|
||||
void ui_pop_size(ui_axis axis);
|
||||
|
||||
void ui_push_bg_color(mg_color color);
|
||||
void ui_push_fg_color(mg_color color);
|
||||
void ui_push_font(mg_font font);
|
||||
void ui_push_font_size(f32 size);
|
||||
void ui_push_font_color(mg_color color);
|
||||
void ui_push_border_size(f32 size);
|
||||
void ui_push_border_color(mg_color color);
|
||||
void ui_push_roundness(f32 roundness);
|
||||
|
||||
void ui_push_bg_color_ext(ui_style_tag tag, ui_style_selector selector, mg_color color);
|
||||
void ui_push_fg_color_ext(ui_style_tag tag, ui_style_selector selector, mg_color color);
|
||||
void ui_push_font_ext(ui_style_tag tag, ui_style_selector selector, mg_font font);
|
||||
void ui_push_font_size_ext(ui_style_tag tag, ui_style_selector selector, f32 size);
|
||||
void ui_push_font_color_ext(ui_style_tag tag, ui_style_selector selector, mg_color color);
|
||||
void ui_push_border_size_ext(ui_style_tag tag, ui_style_selector selector, f32 size);
|
||||
void ui_push_border_color_ext(ui_style_tag tag, ui_style_selector selector, mg_color color);
|
||||
void ui_push_roundness_ext(ui_style_tag tag, ui_style_selector selector, f32 roundness);
|
||||
|
||||
void ui_pop_bg_color();
|
||||
void ui_pop_fg_color();
|
||||
void ui_pop_font();
|
||||
void ui_pop_font_size();
|
||||
void ui_pop_font_color();
|
||||
void ui_pop_border_size();
|
||||
void ui_pop_border_color();
|
||||
void ui_pop_roundness();
|
||||
|
||||
// Basic helpers
|
||||
ui_sig ui_label(const char* label);
|
||||
|
||||
enum {
|
||||
UI_STYLE_TAG_USER_MAX = 1<<16,
|
||||
UI_STYLE_TAG_LABEL,
|
||||
UI_STYLE_TAG_BUTTON,
|
||||
UI_STYLE_TAG_SCROLLBAR,
|
||||
UI_STYLE_TAG_PANEL,
|
||||
UI_STYLE_TAG_TOOLTIP,
|
||||
UI_STYLE_TAG_MENU
|
||||
};
|
||||
|
||||
ui_sig ui_label(const char* label);
|
||||
ui_sig ui_button(const char* label);
|
||||
ui_box* ui_scrollbar(const char* label, f32 thumbRatio, f32* scrollValue);
|
||||
|
||||
|
@ -205,6 +244,16 @@ void ui_menu_begin(const char* label);
|
|||
void ui_menu_end();
|
||||
#define ui_menu(name) defer_loop(ui_menu_begin(name), ui_menu_end())
|
||||
|
||||
typedef struct ui_text_box_result
|
||||
{
|
||||
bool changed;
|
||||
bool accepted;
|
||||
str8 text;
|
||||
|
||||
}ui_text_box_result;
|
||||
|
||||
ui_text_box_result ui_text_box(const char* name, mem_arena* arena, str8 text);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
@ -257,6 +257,57 @@ str32 str32_push_slice(mem_arena* arena, str32 s, u64 start, u64 end)
|
|||
return(str32_push_copy(arena, slice));
|
||||
}
|
||||
|
||||
void str32_list_init(str32_list* list)
|
||||
{
|
||||
ListInit(&list->list);
|
||||
list->eltCount = 0;
|
||||
list->len = 0;
|
||||
}
|
||||
|
||||
void str32_list_push(mem_arena* arena, str32_list* list, str32 str)
|
||||
{
|
||||
str32_elt* elt = mem_arena_alloc_type(arena, str32_elt);
|
||||
elt->string = str;
|
||||
ListAppend(&list->list, &elt->listElt);
|
||||
list->eltCount++;
|
||||
list->len += str.len;
|
||||
}
|
||||
|
||||
str32 str32_list_collate(mem_arena* arena, str32_list list, str32 prefix, str32 separator, str32 postfix)
|
||||
{
|
||||
str32 str = {};
|
||||
str.len = prefix.len + list.len + list.eltCount*separator.len + postfix.len;
|
||||
str.ptr = mem_arena_alloc_array(arena, u32, str.len);
|
||||
char* dst = (char*)str.ptr;
|
||||
memcpy(dst, prefix.ptr, prefix.len*sizeof(u32));
|
||||
dst += prefix.len*sizeof(u32);
|
||||
|
||||
str32_elt* elt = ListFirstEntry(&list.list, str32_elt, listElt);
|
||||
if(elt)
|
||||
{
|
||||
memcpy(dst, elt->string.ptr, elt->string.len*sizeof(u32));
|
||||
dst += elt->string.len*sizeof(u32);
|
||||
elt = ListNextEntry(&list.list, elt, str32_elt, listElt);
|
||||
}
|
||||
|
||||
for( ; elt != 0; elt = ListNextEntry(&list.list, elt, str32_elt, listElt))
|
||||
{
|
||||
memcpy(dst, separator.ptr, separator.len*sizeof(u32));
|
||||
dst += separator.len*sizeof(u32);
|
||||
memcpy(dst, elt->string.ptr, elt->string.len*sizeof(u32));
|
||||
dst += elt->string.len*sizeof(u32);
|
||||
}
|
||||
memcpy(dst, postfix.ptr, postfix.len*sizeof(u32));
|
||||
return(str);
|
||||
}
|
||||
|
||||
str32 str32_list_join(mem_arena* arena, str32_list list)
|
||||
{
|
||||
str32 empty = {.len = 0, .ptr = 0};
|
||||
return(str32_list_collate(arena, list, empty, empty, empty));
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Paths helpers
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
@ -82,6 +82,23 @@ str32 str32_push_buffer(mem_arena* arena, u64 len, u32* buffer);
|
|||
str32 str32_push_copy(mem_arena* arena, str32 s);
|
||||
str32 str32_push_slice(mem_arena* arena, str32 s, u64 start, u64 end);
|
||||
|
||||
typedef struct str32_elt
|
||||
{
|
||||
list_elt listElt;
|
||||
str32 string;
|
||||
} str32_elt;
|
||||
|
||||
typedef struct str32_list
|
||||
{
|
||||
list_info list;
|
||||
u64 eltCount;
|
||||
u64 len;
|
||||
} str32_list;
|
||||
|
||||
void str32_list_push(mem_arena* arena, str32_list* list, str32 str);
|
||||
str32 str32_list_join(mem_arena* arena, str32_list list);
|
||||
str32_list str32_split(mem_arena* arena, str32 str, str32_list separators);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Paths helpers
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
9
todo.txt
9
todo.txt
|
@ -3,14 +3,19 @@
|
|||
Shortlist
|
||||
---------
|
||||
[x] let pass flat args in ui_size_push() and ui_box_set_size()
|
||||
[>>] separate style stacks
|
||||
[x] separate style stacks
|
||||
[x] animation time stack
|
||||
[>] margins? as part of size, or different styling stack?
|
||||
[>] animation time stack
|
||||
|
||||
[ ] Let build code set target style directly, and animate from current to target
|
||||
[ ] filter styles stack by tag
|
||||
[ ] image backgrounds/gradients?
|
||||
[ ] animating open/close widgets?
|
||||
|
||||
[.] Text box widget
|
||||
[ ] Draw selection
|
||||
[ ] Set cursor on click
|
||||
[ ] Scroll to cursor
|
||||
|
||||
Canvas Drawing
|
||||
--------------
|
||||
|
|
Loading…
Reference in New Issue