From 06c2338f0153b66f340889e8abaee04bdf46d425 Mon Sep 17 00:00:00 2001 From: JS Deck Date: Wed, 11 Sep 2024 19:08:35 -0300 Subject: [PATCH 1/4] Fix property edit field mouse click activation when it's earlier in the window --- nuklear.h | 14 +++++++------- src/nuklear_property.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/nuklear.h b/nuklear.h index 19553b418..622d4d55e 100644 --- a/nuklear.h +++ b/nuklear.h @@ -3834,11 +3834,11 @@ NK_API struct nk_vec2 nk_rect_size(struct nk_rect); NK_API int nk_strlen(const char *str); NK_API int nk_stricmp(const char *s1, const char *s2); NK_API int nk_stricmpn(const char *s1, const char *s2, int n); -NK_API int nk_strtoi(const char *str, const char **endptr); -NK_API float nk_strtof(const char *str, const char **endptr); +NK_API int nk_strtoi(const char *str, char **endptr); +NK_API float nk_strtof(const char *str, char **endptr); #ifndef NK_STRTOD #define NK_STRTOD nk_strtod -NK_API double nk_strtod(const char *str, const char **endptr); +NK_API double nk_strtod(const char *str, char **endptr); #endif NK_API int nk_strfilter(const char *text, const char *regexp); NK_API int nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score); @@ -6753,7 +6753,7 @@ nk_strlen(const char *str) return siz; } NK_API int -nk_strtoi(const char *str, const char **endptr) +nk_strtoi(const char *str, char **endptr) { int neg = 1; const char *p = str; @@ -6777,7 +6777,7 @@ nk_strtoi(const char *str, const char **endptr) return neg*value; } NK_API double -nk_strtod(const char *str, const char **endptr) +nk_strtod(const char *str, char **endptr) { double m; double neg = 1.0; @@ -6834,7 +6834,7 @@ nk_strtod(const char *str, const char **endptr) return number; } NK_API float -nk_strtof(const char *str, const char **endptr) +nk_strtof(const char *str, char **endptr) { float float_value; double double_value; @@ -28869,7 +28869,7 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant select_end, &style->property, filter, in, style->font, &ctx->text_edit, ctx->button_behavior); - if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) { + if (in && *state != NK_PROPERTY_DEFAULT && !(win->property.active && hash == win->property.name)) { /* current property is now hot */ win->property.active = 1; NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len); diff --git a/src/nuklear_property.c b/src/nuklear_property.c index 4386b0dd1..8c26c59ad 100644 --- a/src/nuklear_property.c +++ b/src/nuklear_property.c @@ -395,7 +395,7 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant select_end, &style->property, filter, in, style->font, &ctx->text_edit, ctx->button_behavior); - if (in && *state != NK_PROPERTY_DEFAULT && !win->property.active) { + if (in && *state != NK_PROPERTY_DEFAULT && !(win->property.active && hash == win->property.name)) { /* current property is now hot */ win->property.active = 1; NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len); From 540342b12bc4f6300dafa9c60a9e9bf6851dfc4b Mon Sep 17 00:00:00 2001 From: JS Deck Date: Wed, 11 Sep 2024 19:33:36 -0300 Subject: [PATCH 2/4] Add cast to nk_strtoi and nk_strtod --- src/nuklear_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nuklear_util.c b/src/nuklear_util.c index 364753b2c..20f93229e 100644 --- a/src/nuklear_util.c +++ b/src/nuklear_util.c @@ -161,7 +161,7 @@ nk_strtoi(const char *str, char **endptr) p++; } if (endptr) - *endptr = p; + *endptr = (char *)p; return neg*value; } NK_API double @@ -218,7 +218,7 @@ nk_strtod(const char *str, char **endptr) } number = value * neg; if (endptr) - *endptr = p; + *endptr = (char *)p; return number; } NK_API float From ff43861671c92fc36944cacd09e4d12194d31eef Mon Sep 17 00:00:00 2001 From: JS Deck Date: Wed, 11 Sep 2024 19:34:38 -0300 Subject: [PATCH 3/4] Update nuklear.h with paq.sh --- nuklear.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nuklear.h b/nuklear.h index 622d4d55e..854fe80b9 100644 --- a/nuklear.h +++ b/nuklear.h @@ -6773,7 +6773,7 @@ nk_strtoi(const char *str, char **endptr) p++; } if (endptr) - *endptr = p; + *endptr = (char *)p; return neg*value; } NK_API double @@ -6830,7 +6830,7 @@ nk_strtod(const char *str, char **endptr) } number = value * neg; if (endptr) - *endptr = p; + *endptr = (char *)p; return number; } NK_API float From 29b5ca2fda889242a62d97c083d4e0031258d5f7 Mon Sep 17 00:00:00 2001 From: JS Deck Date: Sun, 15 Sep 2024 00:14:23 -0300 Subject: [PATCH 4/4] Fix property edit field value would be discarded on focus lost when clicking on an earlier property --- nuklear.h | 68 +++++++++++++++++++++++++++++------------- src/nuklear.h | 4 +++ src/nuklear_property.c | 64 ++++++++++++++++++++++++++------------- 3 files changed, 94 insertions(+), 42 deletions(-) diff --git a/nuklear.h b/nuklear.h index 854fe80b9..10f01b8ad 100644 --- a/nuklear.h +++ b/nuklear.h @@ -5593,6 +5593,10 @@ struct nk_property_state { unsigned int seq; unsigned int old; int state; + int prev_state; + nk_hash prev_name; + char prev_buffer[NK_MAX_NUMBER_BUFFER]; + int prev_length; }; struct nk_window { @@ -28584,6 +28588,28 @@ nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property * nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font); } } +NK_INTERN void +nk_property_save(struct nk_property_variant *variant, char *buffer, int len) +{ + buffer[len] = '\0'; + switch (variant->kind) { + default: break; + case NK_PROPERTY_INT: + variant->value.i = nk_strtoi(buffer, 0); + variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i); + break; + case NK_PROPERTY_FLOAT: + nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); + variant->value.f = nk_strtof(buffer, 0); + variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f); + break; + case NK_PROPERTY_DOUBLE: + nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); + variant->value.d = nk_strtod(buffer, 0); + variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d); + break; + } +} NK_LIB void nk_do_property(nk_flags *ws, struct nk_command_buffer *out, struct nk_rect property, @@ -28707,7 +28733,7 @@ nk_do_property(nk_flags *ws, variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d); break; } } - if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) { + if (!old && (*state == NK_PROPERTY_EDIT)) { /* property has been activated so setup buffer */ NK_MEMCPY(buffer, dst, (nk_size)*length); *cursor = nk_utf_len(buffer, *length); @@ -28742,24 +28768,7 @@ nk_do_property(nk_flags *ws, if (active && !text_edit->active) { /* property is now not active so convert edit text to value*/ *state = NK_PROPERTY_DEFAULT; - buffer[*len] = '\0'; - switch (variant->kind) { - default: break; - case NK_PROPERTY_INT: - variant->value.i = nk_strtoi(buffer, 0); - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i); - break; - case NK_PROPERTY_FLOAT: - nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); - variant->value.f = nk_strtof(buffer, 0); - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f); - break; - case NK_PROPERTY_DOUBLE: - nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); - variant->value.d = nk_strtod(buffer, 0); - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d); - break; - } + nk_property_save(variant, buffer, *len); } } NK_LIB struct nk_property_variant @@ -28807,6 +28816,7 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant struct nk_rect bounds; enum nk_widget_layout_states s; + nk_bool hot; int *state = 0; nk_hash hash = 0; @@ -28816,6 +28826,7 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant int *select_begin = 0; int *select_end = 0; int old_state; + int prev_state; char dummy_buffer[NK_MAX_NUMBER_BUFFER]; int dummy_state = NK_PROPERTY_DEFAULT; @@ -28842,8 +28853,15 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant name++; /* special number hash */ } else hash = nk_murmur_hash(name, (int)nk_strlen(name), 42); + /* check if property is previously hot */ + if (win->property.prev_state == NK_PROPERTY_EDIT && hash == win->property.prev_name) { + nk_property_save(variant, win->property.prev_buffer, win->property.prev_length); + win->property.prev_state = NK_PROPERTY_DEFAULT; + } + /* check if property is currently hot item */ - if (win->property.active && hash == win->property.name) { + hot = win->property.active && hash == win->property.name; + if (hot) { buffer = win->property.buffer; len = &win->property.length; cursor = &win->property.cursor; @@ -28861,6 +28879,7 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant /* execute property widget */ old_state = *state; + prev_state = win->property.state; ctx->text_edit.clip = ctx->clip; in = ((s == NK_WIDGET_ROM && !win->property.active) || layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED) ? 0 : &ctx->input; @@ -28869,7 +28888,14 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant select_end, &style->property, filter, in, style->font, &ctx->text_edit, ctx->button_behavior); - if (in && *state != NK_PROPERTY_DEFAULT && !(win->property.active && hash == win->property.name)) { + if (in && *state != NK_PROPERTY_DEFAULT && !hot) { + /* another property was active */ + if (win->property.active /* && hash != win->property.name */) { + win->property.prev_state = prev_state; + win->property.prev_name = win->property.name; + win->property.prev_length = win->property.length; + NK_MEMCPY(win->property.prev_buffer, win->property.buffer, win->property.length); + } /* current property is now hot */ win->property.active = 1; NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len); diff --git a/src/nuklear.h b/src/nuklear.h index 6a30b3947..53a5d25ba 100644 --- a/src/nuklear.h +++ b/src/nuklear.h @@ -5371,6 +5371,10 @@ struct nk_property_state { unsigned int seq; unsigned int old; int state; + int prev_state; + nk_hash prev_name; + char prev_buffer[NK_MAX_NUMBER_BUFFER]; + int prev_length; }; struct nk_window { diff --git a/src/nuklear_property.c b/src/nuklear_property.c index 8c26c59ad..78c15f194 100644 --- a/src/nuklear_property.c +++ b/src/nuklear_property.c @@ -110,6 +110,28 @@ nk_draw_property(struct nk_command_buffer *out, const struct nk_style_property * nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font); } } +NK_INTERN void +nk_property_save(struct nk_property_variant *variant, char *buffer, int len) +{ + buffer[len] = '\0'; + switch (variant->kind) { + default: break; + case NK_PROPERTY_INT: + variant->value.i = nk_strtoi(buffer, 0); + variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i); + break; + case NK_PROPERTY_FLOAT: + nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); + variant->value.f = nk_strtof(buffer, 0); + variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f); + break; + case NK_PROPERTY_DOUBLE: + nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); + variant->value.d = nk_strtod(buffer, 0); + variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d); + break; + } +} NK_LIB void nk_do_property(nk_flags *ws, struct nk_command_buffer *out, struct nk_rect property, @@ -233,7 +255,7 @@ nk_do_property(nk_flags *ws, variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d); break; } } - if (old != NK_PROPERTY_EDIT && (*state == NK_PROPERTY_EDIT)) { + if (!old && (*state == NK_PROPERTY_EDIT)) { /* property has been activated so setup buffer */ NK_MEMCPY(buffer, dst, (nk_size)*length); *cursor = nk_utf_len(buffer, *length); @@ -268,24 +290,7 @@ nk_do_property(nk_flags *ws, if (active && !text_edit->active) { /* property is now not active so convert edit text to value*/ *state = NK_PROPERTY_DEFAULT; - buffer[*len] = '\0'; - switch (variant->kind) { - default: break; - case NK_PROPERTY_INT: - variant->value.i = nk_strtoi(buffer, 0); - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i); - break; - case NK_PROPERTY_FLOAT: - nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); - variant->value.f = nk_strtof(buffer, 0); - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f); - break; - case NK_PROPERTY_DOUBLE: - nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); - variant->value.d = nk_strtod(buffer, 0); - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d); - break; - } + nk_property_save(variant, buffer, *len); } } NK_LIB struct nk_property_variant @@ -333,6 +338,7 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant struct nk_rect bounds; enum nk_widget_layout_states s; + nk_bool hot; int *state = 0; nk_hash hash = 0; @@ -342,6 +348,7 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant int *select_begin = 0; int *select_end = 0; int old_state; + int prev_state; char dummy_buffer[NK_MAX_NUMBER_BUFFER]; int dummy_state = NK_PROPERTY_DEFAULT; @@ -368,8 +375,15 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant name++; /* special number hash */ } else hash = nk_murmur_hash(name, (int)nk_strlen(name), 42); + /* check if property is previously hot */ + if (win->property.prev_state == NK_PROPERTY_EDIT && hash == win->property.prev_name) { + nk_property_save(variant, win->property.prev_buffer, win->property.prev_length); + win->property.prev_state = NK_PROPERTY_DEFAULT; + } + /* check if property is currently hot item */ - if (win->property.active && hash == win->property.name) { + hot = win->property.active && hash == win->property.name; + if (hot) { buffer = win->property.buffer; len = &win->property.length; cursor = &win->property.cursor; @@ -387,6 +401,7 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant /* execute property widget */ old_state = *state; + prev_state = win->property.state; ctx->text_edit.clip = ctx->clip; in = ((s == NK_WIDGET_ROM && !win->property.active) || layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED) ? 0 : &ctx->input; @@ -395,7 +410,14 @@ nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant select_end, &style->property, filter, in, style->font, &ctx->text_edit, ctx->button_behavior); - if (in && *state != NK_PROPERTY_DEFAULT && !(win->property.active && hash == win->property.name)) { + if (in && *state != NK_PROPERTY_DEFAULT && !hot) { + /* another property was active */ + if (win->property.active /* && hash != win->property.name */) { + win->property.prev_state = prev_state; + win->property.prev_name = win->property.name; + win->property.prev_length = win->property.length; + NK_MEMCPY(win->property.prev_buffer, win->property.buffer, win->property.length); + } /* current property is now hot */ win->property.active = 1; NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len);