a8ef3db45d4e9036ed21c9c0608d14c6ce17c725 — octaspire 5 months ago 1bab7a7 v0.471.0
Nuklear plugin: add 'nuklear-edit-string', fix two layout functions

* Add function 'nuklear-edit-string' for showing
  text input widgets.

* Fix two layout functions: 'nuklear-layout-row-dynamic'
  and 'nuklear-layout-row-static'. Some of the arguments
  were assigned incorrectly in those functions.

* Add internal helper function for setting the contents of
  a Dern value as text (string or symbol) type.

* Add internal helper function for getting an element from
  a Dern vector as a string value or (unpushed) error,
  if the index is not valid or the value has
  incorrect type.

* Fix naming of one internal helper function to have
  '_const' in the end. Add also a non-const version
  of that same function.
M dev/include/octaspire/dern/octaspire_dern_config.h => dev/include/octaspire/dern/octaspire_dern_config.h +1 -1
@@ 18,7 18,7 @@ #define OCTASPIRE_DERN_CONFIG_H
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "0"
- #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "470"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "471"
  #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "0"
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_STR "Octaspire Dern version " \

M dev/include/octaspire/dern/octaspire_dern_value.h => dev/include/octaspire/dern/octaspire_dern_value.h +22 -1
@@ 563,7 563,14 @@ char const *octaspire_dern_value_as_text_get_c_string(
      octaspire_dern_value_t const * const self);
  
- octaspire_string_t const *octaspire_dern_value_as_text_get_string(
+ bool octaspire_dern_value_as_text_set_c_string(
+     octaspire_dern_value_t * const self,
+     char const * const str);
+ 
+ octaspire_string_t *octaspire_dern_value_as_text_get_string(
+     octaspire_dern_value_t * const self);
+ 
+ octaspire_string_t const *octaspire_dern_value_as_text_get_string_const(
      octaspire_dern_value_t const * const self);
  
  size_t octaspire_dern_value_as_text_get_length_in_octets(


@@ 671,6 678,14 @@ }
  octaspire_dern_text_or_unpushed_error_const_t;
  
+ typedef struct octaspire_dern_string_or_unpushed_error_t
+ {
+     octaspire_string_t     * str;
+     octaspire_dern_value_t * value;
+     octaspire_dern_value_t * unpushedError;
+ }
+ octaspire_dern_string_or_unpushed_error_t;
+ 
  typedef struct octaspire_dern_symbol_or_unpushed_error_t
  {
      octaspire_string_t     const * symbol;


@@ 743,6 758,12 @@ ptrdiff_t const possiblyNegativeIndex,
      char const * const dernFuncName);
  
+ octaspire_dern_string_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_string_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName);
+ 
  octaspire_dern_symbol_or_unpushed_error_t
  octaspire_dern_value_as_vector_get_element_at_as_symbol_or_unpushed_error(
      octaspire_dern_value_t * const self,

M dev/src/octaspire_dern_stdlib.c => dev/src/octaspire_dern_stdlib.c +2 -2
@@ 5891,8 5891,8 @@ return octaspire_dern_vm_create_new_value_integer(
          vm,
          octaspire_string_levenshtein_distance(
-             octaspire_dern_value_as_text_get_string(firstArgVal),
-             octaspire_dern_value_as_text_get_string(secondArgVal)));
+             octaspire_dern_value_as_text_get_string_const(firstArgVal),
+             octaspire_dern_value_as_text_get_string_const(secondArgVal)));
  }
  
  octaspire_dern_value_t *octaspire_dern_vm_builtin_max(

M dev/src/octaspire_dern_value.c => dev/src/octaspire_dern_value.c +100 -3
@@ 3192,7 3192,56 @@ return 0;
  }
  
