diff --git a/nuklear.h b/nuklear.h index 854fe80..10f01b8 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 6a30b39..53a5d25 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 8c26c59..78c15f1 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);