From a8cbc91bf6f3d7dc52912a2b6b69c1b27ab8bf70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Tue, 28 Nov 2023 16:37:20 +0100 Subject: [PATCH] add gui_label and variants --- bind/v4k.lua | 12 +++++++++ demos/99-gui.c | 6 ++--- engine/joint/v4k.h | 56 ++++++++++++++++++++++++++++++++++++++---- engine/split/v4k_gui.c | 50 +++++++++++++++++++++++++++++++++---- engine/split/v4k_gui.h | 6 +++++ engine/v4k.c | 50 +++++++++++++++++++++++++++++++++---- engine/v4k.h | 6 +++++ 7 files changed, 168 insertions(+), 18 deletions(-) diff --git a/bind/v4k.lua b/bind/v4k.lua index 76e3cd0..1a3973a 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -1537,12 +1537,21 @@ ffi.cdef([[ //lcpp INF [0000] vec4: macro name but used as C declaration in:API void gui_rect_id(int id, vec4 rect, const char *skin); //lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC void gui_rect_id(int id, vec4 rect, const char *skin); //lcpp INF [0000] vec4: macro name but used as C declaration in: void gui_rect_id(int id, vec4 rect, const char *skin); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API void gui_label_id(int id, const char *text, vec4 rect); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC void gui_label_id(int id, const char *text, vec4 rect); +//lcpp INF [0000] vec4: macro name but used as C declaration in: void gui_label_id(int id, const char *text, vec4 rect); //lcpp INF [0000] vec4: macro name but used as C declaration in:API bool gui_button_id(int id, vec4 rect, const char *skin); //lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC bool gui_button_id(int id, vec4 rect, const char *skin); //lcpp INF [0000] vec4: macro name but used as C declaration in: bool gui_button_id(int id, vec4 rect, const char *skin); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin); +//lcpp INF [0000] vec4: macro name but used as C declaration in: bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin); //lcpp INF [0000] vec4: macro name but used as C declaration in:API bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, float step, float *value); //lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, float step, float *value); //lcpp INF [0000] vec4: macro name but used as C declaration in: bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, float step, float *value); +//lcpp INF [0000] vec4: macro name but used as C declaration in:API bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value); +//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value); +//lcpp INF [0000] vec4: macro name but used as C declaration in: bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value); //lcpp INF [0000] test: macro name but used as C declaration in:API int (test)(const char *file, int line, const char *expr, bool result); //lcpp INF [0000] test: macro name but used as C declaration in:STATIC int (test)(const char *file, int line, const char *expr, bool result); //lcpp INF [0000] test: macro name but used as C declaration in: int (test)(const char *file, int line, const char *expr, bool result); @@ -3329,8 +3338,11 @@ void *userdata; bool gui_ismouseinrect(const char *skin, vec4 rect); void gui_panel_id(int id, vec4 rect, const char *skin); void gui_rect_id(int id, vec4 rect, const char *skin); + void gui_label_id(int id, const char *text, vec4 rect); bool gui_button_id(int id, vec4 rect, const char *skin); + bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin); bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, float step, float *value); + bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value); void gui_panel_end(); void gui_popskin(); typedef struct skinned_t { diff --git a/demos/99-gui.c b/demos/99-gui.c index 3f5d8d0..4933586 100644 --- a/demos/99-gui.c +++ b/demos/99-gui.c @@ -3,7 +3,7 @@ int main() { window_create(65.0, 0 ); - gui_pushskin(gui_skinned("golden.ase", 1.0f)); + gui_pushskin(gui_skinned("golden.ase", 4.0f)); skinned_t *skinned = C_CAST(skinned_t*, gui_userdata()); vec4 pos = vec4(400,400,100, 30); @@ -36,7 +36,7 @@ int main() { // gui_panel(panel_pos, "panel"); - if (gui_button(pos, 0)) { + if (gui_button_label(FONT_H1 "PRESS", pos, 0)) { printf("%s\n", "Button pressed!"); } @@ -53,7 +53,7 @@ int main() { vec2 slider_size = gui_getskinsize("slider"); gui_slider(vec4(60, 480, 80*skinned->scale, 1), 0, 0.0f, 15.0f, 1.0f, &testval); - gui_slider(vec4(60, 480+slider_size.y+10, 120*skinned->scale, 1), 0, -5.0f, 20.0f, 0.0f, &testval2); + gui_slider_label(va(FONT_H1 "%.02f", testval2), vec4(60, 480+slider_size.y+10, 120*skinned->scale, 1), 0, -5.0f, 20.0f, 0.0f, &testval2); gui_panel_end(); } diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index 1f41fa4..5d0013c 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -18132,16 +18132,22 @@ API bool gui_ismouseinrect(const char *skin, vec4 rect); // -- API void gui_panel_id(int id, vec4 rect, const char *skin); API void gui_rect_id(int id, vec4 rect, const char *skin); +API void gui_label_id(int id, const char *text, vec4 rect); API bool gui_button_id(int id, vec4 rect, const char *skin); +API bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin); API bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, float step, float *value); +API bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value); API void gui_panel_end(); API void gui_popskin(); // helpers #define gui_panel(...) gui_panel_id(__LINE__, __VA_ARGS__) #define gui_rect(...) gui_rect_id(__LINE__, __VA_ARGS__) +#define gui_label(...) gui_label_id(__LINE__, __VA_ARGS__) #define gui_button(...) gui_button_id(__LINE__, __VA_ARGS__) +#define gui_button_label(...) gui_button_label_id(__LINE__, __VA_ARGS__) #define gui_slider(...) gui_slider_id(__LINE__, __VA_ARGS__) +#define gui_slider_label(...) gui_slider_label_id(__LINE__, __VA_ARGS__) // default renderers @@ -358962,6 +358968,7 @@ static __thread array(guiskin_t) skins=0; static __thread guiskin_t *last_skin=0; static __thread map(int, gui_state_t) ctl_states=0; //@leak static __thread array(vec4) scissor_rects=0; +static __thread bool any_widget_used=0; void gui_pushskin(guiskin_t skin) { array_push(skins, skin); @@ -359023,17 +359030,19 @@ bool gui_button_id(int id, vec4 r, const char *skin) { gui_state_t *entry = gui_getstate(id); bool was_clicked=0; - char *btn = va("%s%s", skin?skin:"button", entry->held?"_press":entry->hover?"_hover":""); - if (gui_ismouseinrect(btn, r)) { + skin=skin?skin:"button"; + char *btn = va("%s%s", skin, entry->held?"_press":entry->hover?"_hover":""); + if (gui_ismouseinrect(btn, r) && !any_widget_used) { if (input_up(MOUSE_L) && entry->held) { was_clicked=1; } - entry->held = input_held(MOUSE_L); + any_widget_used = entry->held = input_held(MOUSE_L); entry->hover = true; } else if (input_up(MOUSE_L) && entry->held) { entry->held = false; + any_widget_used = false; } else { entry->hover = false; @@ -359044,6 +359053,21 @@ bool gui_button_id(int id, vec4 r, const char *skin) { return was_clicked; } +bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin) { + bool state = gui_button_id(id, rect, skin); + vec2 buttonsize={0}; + skin=skin?skin:"button"; + if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &buttonsize); + + vec2 textsize = font_rect(text); + vec2 pos; + pos.x = rect.x + max(buttonsize.x*.5f, rect.z*.5f) - textsize.x*.5f; + pos.y = rect.y + max(buttonsize.y*.5f, rect.w*.5f) - textsize.y*.5f; + font_goto(pos.x, pos.y); + font_print(text); + return state; +} + static float slider2posx(float min, float max, float value, float step, float w) { float norm = value - min; @@ -359066,12 +359090,13 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl skin = skin?skin:"slider"; char *cursorskin = va("%s_cursor%s", skin, entry->held?"_press":entry->hover?"_hover":""); - if (gui_ismouseinrect(skin, rect)) { - entry->held = input_held(MOUSE_L); + if (gui_ismouseinrect(skin, rect) && !any_widget_used) { + any_widget_used = entry->held = input_held(MOUSE_L); entry->hover = true; } else if (input_up(MOUSE_L) && entry->held) { entry->held = false; + any_widget_used = false; } else { entry->hover = false; @@ -359100,11 +359125,31 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl return entry->held && (old_value!=*value); } +bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value) { + bool state = gui_slider_id(id, rect, skin, min, max, step, value); + vec2 slidersize={0}; + skin=skin?skin:"slider"; + + vec2 textsize = font_rect(text); + vec2 pos; + pos.x = rect.x + max(slidersize.x, rect.z) + 8 /*padding*/; + pos.y = rect.y - max(slidersize.y*.5f, rect.w*.5f) + textsize.y*.5f; + font_goto(pos.x, pos.y); + font_print(text); + return state; +} + void gui_rect_id(int id, vec4 r, const char *skin) { (void)id; if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, r); } +void gui_label_id(int id, const char *text, vec4 rect) { + (void)id; + font_goto(rect.x, rect.y); + font_print(text); +} + /* skinned */ static @@ -359116,6 +359161,7 @@ void skinned_free(void* userdata) { static atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) { + if (!name) return NULL; for (int i = 0; i < array_count(a->slices); i++) if (!strcmp(quark_string(&a->db, a->slices[i].name), name)) return &a->slice_frames[a->slices[i].frames[0]]; diff --git a/engine/split/v4k_gui.c b/engine/split/v4k_gui.c index 77df43e..750b0b7 100644 --- a/engine/split/v4k_gui.c +++ b/engine/split/v4k_gui.c @@ -100,6 +100,7 @@ static __thread array(guiskin_t) skins=0; static __thread guiskin_t *last_skin=0; static __thread map(int, gui_state_t) ctl_states=0; //@leak static __thread array(vec4) scissor_rects=0; +static __thread bool any_widget_used=0; void gui_pushskin(guiskin_t skin) { array_push(skins, skin); @@ -161,17 +162,19 @@ bool gui_button_id(int id, vec4 r, const char *skin) { gui_state_t *entry = gui_getstate(id); bool was_clicked=0; - char *btn = va("%s%s", skin?skin:"button", entry->held?"_press":entry->hover?"_hover":""); - if (gui_ismouseinrect(btn, r)) { + skin=skin?skin:"button"; + char *btn = va("%s%s", skin, entry->held?"_press":entry->hover?"_hover":""); + if (gui_ismouseinrect(btn, r) && !any_widget_used) { if (input_up(MOUSE_L) && entry->held) { was_clicked=1; } - entry->held = input_held(MOUSE_L); + any_widget_used = entry->held = input_held(MOUSE_L); entry->hover = true; } else if (input_up(MOUSE_L) && entry->held) { entry->held = false; + any_widget_used = false; } else { entry->hover = false; @@ -182,6 +185,21 @@ bool gui_button_id(int id, vec4 r, const char *skin) { return was_clicked; } +bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin) { + bool state = gui_button_id(id, rect, skin); + vec2 buttonsize={0}; + skin=skin?skin:"button"; + if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &buttonsize); + + vec2 textsize = font_rect(text); + vec2 pos; + pos.x = rect.x + max(buttonsize.x*.5f, rect.z*.5f) - textsize.x*.5f; + pos.y = rect.y + max(buttonsize.y*.5f, rect.w*.5f) - textsize.y*.5f; + font_goto(pos.x, pos.y); + font_print(text); + return state; +} + static float slider2posx(float min, float max, float value, float step, float w) { float norm = value - min; @@ -204,12 +222,13 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl skin = skin?skin:"slider"; char *cursorskin = va("%s_cursor%s", skin, entry->held?"_press":entry->hover?"_hover":""); - if (gui_ismouseinrect(skin, rect)) { - entry->held = input_held(MOUSE_L); + if (gui_ismouseinrect(skin, rect) && !any_widget_used) { + any_widget_used = entry->held = input_held(MOUSE_L); entry->hover = true; } else if (input_up(MOUSE_L) && entry->held) { entry->held = false; + any_widget_used = false; } else { entry->hover = false; @@ -238,11 +257,31 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl return entry->held && (old_value!=*value); } +bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value) { + bool state = gui_slider_id(id, rect, skin, min, max, step, value); + vec2 slidersize={0}; + skin=skin?skin:"slider"; + + vec2 textsize = font_rect(text); + vec2 pos; + pos.x = rect.x + max(slidersize.x, rect.z) + 8 /*padding*/; + pos.y = rect.y - max(slidersize.y*.5f, rect.w*.5f) + textsize.y*.5f; + font_goto(pos.x, pos.y); + font_print(text); + return state; +} + void gui_rect_id(int id, vec4 r, const char *skin) { (void)id; if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, r); } +void gui_label_id(int id, const char *text, vec4 rect) { + (void)id; + font_goto(rect.x, rect.y); + font_print(text); +} + /* skinned */ static @@ -254,6 +293,7 @@ void skinned_free(void* userdata) { static atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) { + if (!name) return NULL; for (int i = 0; i < array_count(a->slices); i++) if (!strcmp(quark_string(&a->db, a->slices[i].name), name)) return &a->slice_frames[a->slices[i].frames[0]]; diff --git a/engine/split/v4k_gui.h b/engine/split/v4k_gui.h index 0353c86..4d6b40c 100644 --- a/engine/split/v4k_gui.h +++ b/engine/split/v4k_gui.h @@ -17,16 +17,22 @@ API bool gui_ismouseinrect(const char *skin, vec4 rect); // -- API void gui_panel_id(int id, vec4 rect, const char *skin); API void gui_rect_id(int id, vec4 rect, const char *skin); +API void gui_label_id(int id, const char *text, vec4 rect); API bool gui_button_id(int id, vec4 rect, const char *skin); +API bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin); API bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, float step, float *value); +API bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value); API void gui_panel_end(); API void gui_popskin(); // helpers #define gui_panel(...) gui_panel_id(__LINE__, __VA_ARGS__) #define gui_rect(...) gui_rect_id(__LINE__, __VA_ARGS__) +#define gui_label(...) gui_label_id(__LINE__, __VA_ARGS__) #define gui_button(...) gui_button_id(__LINE__, __VA_ARGS__) +#define gui_button_label(...) gui_button_label_id(__LINE__, __VA_ARGS__) #define gui_slider(...) gui_slider_id(__LINE__, __VA_ARGS__) +#define gui_slider_label(...) gui_slider_label_id(__LINE__, __VA_ARGS__) // default renderers diff --git a/engine/v4k.c b/engine/v4k.c index 2a31c52..8db95b5 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -11110,6 +11110,7 @@ static __thread array(guiskin_t) skins=0; static __thread guiskin_t *last_skin=0; static __thread map(int, gui_state_t) ctl_states=0; //@leak static __thread array(vec4) scissor_rects=0; +static __thread bool any_widget_used=0; void gui_pushskin(guiskin_t skin) { array_push(skins, skin); @@ -11171,17 +11172,19 @@ bool gui_button_id(int id, vec4 r, const char *skin) { gui_state_t *entry = gui_getstate(id); bool was_clicked=0; - char *btn = va("%s%s", skin?skin:"button", entry->held?"_press":entry->hover?"_hover":""); - if (gui_ismouseinrect(btn, r)) { + skin=skin?skin:"button"; + char *btn = va("%s%s", skin, entry->held?"_press":entry->hover?"_hover":""); + if (gui_ismouseinrect(btn, r) && !any_widget_used) { if (input_up(MOUSE_L) && entry->held) { was_clicked=1; } - entry->held = input_held(MOUSE_L); + any_widget_used = entry->held = input_held(MOUSE_L); entry->hover = true; } else if (input_up(MOUSE_L) && entry->held) { entry->held = false; + any_widget_used = false; } else { entry->hover = false; @@ -11192,6 +11195,21 @@ bool gui_button_id(int id, vec4 r, const char *skin) { return was_clicked; } +bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin) { + bool state = gui_button_id(id, rect, skin); + vec2 buttonsize={0}; + skin=skin?skin:"button"; + if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &buttonsize); + + vec2 textsize = font_rect(text); + vec2 pos; + pos.x = rect.x + max(buttonsize.x*.5f, rect.z*.5f) - textsize.x*.5f; + pos.y = rect.y + max(buttonsize.y*.5f, rect.w*.5f) - textsize.y*.5f; + font_goto(pos.x, pos.y); + font_print(text); + return state; +} + static float slider2posx(float min, float max, float value, float step, float w) { float norm = value - min; @@ -11214,12 +11232,13 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl skin = skin?skin:"slider"; char *cursorskin = va("%s_cursor%s", skin, entry->held?"_press":entry->hover?"_hover":""); - if (gui_ismouseinrect(skin, rect)) { - entry->held = input_held(MOUSE_L); + if (gui_ismouseinrect(skin, rect) && !any_widget_used) { + any_widget_used = entry->held = input_held(MOUSE_L); entry->hover = true; } else if (input_up(MOUSE_L) && entry->held) { entry->held = false; + any_widget_used = false; } else { entry->hover = false; @@ -11248,11 +11267,31 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl return entry->held && (old_value!=*value); } +bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value) { + bool state = gui_slider_id(id, rect, skin, min, max, step, value); + vec2 slidersize={0}; + skin=skin?skin:"slider"; + + vec2 textsize = font_rect(text); + vec2 pos; + pos.x = rect.x + max(slidersize.x, rect.z) + 8 /*padding*/; + pos.y = rect.y - max(slidersize.y*.5f, rect.w*.5f) + textsize.y*.5f; + font_goto(pos.x, pos.y); + font_print(text); + return state; +} + void gui_rect_id(int id, vec4 r, const char *skin) { (void)id; if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, r); } +void gui_label_id(int id, const char *text, vec4 rect) { + (void)id; + font_goto(rect.x, rect.y); + font_print(text); +} + /* skinned */ static @@ -11264,6 +11303,7 @@ void skinned_free(void* userdata) { static atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) { + if (!name) return NULL; for (int i = 0; i < array_count(a->slices); i++) if (!strcmp(quark_string(&a->db, a->slices[i].name), name)) return &a->slice_frames[a->slices[i].frames[0]]; diff --git a/engine/v4k.h b/engine/v4k.h index 23603bc..a4e6d53 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -4199,16 +4199,22 @@ API bool gui_ismouseinrect(const char *skin, vec4 rect); // -- API void gui_panel_id(int id, vec4 rect, const char *skin); API void gui_rect_id(int id, vec4 rect, const char *skin); +API void gui_label_id(int id, const char *text, vec4 rect); API bool gui_button_id(int id, vec4 rect, const char *skin); +API bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin); API bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, float step, float *value); +API bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin, float min, float max, float step, float *value); API void gui_panel_end(); API void gui_popskin(); // helpers #define gui_panel(...) gui_panel_id(__LINE__, __VA_ARGS__) #define gui_rect(...) gui_rect_id(__LINE__, __VA_ARGS__) +#define gui_label(...) gui_label_id(__LINE__, __VA_ARGS__) #define gui_button(...) gui_button_id(__LINE__, __VA_ARGS__) +#define gui_button_label(...) gui_button_label_id(__LINE__, __VA_ARGS__) #define gui_slider(...) gui_slider_id(__LINE__, __VA_ARGS__) +#define gui_slider_label(...) gui_slider_label_id(__LINE__, __VA_ARGS__) // default renderers