- octaspire_string_t const *octaspire_dern_value_as_text_get_string(
+ bool octaspire_dern_value_as_text_set_c_string(
+     octaspire_dern_value_t * const self,
+     char const * const str)
+ {
+     switch (self->typeTag)
+     {
+         case OCTASPIRE_DERN_VALUE_TAG_ILLEGAL:
+         {
+             abort();
+         }
+ 
+         case OCTASPIRE_DERN_VALUE_TAG_STRING:
+         {
+             return octaspire_string_set_from_c_string(self->value.string, str);
+         }
+ 
+         case OCTASPIRE_DERN_VALUE_TAG_SYMBOL:
+         {
+             // TODO handle whitespace (and other
+             // characters not allowed in symbols)
+             return octaspire_string_set_from_c_string(self->value.symbol, str);
+         }
+ 
+         case OCTASPIRE_DERN_VALUE_TAG_CHARACTER:
+         case OCTASPIRE_DERN_VALUE_TAG_NIL:
+         case OCTASPIRE_DERN_VALUE_TAG_BOOLEAN:
+         case OCTASPIRE_DERN_VALUE_TAG_INTEGER:
+         case OCTASPIRE_DERN_VALUE_TAG_REAL:
+         case OCTASPIRE_DERN_VALUE_TAG_ERROR:
+         case OCTASPIRE_DERN_VALUE_TAG_VECTOR:
+         case OCTASPIRE_DERN_VALUE_TAG_HASH_MAP:
+         case OCTASPIRE_DERN_VALUE_TAG_QUEUE:
+         case OCTASPIRE_DERN_VALUE_TAG_LIST:
+         case OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT:
+         case OCTASPIRE_DERN_VALUE_TAG_FUNCTION:
+         case OCTASPIRE_DERN_VALUE_TAG_SPECIAL:
+         case OCTASPIRE_DERN_VALUE_TAG_BUILTIN:
+         case OCTASPIRE_DERN_VALUE_TAG_PORT:
+         case OCTASPIRE_DERN_VALUE_TAG_C_DATA:
+         case OCTASPIRE_DERN_VALUE_TAG_SEMVER:
+         {
+             octaspire_helpers_verify_true(false);
+         }
+         break;
+     }
+ 
+     return 0;
+ }
+ 
+ octaspire_string_t const *octaspire_dern_value_as_text_get_string_const(
      octaspire_dern_value_t const * const self)
  {
      switch (self->typeTag)


@@ 3242,6 3291,13 @@ return 0;
  }
  
+ octaspire_string_t *octaspire_dern_value_as_text_get_string(
+     octaspire_dern_value_t * const self)
+ {
+     return (octaspire_string_t*)
+         octaspire_dern_value_as_text_get_string_const(self);
+ }
+ 
  size_t octaspire_dern_value_as_text_get_length_in_octets(
      octaspire_dern_value_t const * const self)
  {


@@ 3651,7 3707,48 @@ }
  
      result.value = arg;
-     result.text = octaspire_dern_value_as_text_get_string(arg);
+     result.text = octaspire_dern_value_as_text_get_string_const(arg);
+     return result;
+ }
+ 
+ octaspire_dern_string_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_string_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName)
+ {
+     octaspire_helpers_verify_not_null(self);
+ 
+     octaspire_dern_vm_t * const vm = self->vm;
+ 
+     octaspire_helpers_verify_not_null(vm);
+ 
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+     octaspire_dern_string_or_unpushed_error_t result = {0, 0, 0};
+ 
+     octaspire_dern_value_t * const arg =
+         octaspire_dern_value_as_vector_get_element_at(self, possiblyNegativeIndex);
+ 
+     octaspire_helpers_verify_not_null(arg);
+ 
+     if (!octaspire_dern_value_is_string(arg))
+     {
+         result.unpushedError = octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects string as "
+             "%d. argument. Type '%s' was given.",
+             dernFuncName,
+             possiblyNegativeIndex,
+             octaspire_dern_value_helper_get_type_as_c_string(arg->typeTag));
+ 
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return result;
+     }
+ 
+     result.value = arg;
+     result.str   = octaspire_dern_value_as_text_get_string(arg);
      return result;
  }
  


@@ 3692,7 3789,7 @@ }
  
      result.value  = arg;
-     result.symbol = octaspire_dern_value_as_text_get_string(arg);
+     result.symbol = octaspire_dern_value_as_text_get_string_const(arg);
      return result;
  }
  

M release/examples/dern-nuklear-example.dern => release/examples/dern-nuklear-example.dern +14 -6
@@ 37,6 37,7 @@ (define dern-nuklear-example-slider-int-value      as {D+15}   [current value of the integer slider])
  (define dern-nuklear-example-slider-float-value    as {D+1.75} [current value of the floating point slider])
  (define dern-nuklear-example-radio-option          as 'EASY    [currently selected option])
+ (define dern-nuklear-example-text-value            as []       [text input])
  
  (define dern-nuklear-example-render as (fn ()
    (if (nuklear-begin dern-nuklear-example-nuklear-ctx [] {D+10} {D+10} {D+780} {D+580})


@@ 85,20 86,27 @@ (println [float to {}] dern-nuklear-example-slider-float-value))
  
        ; Radio buttons
-       (nuklear-layout-row-static dern-nuklear-example-nuklear-ctx {D+90} {D+150} {D+2})
-       (if (nuklear-option-label
+       (nuklear-layout-row-dynamic dern-nuklear-example-nuklear-ctx {D+35} {D+2})
+       (nuklear-option-label
              dern-nuklear-example-nuklear-ctx
              [Easy]
              'EASY
              dern-nuklear-example-radio-option)
-           (println [EASY selected]))
-       (if (nuklear-option-label
+       (nuklear-option-label
              dern-nuklear-example-nuklear-ctx
              [Hard]
              'HARD
              dern-nuklear-example-radio-option)
-           (println [HARD selected]))
-       (println [Radio option {} is active] dern-nuklear-example-radio-option)))
+       ;(println [Radio option {} is active] dern-nuklear-example-radio-option)
+ 
+       ; Text input (simple)
+       (nuklear-layout-row-static dern-nuklear-example-nuklear-ctx {D+35} {D+150} {D+1})
+       (nuklear-edit-string
+         dern-nuklear-example-nuklear-ctx
+         'SIMPLE
+         dern-nuklear-example-text-value
+         {D+256}
+         'DEFAULT)))
    (nuklear-end dern-nuklear-example-nuklear-ctx)
    (nuklear-sdl-render)
    (sdl2-GL-SwapWindow dern-nuklear-example-window))

M release/octaspire-dern-amalgamated.c => release/octaspire-dern-amalgamated.c +125 -7
@@ 26223,7 26223,7 @@ #define OCTASPIRE_DERN_CONFIG_H
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "0"
- #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "470"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "471"
  #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "0"
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_STR "Octaspire Dern version " \


@@ 27149,7 27149,14 @@ char const *octaspire_dern_value_as_text_get_c_string(
      octaspire_dern_value_t const * const self);
  
- octaspire_string_t const *octaspire_dern_value_as_text_get_string(
+ bool octaspire_dern_value_as_text_set_c_string(
+     octaspire_dern_value_t * const self,
+     char const * const str);
+ 
+ octaspire_string_t *octaspire_dern_value_as_text_get_string(
+     octaspire_dern_value_t * const self);
+ 
+ octaspire_string_t const *octaspire_dern_value_as_text_get_string_const(
      octaspire_dern_value_t const * const self);
  
  size_t octaspire_dern_value_as_text_get_length_in_octets(


@@ 27257,6 27264,14 @@ }
  octaspire_dern_text_or_unpushed_error_const_t;
  
+ typedef struct octaspire_dern_string_or_unpushed_error_t
+ {
+     octaspire_string_t     * str;
+     octaspire_dern_value_t * value;
+     octaspire_dern_value_t * unpushedError;
+ }
+ octaspire_dern_string_or_unpushed_error_t;
+ 
  typedef struct octaspire_dern_symbol_or_unpushed_error_t
  {
      octaspire_string_t     const * symbol;


@@ 27329,6 27344,12 @@ ptrdiff_t const possiblyNegativeIndex,
      char const * const dernFuncName);
  
+ octaspire_dern_string_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_string_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName);
+ 
  octaspire_dern_symbol_or_unpushed_error_t
  octaspire_dern_value_as_vector_get_element_at_as_symbol_or_unpushed_error(
      octaspire_dern_value_t * const self,


@@ 39781,8 39802,8 @@ return octaspire_dern_vm_create_new_value_integer(
          vm,
          octaspire_string_levenshtein_distance(
-             octaspire_dern_value_as_text_get_string(firstArgVal),
-             octaspire_dern_value_as_text_get_string(secondArgVal)));
+             octaspire_dern_value_as_text_get_string_const(firstArgVal),
+             octaspire_dern_value_as_text_get_string_const(secondArgVal)));
  }
  
  octaspire_dern_value_t *octaspire_dern_vm_builtin_max(


@@ 47839,7 47860,56 @@ return 0;
  }
  
- octaspire_string_t const *octaspire_dern_value_as_text_get_string(
+ bool octaspire_dern_value_as_text_set_c_string(
+     octaspire_dern_value_t * const self,
+     char const * const str)
+ {
+     switch (self->typeTag)
+     {
+         case OCTASPIRE_DERN_VALUE_TAG_ILLEGAL:
+         {
+             abort();
+         }
+ 
+         case OCTASPIRE_DERN_VALUE_TAG_STRING:
+         {
+             return octaspire_string_set_from_c_string(self->value.string, str);
+         }
+ 
+         case OCTASPIRE_DERN_VALUE_TAG_SYMBOL:
+         {
+             // TODO handle whitespace (and other
+             // characters not allowed in symbols)
+             return octaspire_string_set_from_c_string(self->value.symbol, str);
+         }
+ 
+         case OCTASPIRE_DERN_VALUE_TAG_CHARACTER:
+         case OCTASPIRE_DERN_VALUE_TAG_NIL:
+         case OCTASPIRE_DERN_VALUE_TAG_BOOLEAN:
+         case OCTASPIRE_DERN_VALUE_TAG_INTEGER:
+         case OCTASPIRE_DERN_VALUE_TAG_REAL:
+         case OCTASPIRE_DERN_VALUE_TAG_ERROR:
+         case OCTASPIRE_DERN_VALUE_TAG_VECTOR:
+         case OCTASPIRE_DERN_VALUE_TAG_HASH_MAP:
+         case OCTASPIRE_DERN_VALUE_TAG_QUEUE:
+         case OCTASPIRE_DERN_VALUE_TAG_LIST:
+         case OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT:
+         case OCTASPIRE_DERN_VALUE_TAG_FUNCTION:
+         case OCTASPIRE_DERN_VALUE_TAG_SPECIAL:
+         case OCTASPIRE_DERN_VALUE_TAG_BUILTIN:
+         case OCTASPIRE_DERN_VALUE_TAG_PORT:
+         case OCTASPIRE_DERN_VALUE_TAG_C_DATA:
+         case OCTASPIRE_DERN_VALUE_TAG_SEMVER:
+         {
+             octaspire_helpers_verify_true(false);
+         }
+         break;
+     }
+ 
+     return 0;
+ }
+ 
+ octaspire_string_t const *octaspire_dern_value_as_text_get_string_const(
      octaspire_dern_value_t const * const self)
  {
      switch (self->typeTag)


@@ 47889,6 47959,13 @@ return 0;
  }
  
+ octaspire_string_t *octaspire_dern_value_as_text_get_string(
+     octaspire_dern_value_t * const self)
+ {
+     return (octaspire_string_t*)
+         octaspire_dern_value_as_text_get_string_const(self);
+ }
+ 
  size_t octaspire_dern_value_as_text_get_length_in_octets(
      octaspire_dern_value_t const * const self)
  {


@@ 48298,7 48375,48 @@ }
  
      result.value = arg;
-     result.text = octaspire_dern_value_as_text_get_string(arg);
+     result.text = octaspire_dern_value_as_text_get_string_const(arg);
+     return result;
+ }
+ 
+ octaspire_dern_string_or_unpushed_error_t
+ octaspire_dern_value_as_vector_get_element_at_as_string_or_unpushed_error(
+     octaspire_dern_value_t * const self,
+     ptrdiff_t const possiblyNegativeIndex,
+     char const * const dernFuncName)
+ {
+     octaspire_helpers_verify_not_null(self);
+ 
+     octaspire_dern_vm_t * const vm = self->vm;
+ 
+     octaspire_helpers_verify_not_null(vm);
+ 
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+     octaspire_dern_string_or_unpushed_error_t result = {0, 0, 0};
+ 
+     octaspire_dern_value_t * const arg =
+         octaspire_dern_value_as_vector_get_element_at(self, possiblyNegativeIndex);
+ 
+     octaspire_helpers_verify_not_null(arg);
+ 
+     if (!octaspire_dern_value_is_string(arg))
+     {
+         result.unpushedError = octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects string as "
+             "%d. argument. Type '%s' was given.",
+             dernFuncName,
+             possiblyNegativeIndex,
+             octaspire_dern_value_helper_get_type_as_c_string(arg->typeTag));
+ 
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return result;
+     }
+ 
+     result.value = arg;
+     result.str   = octaspire_dern_value_as_text_get_string(arg);
      return result;
  }
  


@@ 48339,7 48457,7 @@ }
  
      result.value  = arg;
-     result.symbol = octaspire_dern_value_as_text_get_string(arg);
+     result.symbol = octaspire_dern_value_as_text_get_string_const(arg);
      return result;
  }
  

M release/plugins/dern_nuklear.c => release/plugins/dern_nuklear.c +311 -6
@@ 361,7 361,7 @@ octaspire_dern_value_helper_get_type_as_c_string(thirdArg->typeTag));
      }
  
-     octaspire_string_t const * const alignment = octaspire_dern_value_as_text_get_string(thirdArg);
+     octaspire_string_t const * const alignment = octaspire_dern_value_as_text_get_string_const(thirdArg);
  
      nk_flags flags = 0;
  


@@ 986,6 986,275 @@ return octaspire_dern_vm_create_new_value_boolean(vm, result);
  }
  
+ octaspire_dern_value_t *dern_nuklear_edit_string(
+     octaspire_dern_vm_t * const vm,
+     octaspire_dern_value_t * const arguments,
+     octaspire_dern_value_t * const environment)
+ {
+     OCTASPIRE_HELPERS_UNUSED_PARAMETER(environment);
+ 
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+     char   const * const dernFuncName    = "nuklear-edit-string";
+     char   const * const ctxName         = "ctx";
+     size_t const         numExpectedArgs = 5;
+ 
+     size_t const numArgs =
+         octaspire_dern_value_as_vector_get_length(arguments);
+ 
+     if (numArgs != numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     // ctx
+ 
+     octaspire_dern_c_data_or_unpushed_error_t cDataOrError =
+         octaspire_dern_value_as_vector_get_element_at_as_c_data_or_unpushed_error(
+             arguments,
+             0,
+             dernFuncName,
+             ctxName,
+             DERN_NUKLEAR_PLUGIN_NAME);
+ 
+     if (cDataOrError.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return cDataOrError.unpushedError;
+     }
+ 
+     struct nk_context * const ctx = cDataOrError.cData;
+ 
+     octaspire_helpers_verify_not_null(ctx);
+ 
+     // edit-type
+ 
+     char const * const altEditType[] =
+     {
+         "SIMPLE",
+         "FIELD",
+         "BOX",
+         "EDITOR",
+         0
+     };
+ 
+     octaspire_dern_one_of_texts_or_unpushed_error_const_t textOrErrorEditType =
+         octaspire_dern_value_as_vector_get_element_at_as_one_of_texts_or_unpushed_error_const(
+             arguments,
+             1,
+             dernFuncName,
+             altEditType);
+ 
+     if (textOrErrorEditType.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return textOrErrorEditType.unpushedError;
+     }
+ 
+     octaspire_helpers_verify_true(
+         textOrErrorEditType.index >= 0 && textOrErrorEditType.index <= 3);
+ 
+     nk_flags editType = NK_EDIT_SIMPLE;
+ 
+     switch (textOrErrorEditType.index)
+     {
+         case 0: { editType = NK_EDIT_SIMPLE; } break;
+         case 1: { editType = NK_EDIT_FIELD;  } break;
+         case 2: { editType = NK_EDIT_BOX;    } break;
+         case 3: { editType = NK_EDIT_EDITOR; } break;
+     }
+ 
+     // str
+ 
+     octaspire_dern_string_or_unpushed_error_t stringOrError =
+         octaspire_dern_value_as_vector_get_element_at_as_string_or_unpushed_error(
+             arguments,
+             2,
+             dernFuncName);
+ 
+     if (stringOrError.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return stringOrError.unpushedError;
+     }
+ 
+     // len
+ 
+     octaspire_dern_number_or_unpushed_error_const_t numberOrError =
+         octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error_const(
+             arguments,
+             3,
+             dernFuncName);
+ 
+     if (numberOrError.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return numberOrError.unpushedError;
+     }
+ 
+     int const len = numberOrError.number;
+ 
+     if (len < 2)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects input length larger than 1. %zu was given."
+             "%zu arguments were given.",
+             dernFuncName,
+             len);
+     }
+ 
+     // Remove characters until the string fits into the buffer.
+     while (octaspire_dern_value_as_string_get_length_in_octets(
+                stringOrError.value) >= (size_t)(len - 1))
+     {
+         octaspire_helpers_verify_true(
+             octaspire_dern_value_as_string_pop_back_ucs_character(
+                 stringOrError.value));
+     }
+ 
+     // filter
+ 
+     char const * const altFilter[] =
+     {
+         "DEFAULT",
+         "ASCII",
+         "FLOAT",
+         "DECIMAL",
+         "HEX",
+         "OCT",
+         "BINARY",
+         0
+     };
+ 
+     octaspire_dern_one_of_texts_or_unpushed_error_const_t textOrErrorFilter =
+         octaspire_dern_value_as_vector_get_element_at_as_one_of_texts_or_unpushed_error_const(
+             arguments,
+             4,
+             dernFuncName,
+             altFilter);
+ 
+     if (textOrErrorFilter.unpushedError)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return textOrErrorFilter.unpushedError;
+     }
+ 
+     octaspire_helpers_verify_true(
+         textOrErrorFilter.index >= 0 && textOrErrorFilter.index <= 6);
+ 
+     nk_plugin_filter filter = nk_filter_default;
+ 
+     switch (textOrErrorFilter.index)
+     {
+         case 0: { filter = nk_filter_default; } break;
+         case 1: { filter = nk_filter_ascii;   } break;
+         case 2: { filter = nk_filter_float;   } break;
+         case 3: { filter = nk_filter_decimal; } break;
+         case 4: { filter = nk_filter_hex;     } break;
+         case 5: { filter = nk_filter_oct;     } break;
+         case 6: { filter = nk_filter_binary;  } break;
+     }
+ 
+     char * memory = octaspire_allocator_malloc(
+         octaspire_dern_vm_get_allocator(vm),
+         len);
+ 
+     octaspire_helpers_verify_not_null(memory);
+ 
+     strncpy(
+         memory,
+         octaspire_dern_value_as_string_get_c_string(stringOrError.value),
+         len);
+ 
+     int memused = octaspire_dern_value_as_string_get_length_in_octets(
+         stringOrError.value);
+ 
+     // Show the widget.
+ 
+     nk_flags const resultFlags = nk_edit_string(
+         ctx,
+         NK_EDIT_SIMPLE,
+         memory,
+         &memused,
+         len,
+         filter);
+ 
+     if (memused < len)
+     {
+         memory[memused] = '\0';
+     }
+ 
+     octaspire_helpers_verify_true(
+         octaspire_dern_value_as_text_set_c_string(
+             stringOrError.value,
+             memory));
+ 
+     octaspire_allocator_free(octaspire_dern_vm_get_allocator(vm), memory);
+ 
+     memory = 0;
+ 
+     octaspire_string_t * const result = octaspire_string_new(
+         "",
+         octaspire_dern_vm_get_allocator(vm));
+ 
+     octaspire_helpers_verify_not_null(result);
+ 
+     if (resultFlags)
+     {
+         if (resultFlags & NK_EDIT_ACTIVE)
+         {
+             octaspire_string_concatenate_c_string(result, "ACTIVE ");
+         }
+ 
+         if (resultFlags & NK_EDIT_INACTIVE)
+         {
+             octaspire_string_concatenate_c_string(result, "INACTIVE ");
+         }
+ 
+         if (resultFlags & NK_EDIT_ACTIVATED)
+         {
+             octaspire_string_concatenate_c_string(result, "ACTIVATED ");
+         }
+ 
+         if (resultFlags & NK_EDIT_DEACTIVATED)
+         {
+             octaspire_string_concatenate_c_string(result, "DEACTIVATED ");
+         }
+ 
+         if (resultFlags & NK_EDIT_COMMITED)
+         {
+             octaspire_string_concatenate_c_string(result, "COMMITED ");
+         }
+     }
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     return octaspire_dern_vm_create_new_value_string(vm, result);
+ }
+ 
  octaspire_dern_value_t *dern_nuklear_progress(
      octaspire_dern_vm_t * const vm,
      octaspire_dern_value_t * const arguments,


@@ 1182,7 1451,7 @@ octaspire_dern_number_or_unpushed_error_const_t numberOrErrorNumColumns =
          octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error_const(
              arguments,
-             1,
+             2,
              dernFuncName);
  
      if (numberOrErrorNumColumns.unpushedError)


@@ 1278,7 1547,7 @@ octaspire_dern_number_or_unpushed_error_const_t numberOrErrorItemWidth =
          octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error_const(
              arguments,
-             1,
+             2,
              dernFuncName);
  
      if (numberOrErrorItemWidth.unpushedError)


@@ 1296,7 1565,7 @@ octaspire_dern_number_or_unpushed_error_const_t numberOrErrorColumns =
          octaspire_dern_value_as_vector_get_element_at_as_number_or_unpushed_error_const(
              arguments,
-             2,
+             3,
              dernFuncName);
  
      if (numberOrErrorColumns.unpushedError)


@@ 1487,8 1756,6 @@ ratios[numRatiosAdded + i] = ratio;
      }
  
-     printf("--->%d | %f | %d | %f | %f\n", textOrError.index, height, columns, ratios[0], ratios[1]);
- 
      nk_layout_row(
          ctx,
          textOrError.index == 0 ? NK_DYNAMIC : NK_STATIC,


@@ 2128,6 2395,44 @@       if (!octaspire_dern_vm_create_and_register_new_builtin(
              vm,
+             "nuklear-edit-string",
+             dern_nuklear_edit_string,
+             5,
+             "NAME\n"
+             "\tnuklear-edit-string\n"
+             "\n"
+             "SYNOPSIS\n"
+             "\t(require 'dern_nuklear)\n"
+             "\n"
+             "\t(nuklear-edit-string ctx edit-type str len filter) -> string or error\n"
+             "\n"
+             "DESCRIPTION\n"
+             "\tDisplay a simple text input with the given maximum length.\n"
+             "\n"
+             "ARGUMENTS\n"
+             "\tctx           nuklear context.\n"
+             "\tedit-type     One of symbols: SIMPLE, FIELD, BOX or EDITOR."
+             "\tstr           edit result.\n"
+             "\tlen           max allowed input length.\n"
+             "\tfilter        text (string or symbol) describing allowed input.\n"
+             "\t              Must be one of: DEFAULT, ASCII, FLOAT, DECIMAL,\n"
+             "\t              HEX, OCT or BINARY.\n"
+             "\n"
+             "RETURN VALUE\n"
+             "\tString that is empty or contains status information.\n"
+             "\tPossible values are: ACTIVE, INACTIVE, ACTIVATED, DEACTIVATED\n"
+             "\tand COMMITED. Error is returned if something went wrong.\n"
+             "\n"
+             "SEE ALSO\n"
+             "\tnuklear-begin\n",
+             false,
+             targetEnv))
+     {
+         return false;
+     }
+ 
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+             vm,
              "nuklear-layout-row-dynamic",
              dern_nuklear_layout_row_dynamic,
              3,